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";
|
||||
|
||||
const App: React.FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
Cache.clear();
|
||||
Cache.enabled = true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
import { useEffect, useState } from "react";
|
||||
@@ -9,21 +9,18 @@ import CompareLayOut from "../../ui/compareVersion/CompareLayOut";
|
||||
import ComparisonResult from "../../ui/compareVersion/ComparisonResult";
|
||||
import RegularDropDown from "../../ui/inputs/RegularDropDown";
|
||||
|
||||
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
|
||||
|
||||
function ComparisonScene() {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { productStore, versionStore } = useSceneContext();
|
||||
const { versionHistory, selectedVersion, setSelectedVersion, setVersions } = versionStore();
|
||||
const { versionHistory, selectedVersion, setSelectedVersion } = versionStore();
|
||||
const { products, selectedProduct } = productStore();
|
||||
const { isVersionSaved } = useSaveVersion();
|
||||
const { isComparing } = useIsComparing();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
||||
const { mainProduct } = useMainProduct();
|
||||
const { loadingProgress } = useLoadingProgress();
|
||||
const { compareProductsData } = useCompareProductDataStore();
|
||||
const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false);
|
||||
const { projectId } = useParams();
|
||||
|
||||
const handleSelectVersion = (option: string) => {
|
||||
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(() => {
|
||||
if (mainProduct && comparisonProduct && compareProductsData.length > 1) {
|
||||
const hasMain = compareProductsData.some((val) => val.productUuid === mainProduct.productUuid);
|
||||
@@ -79,7 +52,7 @@ function ComparisonScene() {
|
||||
|
||||
return (
|
||||
<>
|
||||
{isVersionSaved && activeModule === "simulation" && selectedProduct && (
|
||||
{isComparing && activeModule === "simulation" && selectedProduct && (
|
||||
<>
|
||||
{selectedVersion && !isPlaying && (
|
||||
<div className="initial-selectLayout-wrapper">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect } from "react";
|
||||
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 { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
|
||||
@@ -36,7 +36,7 @@ import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionCo
|
||||
|
||||
function MainScene() {
|
||||
const { setMainProduct } = useMainProduct();
|
||||
const { isVersionSaved, setIsVersionSaved } = useSaveVersion();
|
||||
const { isComparing, setIsComparing } = useIsComparing();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedUser } = useSelectedUserStore();
|
||||
const { loadingProgress } = useLoadingProgress();
|
||||
@@ -67,9 +67,9 @@ function MainScene() {
|
||||
useEffect(() => {
|
||||
if (activeModule !== "simulation") {
|
||||
clearComparisonProduct();
|
||||
setIsVersionSaved(false);
|
||||
setIsComparing(false);
|
||||
}
|
||||
}, [activeModule, clearComparisonProduct, setIsVersionSaved]);
|
||||
}, [activeModule, clearComparisonProduct, setIsComparing]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!projectId) return;
|
||||
@@ -162,14 +162,14 @@ function MainScene() {
|
||||
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
|
||||
{!isPlaying && (
|
||||
<>
|
||||
{toggleThreeD && !isVersionSaved && <ModuleToggle />}
|
||||
{toggleThreeD && !isComparing && <ModuleToggle />}
|
||||
<SideBarLeft />
|
||||
<SideBarRight />
|
||||
</>
|
||||
)}
|
||||
<RealTimeVisulization />
|
||||
{activeModule === "market" && <MarketPlace />}
|
||||
{activeModule !== "market" && !isPlaying && !isVersionSaved && <Tools />}
|
||||
{activeModule !== "market" && !isPlaying && !isComparing && <Tools />}
|
||||
{isPlaying && activeModule === "simulation" && loadingProgress === 0 && <SimulationPlayer />}
|
||||
{isPlaying && activeModule !== "simulation" && <ControlsPlayer />}
|
||||
|
||||
@@ -204,7 +204,7 @@ function MainScene() {
|
||||
<Scene layout="Main Layout" />
|
||||
</div>
|
||||
|
||||
{selectedProduct && selectedVersion && isVersionSaved && !isPlaying && activeModule === "simulation" && (
|
||||
{selectedProduct && selectedVersion && isComparing && !isPlaying && activeModule === "simulation" && (
|
||||
<div className="selectLayout-wrapper">
|
||||
<RegularDropDown
|
||||
header={selectedVersion.versionName}
|
||||
|
||||
@@ -8,7 +8,7 @@ import useModuleStore from "../../../store/ui/useModuleStore";
|
||||
import Widgets from "./visualization/widgets/Widgets";
|
||||
import Templates from "../../../modules/visualization/template/Templates";
|
||||
import Search from "../../ui/inputs/Search";
|
||||
import { useSaveVersion } from "../../../store/builder/store";
|
||||
import { useIsComparing } from "../../../store/builder/store";
|
||||
|
||||
const SideBarLeft: React.FC = () => {
|
||||
const [activeOption, setActiveOption] = useState("Widgets");
|
||||
@@ -16,7 +16,7 @@ const SideBarLeft: React.FC = () => {
|
||||
const { toggleUILeft } = useToggleStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
const { isVersionSaved } = useSaveVersion();
|
||||
const { isComparing } = useIsComparing();
|
||||
|
||||
// Reset activeOption whenever activeModule changes
|
||||
useEffect(() => {
|
||||
@@ -35,7 +35,7 @@ const SideBarLeft: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`sidebar-left-wrapper ${toggleUILeft && (!isVersionSaved || activeModule !== "simulation") ? "open" : "closed"
|
||||
className={`sidebar-left-wrapper ${toggleUILeft && (!isComparing || activeModule !== "simulation") ? "open" : "closed"
|
||||
}`}
|
||||
>
|
||||
<Header />
|
||||
@@ -74,7 +74,7 @@ const SideBarLeft: React.FC = () => {
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
{!isVersionSaved && (
|
||||
{!isComparing && (
|
||||
<>
|
||||
<ToggleHeader
|
||||
options={["Outline"]}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useToggleStore } from "../../../store/ui/useUIToggleStore";
|
||||
import Visualization from "./visualization/Visualization";
|
||||
import Analysis from "./analysis/Analysis";
|
||||
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 { useBuilderStore } from "../../../store/builder/useBuilderStore";
|
||||
import GlobalProperties from "./properties/GlobalProperties";
|
||||
@@ -52,7 +52,7 @@ const SideBarRight: React.FC = () => {
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { viewVersionHistory, setVersionHistoryVisible } = useVersionHistoryVisibleStore();
|
||||
const { isVersionSaved } = useSaveVersion();
|
||||
const { isComparing } = useIsComparing();
|
||||
|
||||
const [displayComponent, setDisplayComponent] = useState<DisplayComponent>("none");
|
||||
|
||||
@@ -80,7 +80,7 @@ const SideBarRight: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isVersionSaved && activeModule === "simulation") {
|
||||
if (!isComparing && activeModule === "simulation") {
|
||||
if (subModule === "simulations") {
|
||||
setDisplayComponent("simulations");
|
||||
return;
|
||||
@@ -155,7 +155,7 @@ const SideBarRight: React.FC = () => {
|
||||
}
|
||||
|
||||
setDisplayComponent("none");
|
||||
}, [viewVersionHistory, activeModule, subModule, isVersionSaved, selectedFloorAsset, selectedWall, selectedFloor, selectedAisle, toolMode, selectedDecal]);
|
||||
}, [viewVersionHistory, activeModule, subModule, isComparing, selectedFloorAsset, selectedWall, selectedFloor, selectedAisle, toolMode, selectedDecal]);
|
||||
|
||||
const renderComponent = () => {
|
||||
switch (displayComponent) {
|
||||
@@ -197,11 +197,11 @@ const SideBarRight: React.FC = () => {
|
||||
};
|
||||
|
||||
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 />
|
||||
{toggleUIRight && (
|
||||
<>
|
||||
{(!isVersionSaved || activeModule !== "simulation") && (
|
||||
{(!isComparing || activeModule !== "simulation") && (
|
||||
<div className="sidebar-actions-container">
|
||||
{activeModule !== "simulation" && (
|
||||
<>
|
||||
|
||||
@@ -13,7 +13,7 @@ import { deleteProductApi } from "../../../../services/simulation/products/delet
|
||||
import { renameProductApi } from "../../../../services/simulation/products/renameProductApi";
|
||||
import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences";
|
||||
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 { useParams } from "react-router-dom";
|
||||
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||
@@ -36,10 +36,10 @@ const Simulations: React.FC = () => {
|
||||
const { setMainProduct } = useMainProduct();
|
||||
const { selectedVersion } = versionStore();
|
||||
const { comparePopUp, setComparePopUp } = useCompareStore();
|
||||
const { setIsVersionSaved } = useSaveVersion();
|
||||
const { setIsComparing } = useIsComparing();
|
||||
|
||||
const handleSaveVersion = () => {
|
||||
setIsVersionSaved(true);
|
||||
setIsComparing(true);
|
||||
setComparePopUp(false);
|
||||
setToggleUI(false, false);
|
||||
};
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import React, { useState, useRef, useEffect, Suspense } from "react";
|
||||
import { CompareLayoutIcon, LayoutIcon, ResizerIcon } from "../../icons/SimulationIcons";
|
||||
import { useLoadingProgress, useSaveVersion } from "../../../store/builder/store";
|
||||
import Search from "../inputs/Search";
|
||||
import OuterClick from "../../../utils/outerClick";
|
||||
import Scene from "../../../modules/scene/scene";
|
||||
import { useLoadingProgress, useIsComparing } from "../../../store/builder/store";
|
||||
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
||||
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 { clearComparisonProduct, comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
||||
const { versionStore } = useSceneContext();
|
||||
const { versionHistory, selectedVersion, setSelectedVersion, clearSelectedVersion } = versionStore();
|
||||
const { versionHistory, selectedVersion, setSelectedVersion, clearSelectedVersion, setVersions } = versionStore();
|
||||
const { setLoadingProgress } = useLoadingProgress();
|
||||
const [width, setWidth] = useState("50vw");
|
||||
const [isResizing, setIsResizing] = useState(false);
|
||||
@@ -21,10 +24,43 @@ const CompareLayOut = () => {
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const startWidthRef = useRef<number>(0);
|
||||
const startXRef = useRef<number>(0);
|
||||
const { setIsVersionSaved } = useSaveVersion();
|
||||
const { setIsComparing } = useIsComparing();
|
||||
const { loadingProgress } = useLoadingProgress();
|
||||
const { setIsPlaying } = usePlayButtonStore();
|
||||
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(() => {
|
||||
if (!comparisonProduct) {
|
||||
@@ -71,7 +107,7 @@ const CompareLayOut = () => {
|
||||
|
||||
if (finalWidthVw <= 10) {
|
||||
setWidth("0px");
|
||||
setIsVersionSaved(false);
|
||||
setIsComparing(false);
|
||||
clearComparisonProduct();
|
||||
setIsPlaying(false);
|
||||
} else {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import * as THREE from 'three';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils';
|
||||
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||
import { useToggleView, useToolMode } from '../../../../../store/builder/store';
|
||||
import { AssetBoundingBox } from '../../functions/assetBoundingBox';
|
||||
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
|
||||
import useModuleStore from '../../../../../store/ui/useModuleStore';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { SkeletonUtils } from 'three-stdlib';
|
||||
import * as THREE from "three";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { retrieveGLTF, storeGLTF } from "../../../../../utils/indexDB/idbUtils";
|
||||
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import { useToggleView, useToolMode } from "../../../../../store/builder/store";
|
||||
import { AssetBoundingBox } from "../../functions/assetBoundingBox";
|
||||
import { useBuilderStore } from "../../../../../store/builder/useBuilderStore";
|
||||
import useModuleStore from "../../../../../store/ui/useModuleStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { SkeletonUtils } from "three-stdlib";
|
||||
|
||||
import { getAssetFieldApi } from '../../../../../services/factoryBuilder/asset/floorAsset/getAssetField';
|
||||
import { ModelAnimator } from './animator/modelAnimator';
|
||||
import { useModelEventHandlers } from './eventHandlers/useModelEventHandlers';
|
||||
import { getAssetFieldApi } from "../../../../../services/factoryBuilder/asset/floorAsset/getAssetField";
|
||||
import { ModelAnimator } from "./animator/modelAnimator";
|
||||
import { useModelEventHandlers } from "./eventHandlers/useModelEventHandlers";
|
||||
|
||||
function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendered: boolean; loader: GLTFLoader }>) {
|
||||
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(() => {
|
||||
if (!fieldData && asset.eventData) {
|
||||
getAssetFieldApi(asset.assetId).then((data) => {
|
||||
if (data.type === 'ArmBot') {
|
||||
if (data.type === "ArmBot") {
|
||||
if (data.data) {
|
||||
const fieldData: IK[] = data.data;
|
||||
setFieldData(fieldData);
|
||||
}
|
||||
} else if (data.type === 'Conveyor' || data.type === 'Crane') {
|
||||
} else if (data.type === "Conveyor" || data.type === "Crane") {
|
||||
if (data.data) {
|
||||
const fieldData = data.data;
|
||||
setFieldData(fieldData);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}, [asset.modelUuid, fieldData])
|
||||
}, [asset.modelUuid, fieldData]);
|
||||
|
||||
useEffect(() => {
|
||||
setDeletableFloorAsset(null);
|
||||
if (selectedFloorAsset === null || selectedFloorAsset.userData.modelUuid !== asset.modelUuid) {
|
||||
resetAnimation(asset.modelUuid);
|
||||
}
|
||||
}, [activeModule, toolMode, selectedFloorAsset])
|
||||
}, [activeModule, toolMode, selectedFloorAsset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedFloorAsset && selectedFloorAsset.userData.modelUuid === asset.modelUuid) {
|
||||
setSelectedFloorAsset(groupRef.current);
|
||||
}
|
||||
}, [isRendered, selectedFloorAsset])
|
||||
}, [isRendered, selectedFloorAsset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedAssets.length > 0) {
|
||||
@@ -69,7 +69,7 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
||||
} else {
|
||||
setIsSelected(false);
|
||||
}
|
||||
}, [selectedAssets])
|
||||
}, [selectedAssets]);
|
||||
|
||||
useEffect(() => {
|
||||
if (gltfScene) {
|
||||
@@ -78,13 +78,13 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
||||
child.castShadow = true;
|
||||
child.receiveShadow = true;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}, [gltfScene]);
|
||||
|
||||
const logModelStatus = (modelId: string, status: string) => {
|
||||
// console.log(modelId, status);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Calculate Bounding Box
|
||||
@@ -101,12 +101,13 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
||||
clone.animations = cachedModel.animations || [];
|
||||
setGltfScene(clone);
|
||||
calculateBoundingBox(clone);
|
||||
logModelStatus(assetId, 'cache-loaded');
|
||||
logModelStatus(assetId, "cache-loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check IndexedDB
|
||||
retrieveGLTF(assetId).then((indexedDBModel) => {
|
||||
retrieveGLTF(assetId)
|
||||
.then((indexedDBModel) => {
|
||||
if (indexedDBModel) {
|
||||
const blobUrl = URL.createObjectURL(indexedDBModel);
|
||||
loader.load(
|
||||
@@ -117,10 +118,10 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
||||
THREE.Cache.add(assetId, gltf);
|
||||
setGltfScene(gltf.scene.clone());
|
||||
calculateBoundingBox(gltf.scene);
|
||||
logModelStatus(assetId, 'indexedDB-loaded');
|
||||
logModelStatus(assetId, "indexedDB-loaded");
|
||||
},
|
||||
undefined,
|
||||
(error) => {
|
||||
() => {
|
||||
echo.error(`[IndexedDB] Error loading ${asset.modelName}:`);
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
}
|
||||
@@ -140,21 +141,19 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
||||
THREE.Cache.add(assetId, gltf);
|
||||
setGltfScene(gltf.scene.clone());
|
||||
calculateBoundingBox(gltf.scene);
|
||||
logModelStatus(assetId, 'backend-loaded');
|
||||
logModelStatus(assetId, "backend-loaded");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(
|
||||
`[Backend] Error storing/loading ${asset.modelName}:`,
|
||||
error
|
||||
);
|
||||
console.error(`[Backend] Error storing/loading ${asset.modelName}:`, error);
|
||||
});
|
||||
},
|
||||
undefined,
|
||||
(error) => {
|
||||
() => {
|
||||
echo.error(`[Backend] Error loading ${asset.modelName}:`);
|
||||
}
|
||||
);
|
||||
}).catch((err) => {
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Failed to load model:", asset.assetId, err);
|
||||
});
|
||||
}, []);
|
||||
@@ -164,7 +163,7 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
||||
return (
|
||||
<group
|
||||
key={asset.modelUuid}
|
||||
name='Asset Model'
|
||||
name="Asset Model"
|
||||
ref={groupRef}
|
||||
uuid={asset.modelUuid}
|
||||
position={asset.position}
|
||||
@@ -206,22 +205,14 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
||||
<>
|
||||
{isRendered ? (
|
||||
<>
|
||||
|
||||
<primitive object={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 &&
|
||||
<AssetBoundingBox name='Asset BBox' boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />
|
||||
}
|
||||
{isSelected && <AssetBoundingBox name="Asset BBox" boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />}
|
||||
</>
|
||||
)}
|
||||
</group>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useThree, useFrame } from "@react-three/fiber";
|
||||
import { Group, Vector3 } from "three";
|
||||
import { CameraControls } from '@react-three/drei';
|
||||
import { useLimitDistance, useRenderDistance } from '../../../../store/builder/store';
|
||||
import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { CameraControls } from "@react-three/drei";
|
||||
import { useLimitDistance, useRenderDistance } from "../../../../store/builder/store";
|
||||
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
|
||||
|
||||
import Model from './model/model';
|
||||
import Model from "./model/model";
|
||||
import { GLTFLoader } from "three/examples/jsm/Addons";
|
||||
|
||||
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 }) {
|
||||
const { controls, camera } = useThree();
|
||||
const assetGroupRef = useRef<Group>(null);
|
||||
const { assetStore } = useSceneContext();
|
||||
const { assetStore, layout } = useSceneContext();
|
||||
const { assets } = assetStore();
|
||||
const { selectedFloorAsset, setSelectedFloorAsset } = useBuilderStore();
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
@@ -40,13 +40,13 @@ function Models({ loader }: { readonly loader: GLTFLoader }) {
|
||||
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, });
|
||||
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
|
||||
name='Asset Group'
|
||||
name="Asset Group"
|
||||
ref={assetGroupRef}
|
||||
onPointerMissed={(e) => {
|
||||
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 { useThree } from "@react-three/fiber";
|
||||
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 CamMode from "../camera/camMode";
|
||||
@@ -20,6 +20,7 @@ import { getUserData } from "../../../functions/getUserData";
|
||||
import { getCameraApi } from "../../../services/factoryBuilder/camera/getCameraApi";
|
||||
import { setCameraApi } from "../../../services/factoryBuilder/camera/setCameraApi";
|
||||
import updateCamPosition from "../camera/functions/updateCameraPosition";
|
||||
import SyncCam from "../camera/syncCam";
|
||||
|
||||
export default function Controls() {
|
||||
const controlsRef = useRef<CameraControls>(null);
|
||||
@@ -38,7 +39,8 @@ export default function Controls() {
|
||||
}
|
||||
|
||||
if (!projectId) return;
|
||||
getCameraApi(projectId).then((data) => {
|
||||
getCameraApi(projectId)
|
||||
.then((data) => {
|
||||
if (data?.position && data?.target) {
|
||||
controlsRef.current?.setPosition(data.position.x, data.position.y, data.position.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?.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]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -56,12 +59,7 @@ export default function Controls() {
|
||||
controlsRef.current?.rotateAzimuthTo(CONSTANTS.threeDimension.defaultAzimuth);
|
||||
|
||||
if (!socket?.connected) {
|
||||
setCameraApi(
|
||||
projectId,
|
||||
new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition),
|
||||
new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget),
|
||||
new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation),
|
||||
)
|
||||
setCameraApi(projectId, new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition), new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget), new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation));
|
||||
} else {
|
||||
const camData = {
|
||||
organization,
|
||||
@@ -70,9 +68,9 @@ export default function Controls() {
|
||||
target: new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget),
|
||||
rotation: new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation),
|
||||
socketId: socket.id,
|
||||
projectId
|
||||
projectId,
|
||||
};
|
||||
socket.emit('v1:Camera:set', camData)
|
||||
socket.emit("v1:Camera:set", camData);
|
||||
}
|
||||
|
||||
setResetCamera(false);
|
||||
@@ -152,6 +150,7 @@ export default function Controls() {
|
||||
|
||||
<CameraShortcutsControls />
|
||||
|
||||
<SyncCam />
|
||||
</CameraControls>
|
||||
|
||||
<SelectionControls3D />
|
||||
@@ -165,7 +164,6 @@ export default function Controls() {
|
||||
<TransformControl />
|
||||
|
||||
<ContextControls />
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +1,7 @@
|
||||
import { useRef, useEffect } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import {
|
||||
useAzimuth,
|
||||
useElevation,
|
||||
useShadows,
|
||||
useSunPosition,
|
||||
useTileDistance,
|
||||
} from "../../../store/builder/store";
|
||||
import { useAzimuth, useElevation, useShadows, useSunPosition, useTileDistance } from "../../../store/builder/store";
|
||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||
|
||||
const shadowWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/shadowWorker", import.meta.url));
|
||||
@@ -67,31 +61,11 @@ export default function Shadows() {
|
||||
{/* {(lightRef.current?.shadow) &&
|
||||
<cameraHelper visible={shadows} args={[lightRef.current.shadow.camera]} />
|
||||
} */}
|
||||
<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}
|
||||
/>
|
||||
<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} />
|
||||
<object3D ref={targetRef} />
|
||||
<mesh
|
||||
position={CONSTANTS.shadowConfig.shadowMaterialPosition}
|
||||
rotation={CONSTANTS.shadowConfig.shadowMaterialRotation}
|
||||
receiveShadow
|
||||
>
|
||||
<mesh position={CONSTANTS.shadowConfig.shadowMaterialPosition} rotation={CONSTANTS.shadowConfig.shadowMaterialRotation} receiveShadow>
|
||||
<planeGeometry args={[planeValue.width, planeValue.height]} />
|
||||
<shadowMaterial
|
||||
opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity}
|
||||
transparent
|
||||
/>
|
||||
<shadowMaterial opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity} transparent />
|
||||
</mesh>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -8,12 +8,7 @@ type SocketStore = {
|
||||
dashBoardSocket?: ReturnType<typeof io> | null;
|
||||
projectSocket?: ReturnType<typeof io> | null;
|
||||
threadSocket?: ReturnType<typeof io> | null;
|
||||
initializeSocket: (
|
||||
email?: string,
|
||||
organization?: string,
|
||||
token?: string,
|
||||
refreshToken?: string
|
||||
) => void;
|
||||
initializeSocket: (email?: string, organization?: string, token?: string, refreshToken?: string) => void;
|
||||
disconnectSocket: () => void;
|
||||
};
|
||||
|
||||
@@ -23,54 +18,34 @@ export const useSocketStore = create<SocketStore>((set, get) => ({
|
||||
dashBoardSocket: null,
|
||||
projectSocket: null,
|
||||
threadSocket: null,
|
||||
initializeSocket: (
|
||||
email?: string,
|
||||
organization?: string,
|
||||
token?: string,
|
||||
refreshToken?: string
|
||||
) => {
|
||||
initializeSocket: (email?: string, organization?: string, token?: string, refreshToken?: string) => {
|
||||
const existingSocket = get().socket;
|
||||
if (existingSocket) {
|
||||
return;
|
||||
}
|
||||
|
||||
const socket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
||||
{
|
||||
const socket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`, {
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const visualizationSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
||||
{
|
||||
const visualizationSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`, {
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const dashBoardSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
||||
{
|
||||
const dashBoardSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`, {
|
||||
reconnection: true,
|
||||
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,
|
||||
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,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
set({
|
||||
socket,
|
||||
@@ -154,8 +129,7 @@ export const useShadows = create<any>((set: any) => ({
|
||||
|
||||
export const useSunPosition = create<any>((set: any) => ({
|
||||
sunPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setSunPosition: (newSuntPosition: any) =>
|
||||
set({ sunPosition: newSuntPosition }),
|
||||
setSunPosition: (newSuntPosition: any) => set({ sunPosition: newSuntPosition }),
|
||||
}));
|
||||
|
||||
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) => ({
|
||||
objectPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectPosition: (newObjectPosition: any) =>
|
||||
set({ objectPosition: newObjectPosition }),
|
||||
setObjectPosition: (newObjectPosition: any) => set({ objectPosition: newObjectPosition }),
|
||||
}));
|
||||
|
||||
export const useObjectRotation = create<any>((set: any) => ({
|
||||
objectRotation: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectRotation: (newObjectRotation: any) =>
|
||||
set({ objectRotation: newObjectRotation }),
|
||||
setObjectRotation: (newObjectRotation: any) => set({ objectRotation: newObjectRotation }),
|
||||
}));
|
||||
|
||||
export const useDrieTemp = create<any>((set: any) => ({
|
||||
@@ -234,16 +206,14 @@ export const useActiveUsers = create<any>((set: any) => ({
|
||||
activeUsers: [],
|
||||
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
||||
set((state: { activeUsers: any[] }) => ({
|
||||
activeUsers:
|
||||
typeof callback === "function" ? callback(state.activeUsers) : callback,
|
||||
activeUsers: typeof callback === "function" ? callback(state.activeUsers) : callback,
|
||||
})),
|
||||
}));
|
||||
|
||||
export const useDrieUIValue = create<any>((set: any) => ({
|
||||
drieUIValue: { touch: null, temperature: null, humidity: null },
|
||||
|
||||
setDrieUIValue: (x: any) =>
|
||||
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||
setDrieUIValue: (x: any) => set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||
|
||||
setTouch: (value: any) =>
|
||||
set((state: any) => ({
|
||||
@@ -367,8 +337,7 @@ interface ShortcutStore {
|
||||
export const useShortcutStore = create<ShortcutStore>((set) => ({
|
||||
showShortcuts: false,
|
||||
setShowShortcuts: (value) => set({ showShortcuts: value }),
|
||||
toggleShortcuts: () =>
|
||||
set((state) => ({ showShortcuts: !state.showShortcuts })),
|
||||
toggleShortcuts: () => set((state) => ({ showShortcuts: !state.showShortcuts })),
|
||||
}));
|
||||
|
||||
export const useMachineCount = create<any>((set: any) => ({
|
||||
@@ -470,19 +439,18 @@ interface CompareStore {
|
||||
export const useCompareStore = create<CompareStore>((set) => ({
|
||||
comparePopUp: false,
|
||||
setComparePopUp: (value) => set({ comparePopUp: value }),
|
||||
toggleComparePopUp: () =>
|
||||
set((state) => ({ comparePopUp: !state.comparePopUp })),
|
||||
toggleComparePopUp: () => set((state) => ({ comparePopUp: !state.comparePopUp })),
|
||||
}));
|
||||
|
||||
// Save state store
|
||||
interface SaveVersionStore {
|
||||
isVersionSaved: boolean;
|
||||
setIsVersionSaved: (value: boolean) => void;
|
||||
interface IsComparingStore {
|
||||
isComparing: boolean;
|
||||
setIsComparing: (value: boolean) => void;
|
||||
}
|
||||
|
||||
export const useSaveVersion = create<SaveVersionStore>((set) => ({
|
||||
isVersionSaved: false,
|
||||
setIsVersionSaved: (value: boolean) => set({ isVersionSaved: value }),
|
||||
export const useIsComparing = create<IsComparingStore>((set) => ({
|
||||
isComparing: false,
|
||||
setIsComparing: (value: boolean) => set({ isComparing: value }),
|
||||
}));
|
||||
|
||||
interface ViewSceneState {
|
||||
@@ -494,8 +462,7 @@ export const useViewSceneStore = create<ViewSceneState>((set) => ({
|
||||
viewSceneLabels: getInitialViewSceneLabels(),
|
||||
setViewSceneLabels: (value) => {
|
||||
set((state) => {
|
||||
const newValue =
|
||||
typeof value === "function" ? value(state.viewSceneLabels) : value;
|
||||
const newValue = typeof value === "function" ? value(state.viewSceneLabels) : value;
|
||||
|
||||
// Store in localStorage manually
|
||||
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 useModuleStore, { useSubModuleStore, useThreeDStore } from "../../store/ui/useModuleStore";
|
||||
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 { detectModifierKeys } from "./detectModifierKeys";
|
||||
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
|
||||
@@ -27,7 +27,7 @@ const KeyPressListener: React.FC = () => {
|
||||
const { clearSelectedZone } = useSelectedZoneStore();
|
||||
const { showShortcuts, setShowShortcuts } = useShortcutStore();
|
||||
const { setWalkMode } = useCameraModeStore();
|
||||
const { setIsVersionSaved } = useSaveVersion();
|
||||
const { setIsComparing } = useIsComparing();
|
||||
const { isLogListVisible, setIsLogListVisible } = useLogger();
|
||||
const { hidePlayer, setHidePlayer } = usePlayerStore();
|
||||
const { setViewSceneLabels } = useViewSceneStore();
|
||||
@@ -177,7 +177,7 @@ const KeyPressListener: React.FC = () => {
|
||||
setIsPlaying(false);
|
||||
clearSelectedZone();
|
||||
setShowShortcuts(false);
|
||||
setIsVersionSaved(false);
|
||||
setIsComparing(false);
|
||||
clearComparisonProduct();
|
||||
setIsLogListVisible(false);
|
||||
setIsRenameMode(false);
|
||||
|
||||
Reference in New Issue
Block a user