added ortho cam toggle
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useLoadingProgress, useRenameModeStore, useIsComparing, useSelectedComment, useSocketStore, useWidgetSubOption } from "../../../store/builder/store";
|
||||
import useModuleStore, { useThreeDStore } from "../../../store/ui/useModuleStore";
|
||||
import { useLoadingProgress, useRenameModeStore, useIsComparing, useSelectedComment, useSocketStore, useWidgetSubOption, useToggleView } from "../../../store/builder/store";
|
||||
import useModuleStore from "../../../store/ui/useModuleStore";
|
||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
|
||||
import { useFloatingWidget } from "../../../store/visualization/useDroppedObjectsStore";
|
||||
@@ -39,7 +39,7 @@ function MainScene() {
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedUser } = useSelectedUserStore();
|
||||
const { loadingProgress } = useLoadingProgress();
|
||||
const { toggleThreeD } = useThreeDStore();
|
||||
const { toggleView } = useToggleView();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { widgetSubOption } = useWidgetSubOption();
|
||||
const { visualizationSocket } = useSocketStore();
|
||||
@@ -166,7 +166,7 @@ function MainScene() {
|
||||
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
|
||||
{!isPlaying && (
|
||||
<>
|
||||
{toggleThreeD && !isComparing && <ModuleToggle />}
|
||||
{!toggleView && !isComparing && <ModuleToggle />}
|
||||
<SideBarLeft />
|
||||
<SideBarRight />
|
||||
</>
|
||||
@@ -181,7 +181,7 @@ function MainScene() {
|
||||
<RenameTooltip name={selectedFloorAsset?.userData.modelName || selectedAssets[0].userData.modelName} onSubmit={handleObjectRename} />
|
||||
)}
|
||||
{/* remove this later */}
|
||||
{activeModule === "builder" && !toggleThreeD && <SelectFloorPlan />}
|
||||
{activeModule === "builder" && toggleView && <SelectFloorPlan />}
|
||||
</>
|
||||
)}
|
||||
<div
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { AsileIcon, CommentIcon, CursorIcon, DeleteIcon, FloorIcon, FreeMoveIcon, MeasureToolIcon, PenIcon, PlayIcon, SaveTemplateIcon, WallIcon, ZoneIcon } from "../icons/ExportToolsIcons";
|
||||
import { ArrowIcon, TickIcon } from "../icons/ExportCommonIcons";
|
||||
import useModuleStore, { useThreeDStore } from "../../store/ui/useModuleStore";
|
||||
import useModuleStore from "../../store/ui/useModuleStore";
|
||||
import { handleSaveTemplate } from "../../modules/visualization/functions/handleSaveTemplate";
|
||||
import { usePlayButtonStore } from "../../store/ui/usePlayButtonStore";
|
||||
import useTemplateStore from "../../store/ui/useTemplateStore";
|
||||
@@ -31,7 +31,6 @@ const ToolButton = ({ toolKey, toolId, icon: Icon, active, onClick, tooltip }: a
|
||||
|
||||
const Tools: React.FC = () => {
|
||||
const { activeModule } = useModuleStore();
|
||||
const { toggleThreeD, setToggleThreeD } = useThreeDStore();
|
||||
const { isPlaying, setIsPlaying } = usePlayButtonStore();
|
||||
const { showShortcuts } = useShortcutStore();
|
||||
const { activeTool, setActiveTool, setToolMode } = useStoreHooks();
|
||||
@@ -126,7 +125,6 @@ const Tools: React.FC = () => {
|
||||
const toggle2D3D = () => {
|
||||
const toggleTo2D = toggleView;
|
||||
setToggleView(!toggleTo2D);
|
||||
setToggleThreeD(toggleTo2D);
|
||||
setToggleUI(toggleTo2D, toggleTo2D);
|
||||
if (toggleTo2D) {
|
||||
setSelectedWallAsset(null);
|
||||
@@ -138,7 +136,7 @@ const Tools: React.FC = () => {
|
||||
|
||||
const renderBuilderTools = () => (
|
||||
<>
|
||||
{!toggleThreeD && (
|
||||
{toggleView && (
|
||||
<div className="draw-tools">
|
||||
<ToolButton toolId="drawWall" icon={WallIcon} tooltip="draw wall (q)" active={activeTool === "draw-wall"} onClick={() => setActiveTool("draw-wall")} />
|
||||
<ToolButton toolId="drawZone" icon={ZoneIcon} tooltip="draw zone (e)" active={activeTool === "draw-zone"} onClick={() => setActiveTool("draw-zone")} />
|
||||
@@ -182,10 +180,10 @@ const Tools: React.FC = () => {
|
||||
);
|
||||
|
||||
const renderModeSwitcher = () => (
|
||||
<button id="toggle-threed-button" className={`toggle-threed-button${toggleThreeD ? " toggled" : ""}`} onClick={toggle2D3D}>
|
||||
<button id="toggle-threed-button" className={`toggle-threed-button${!toggleView ? " toggled" : ""}`} onClick={toggle2D3D}>
|
||||
<div className="tooltip">toggle view (tab)</div>
|
||||
<div className={`toggle-option${!toggleThreeD ? " active" : ""}`}>2d</div>
|
||||
<div className={`toggle-option${toggleThreeD ? " active" : ""}`}>3d</div>
|
||||
<div className={`toggle-option${toggleView ? " active" : ""}`}>2d</div>
|
||||
<div className={`toggle-option${!toggleView ? " active" : ""}`}>3d</div>
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -281,7 +279,7 @@ const Tools: React.FC = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{toggleThreeD && activeModule !== "visualization" && (
|
||||
{!toggleView && activeModule !== "visualization" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="transform-tools">
|
||||
@@ -300,7 +298,7 @@ const Tools: React.FC = () => {
|
||||
<div className="split"></div>
|
||||
<div className="general-options">
|
||||
<ToolButton toolId="comment" icon={CommentIcon} tooltip="comment" active={activeTool === "comment"} onClick={() => setActiveTool("comment")} />
|
||||
{toggleThreeD && <ToolButton toolId="play" icon={PlayIcon} tooltip="play (ctrl + p)" active={activeTool === "play"} onClick={() => setIsPlaying(!isPlaying)} />}
|
||||
{!toggleView && <ToolButton toolId="play" icon={PlayIcon} tooltip="play (ctrl + p)" active={activeTool === "play"} onClick={() => setIsPlaying(!isPlaying)} />}
|
||||
</div>
|
||||
|
||||
{activeModule === "builder" && (
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { Vector3 } from "three";
|
||||
import { useEffect } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import type { CameraControls } from "@react-three/drei";
|
||||
import { useThreeDStore } from "../../../../store/ui/useModuleStore";
|
||||
import { CameraControls } from "@react-three/drei";
|
||||
import { useToggleView } from "../../../../store/builder/store";
|
||||
import useModuleStore from "../../../../store/ui/useModuleStore";
|
||||
import { useSceneStore } from "../../../../store/scene/useSceneStore";
|
||||
import * as CONSTANTS from "../../../../types/world/worldConstants";
|
||||
|
||||
const CameraShortcutsControls = () => {
|
||||
const { camera, controls } = useThree();
|
||||
const { toggleThreeD, setToggleThreeD } = useThreeDStore();
|
||||
const { toggleView } = useToggleView();
|
||||
const { camType, setCamType } = useSceneStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
const isTextInput = (element: Element | null): boolean => element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element?.getAttribute("contenteditable") === "true";
|
||||
|
||||
@@ -54,12 +59,16 @@ const CameraShortcutsControls = () => {
|
||||
break;
|
||||
}
|
||||
case "Numpad5": {
|
||||
if (!toggleThreeD) {
|
||||
setToggleThreeD(true);
|
||||
} else {
|
||||
cc.setLookAt(0, distance, 0, target.x, target.y, target.z, false).then(() => {
|
||||
setToggleThreeD(false);
|
||||
});
|
||||
if (!toggleView) {
|
||||
if (camType === "perspective") {
|
||||
setCamType("orthographic");
|
||||
(controls as any).mouseButtons.left = CONSTANTS.twoDimension.leftMouse;
|
||||
(controls as any).mouseButtons.right = CONSTANTS.twoDimension.rightMouse;
|
||||
} else {
|
||||
setCamType("perspective");
|
||||
(controls as any).mouseButtons.left = CONSTANTS.threeDimension.leftMouse;
|
||||
(controls as any).mouseButtons.right = CONSTANTS.threeDimension.rightMouse;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -72,7 +81,7 @@ const CameraShortcutsControls = () => {
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [controls, camera, toggleThreeD, setToggleThreeD]);
|
||||
}, [controls, camera, camType, setCamType, toggleView, activeModule]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import { useEffect } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { PerspectiveCamera, OrthographicCamera, CameraControls } from "@react-three/drei";
|
||||
import { useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { PerspectiveCamera, OrthographicCamera, CameraControls } from "@react-three/drei";
|
||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||
import { getCameraApi } from "../../../services/factoryBuilder/camera/getCameraApi";
|
||||
import { useToggleView } from "../../../store/builder/store";
|
||||
import { useThreeDStore } from "../../../store/ui/useModuleStore";
|
||||
import { useSceneStore } from "../../../store/scene/useSceneStore";
|
||||
|
||||
export default function SwitchView() {
|
||||
const { toggleView } = useToggleView();
|
||||
const { controls } = useThree();
|
||||
const { camType } = useSceneStore();
|
||||
const { projectId } = useParams();
|
||||
const { toggleThreeD } = useThreeDStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (toggleView && controls) {
|
||||
if ((toggleView || camType === "orthographic") && controls) {
|
||||
(controls as any).mouseButtons.left = CONSTANTS.twoDimension.leftMouse;
|
||||
(controls as any).mouseButtons.right = CONSTANTS.twoDimension.rightMouse;
|
||||
} else {
|
||||
} else if (!toggleView && camType === "perspective") {
|
||||
if (!projectId) return;
|
||||
getCameraApi(projectId)
|
||||
.then((data) => {
|
||||
@@ -41,11 +41,11 @@ export default function SwitchView() {
|
||||
(controls as any).mouseButtons.right = CONSTANTS.threeDimension.rightMouse;
|
||||
}
|
||||
}
|
||||
}, [toggleView, controls, projectId]);
|
||||
}, [toggleView, controls, projectId, camType]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{toggleView || !toggleThreeD ? (
|
||||
{toggleView || camType === "orthographic" ? (
|
||||
<OrthographicCamera
|
||||
makeDefault
|
||||
position={CONSTANTS.twoDimension.defaultPosition}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||
import { useSocketStore, useToggleView, useResetCamera } from "../../../store/builder/store";
|
||||
import { useSceneStore } from "../../../store/scene/useSceneStore";
|
||||
|
||||
import CamMode from "../camera/camMode";
|
||||
import SwitchView from "../camera/switchView";
|
||||
@@ -24,10 +25,10 @@ import updateCamPosition from "../camera/functions/updateCameraPosition";
|
||||
|
||||
export default function Controls() {
|
||||
const controlsRef = useRef<CameraControls>(null);
|
||||
|
||||
const state = useThree();
|
||||
const { toggleView } = useToggleView();
|
||||
const { resetCamera, setResetCamera } = useResetCamera();
|
||||
const { camType } = useSceneStore();
|
||||
const { socket } = useSocketStore();
|
||||
const { projectId } = useParams();
|
||||
const { userId, organization } = getUserData();
|
||||
@@ -89,7 +90,7 @@ export default function Controls() {
|
||||
let intervalId: NodeJS.Timeout | null = null;
|
||||
|
||||
const handleRest = () => {
|
||||
if (hasInteracted && controlsRef.current && state.camera.position && !toggleView && socket) {
|
||||
if (hasInteracted && controlsRef.current && state.camera.position && !toggleView && socket && camType === "perspective") {
|
||||
const position = state.camera.position;
|
||||
if (position.x === 0 && position.y === 0 && position.z === 0) return;
|
||||
updateCamPosition(controlsRef, socket, position, state.camera.rotation, projectId);
|
||||
@@ -101,7 +102,7 @@ export default function Controls() {
|
||||
hasInteracted = true;
|
||||
if (!intervalId) {
|
||||
intervalId = setInterval(() => {
|
||||
if (controlsRef.current && !toggleView) {
|
||||
if (controlsRef.current && !toggleView && camType === "perspective") {
|
||||
handleRest();
|
||||
}
|
||||
}, CONSTANTS.camPositionUpdateInterval);
|
||||
@@ -116,7 +117,7 @@ export default function Controls() {
|
||||
};
|
||||
|
||||
const controls = controlsRef.current;
|
||||
if (controls) {
|
||||
if (controls && !toggleView && camType === "perspective") {
|
||||
controls.addEventListener("sleep", handleRest);
|
||||
controls.addEventListener("control", startInterval);
|
||||
controls.addEventListener("controlend", stopInterval);
|
||||
@@ -130,20 +131,20 @@ export default function Controls() {
|
||||
}
|
||||
stopInterval();
|
||||
};
|
||||
}, [toggleView, state, socket]);
|
||||
}, [toggleView, state, socket, camType]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CameraControls
|
||||
makeDefault
|
||||
ref={controlsRef}
|
||||
minDistance={toggleView ? CONSTANTS.twoDimension.minDistance : CONSTANTS.threeDimension.minDistance}
|
||||
minDistance={toggleView || camType === "orthographic" ? CONSTANTS.twoDimension.minDistance : CONSTANTS.threeDimension.minDistance}
|
||||
maxDistance={CONSTANTS.thirdPersonControls.maxDistance}
|
||||
minZoom={CONSTANTS.thirdPersonControls.minZoom}
|
||||
maxZoom={CONSTANTS.thirdPersonControls.maxZoom}
|
||||
maxPolarAngle={CONSTANTS.thirdPersonControls.maxPolarAngle}
|
||||
camera={state.camera}
|
||||
dollyToCursor={toggleView}
|
||||
dollyToCursor={toggleView || camType === "orthographic"}
|
||||
verticalDragToForward={true}
|
||||
boundaryEnclosesCamera={true}
|
||||
dollyDragInverted
|
||||
|
||||
@@ -108,9 +108,7 @@ const MeasurementTool = () => {
|
||||
!intersect.object.name.includes("zonePlane") &&
|
||||
!intersect.object.name.includes("SelectionGroup") &&
|
||||
!intersect.object.name.includes("selectionAssetGroup") &&
|
||||
!intersect.object.name.includes(
|
||||
"SelectionGroupBoundingBoxLine"
|
||||
) &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingBoxLine") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingBox") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingLine") &&
|
||||
intersect.object.type !== "GridHelper"
|
||||
@@ -119,10 +117,7 @@ const MeasurementTool = () => {
|
||||
if (intersects.length > 0) {
|
||||
let intersectionPoint = intersects[0].point.clone();
|
||||
if (axisLock && points.length > 0) {
|
||||
intersectionPoint = applyAxisLock(
|
||||
intersectionPoint,
|
||||
points[points.length - 1]
|
||||
);
|
||||
intersectionPoint = applyAxisLock(intersectionPoint, points[points.length - 1]);
|
||||
}
|
||||
if (points.length < 2) {
|
||||
setPoints([...points, intersectionPoint]);
|
||||
@@ -232,27 +227,14 @@ const MeasurementTool = () => {
|
||||
)}
|
||||
|
||||
{points.map((point, index) => (
|
||||
<Html
|
||||
key={index}
|
||||
position={point}
|
||||
scale={0.5}
|
||||
wrapperClass="measurement-label-wrapper"
|
||||
className="measurement-label"
|
||||
zIndexRange={[1, 0]}
|
||||
prepend
|
||||
sprite
|
||||
>
|
||||
<Html key={index} position={point} scale={0.5} wrapperClass="measurement-label-wrapper" className="measurement-label" zIndexRange={[1, 0]} prepend sprite>
|
||||
<div className="measurement-point"></div>
|
||||
</Html>
|
||||
))}
|
||||
|
||||
{linePoints && linePoints.length === 2 && (
|
||||
<Html
|
||||
position={[
|
||||
(linePoints[0].x + linePoints[1].x) / 2,
|
||||
(linePoints[0].y + linePoints[1].y) / 2,
|
||||
(linePoints[0].z + linePoints[1].z) / 2,
|
||||
]}
|
||||
position={[(linePoints[0].x + linePoints[1].x) / 2, (linePoints[0].y + linePoints[1].y) / 2, (linePoints[0].z + linePoints[1].z) / 2]}
|
||||
scale={0.5}
|
||||
wrapperClass="distance-text-wrapper"
|
||||
className="distance-text"
|
||||
|
||||
@@ -10,9 +10,13 @@ type SceneStore = {
|
||||
target: THREE.Vector3;
|
||||
};
|
||||
|
||||
camType: "orthographic" | "perspective";
|
||||
|
||||
setLimitFps: (limitFps: boolean) => void;
|
||||
setFps: (fps: number) => void;
|
||||
setCamera: (pos: THREE.Vector3, target: THREE.Vector3) => void;
|
||||
|
||||
setCamType: (type: "orthographic" | "perspective") => void;
|
||||
};
|
||||
|
||||
export const useSceneStore = create<SceneStore>()(
|
||||
@@ -24,6 +28,8 @@ export const useSceneStore = create<SceneStore>()(
|
||||
target: new THREE.Vector3(0, 0, 0),
|
||||
},
|
||||
|
||||
camType: "perspective",
|
||||
|
||||
setLimitFps: (limitFps) => {
|
||||
set((state) => {
|
||||
state.limitFps = limitFps;
|
||||
@@ -36,11 +42,18 @@ export const useSceneStore = create<SceneStore>()(
|
||||
});
|
||||
},
|
||||
|
||||
setCamera: (pos, target) =>
|
||||
setCamera: (pos, target) => {
|
||||
set((state) => {
|
||||
state.camState.position.copy(pos);
|
||||
|
||||
state.camState.target.copy(target);
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
||||
setCamType: (type) => {
|
||||
set((state) => {
|
||||
state.camType = type;
|
||||
});
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
@@ -1,42 +1,29 @@
|
||||
import { create } from "zustand";
|
||||
|
||||
interface ModuleStore {
|
||||
activeModule: string;
|
||||
setActiveModule: (module: string) => void;
|
||||
activeModule: string;
|
||||
setActiveModule: (module: string) => void;
|
||||
}
|
||||
|
||||
const useModuleStore = create<ModuleStore>((set) => ({
|
||||
activeModule: "builder", // Initial state
|
||||
setActiveModule: (module) => set({ activeModule: module }), // Update state
|
||||
activeModule: "builder", // Initial state
|
||||
setActiveModule: (module) => set({ activeModule: module }), // Update state
|
||||
}));
|
||||
|
||||
export default useModuleStore;
|
||||
|
||||
// New store for subModule
|
||||
|
||||
type SubModule = 'properties' | 'simulations' | 'mechanics' | 'analysis' | 'zoneProperties'|"resourceManagement";
|
||||
type SubModule = "properties" | "simulations" | "mechanics" | "analysis" | "zoneProperties" | "resourceManagement";
|
||||
|
||||
interface SubModuleStore {
|
||||
subModule: SubModule;
|
||||
setSubModule: (subModule: SubModule) => void;
|
||||
subModule: SubModule;
|
||||
setSubModule: (subModule: SubModule) => void;
|
||||
}
|
||||
|
||||
const useSubModuleStore = create<SubModuleStore>((set) => ({
|
||||
subModule: "properties", // Initial subModule state
|
||||
setSubModule: (value) => set({ subModule: value }), // Update subModule state
|
||||
subModule: "properties", // Initial subModule state
|
||||
setSubModule: (value) => set({ subModule: value }), // Update subModule state
|
||||
}));
|
||||
|
||||
export { useSubModuleStore };
|
||||
|
||||
interface ThreeDState {
|
||||
toggleThreeD: boolean;
|
||||
setToggleThreeD: (value: boolean) => void;
|
||||
}
|
||||
|
||||
// Create the Zustand store
|
||||
const useThreeDStore = create<ThreeDState>((set) => ({
|
||||
toggleThreeD: true, // Initial state
|
||||
setToggleThreeD: (value) => set({ toggleThreeD: value }), // Action to update the state
|
||||
}));
|
||||
|
||||
export { useThreeDStore };
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect } from "react";
|
||||
import useModuleStore, { useSubModuleStore, useThreeDStore } from "../../store/ui/useModuleStore";
|
||||
import useModuleStore, { useSubModuleStore } from "../../store/ui/useModuleStore";
|
||||
import { usePlayerStore, useToggleStore } from "../../store/ui/useUIToggleStore";
|
||||
import {
|
||||
useActiveSubTool,
|
||||
@@ -29,7 +29,6 @@ const KeyPressListener: React.FC = () => {
|
||||
const { setSubModule } = useSubModuleStore();
|
||||
const { setActiveSubTool } = useActiveSubTool();
|
||||
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
|
||||
const { setToggleThreeD } = useThreeDStore();
|
||||
const { setToolMode } = useToolMode();
|
||||
const { isPlaying, setIsPlaying } = usePlayButtonStore();
|
||||
const { toggleView, setToggleView } = useToggleView();
|
||||
@@ -83,7 +82,6 @@ const KeyPressListener: React.FC = () => {
|
||||
if (key === "TAB") {
|
||||
const toggleTo2D = toggleView;
|
||||
setToggleView(!toggleTo2D);
|
||||
setToggleThreeD(toggleTo2D);
|
||||
if (toggleTo2D) {
|
||||
setSelectedWallAsset(null);
|
||||
setToggleUI(localStorage.getItem("navBarUiLeft") !== "false", localStorage.getItem("navBarUiRight") !== "false");
|
||||
|
||||
Reference in New Issue
Block a user