diff --git a/app/src/modules/scene/camera/camMode.tsx b/app/src/modules/scene/camera/camMode.tsx index 2f03c97..77e2f31 100644 --- a/app/src/modules/scene/camera/camMode.tsx +++ b/app/src/modules/scene/camera/camMode.tsx @@ -9,124 +9,89 @@ import { detectModifierKeys } from "../../../utils/shortcutkeys/detectModifierKe import { firstPersonCamera } from "./firstPersonCamera"; const CamMode: React.FC = () => { - const { camMode, setCamMode } = useCamMode(); - const [, get] = useKeyboardControls(); - const [isTransitioning, setIsTransitioning] = useState(false); - const state: any = useThree(); - const { toggleView } = useToggleView(); - const [isShiftActive, setIsShiftActive] = useState(false); + const { camMode, setCamMode } = useCamMode(); + const [_, get] = useKeyboardControls(); + const [isTransitioning, setIsTransitioning] = useState(false); + const state: any = useThree(); + const { toggleView } = useToggleView(); + const [isShiftActive, setIsShiftActive] = useState(false); - useEffect(() => { - const handlePointerLockChange = async () => { - if (document.pointerLockElement && !toggleView) { - // Pointer is locked - } else if (camMode === "FirstPerson" && !toggleView) { - // Pointer is unlocked - setCamMode("ThirdPerson"); - await switchToThirdPerson(state.controls, state.camera); - } - }; + useEffect(() => { + const handlePointerLockChange = async () => { + if (document.pointerLockElement && !toggleView) { + } else if (camMode === "FirstPerson" && !toggleView) { + setCamMode("ThirdPerson"); + await switchToThirdPerson(state.controls, state.camera); + } + }; - document.addEventListener("pointerlockchange", handlePointerLockChange); + document.addEventListener("pointerlockchange", handlePointerLockChange); - return () => { - document.removeEventListener( - "pointerlockchange", - handlePointerLockChange - ); - }; - }, [camMode, toggleView, setCamMode, state.controls, state.camera]); + return () => { + document.removeEventListener("pointerlockchange", handlePointerLockChange); + }; + }, [camMode, toggleView, setCamMode, state.controls, state.camera]); - useEffect(() => { - const handleKeyDown = (event: KeyboardEvent) => { - if (event.key === "Shift") { - setIsShiftActive(true); - } - }; + useEffect(() => { + const handleKeyPress = async (event: KeyboardEvent) => { + if (!state.controls) return; - const handleKeyUp = (event: KeyboardEvent) => { - if (event.key === "Shift") { - setIsShiftActive(false); - } - }; + const keyCombination = detectModifierKeys(event); - window.addEventListener("keydown", handleKeyDown); - window.addEventListener("keyup", handleKeyUp); + if (keyCombination === "/" && !isTransitioning && !toggleView) { + firstPersonCamera({ + setIsTransitioning, + state, + camMode, + setCamMode, + switchToFirstPerson, + switchToThirdPerson, + }); + } - return () => { - window.removeEventListener("keydown", handleKeyDown); - window.removeEventListener("keyup", handleKeyUp); - }; - }, []); + if (keyCombination === 'Shift') { + setIsShiftActive(true); + } + }; - useEffect(() => { - const handleKeyPress = async (event: KeyboardEvent) => { - if (!state.controls) return; + const handleKeyUp = (event: KeyboardEvent) => { + if (event.key === "Shift") { + setIsShiftActive(false); + } + }; - const keyCombination = detectModifierKeys(event); + window.addEventListener("keydown", handleKeyPress); + window.addEventListener("keyup", handleKeyUp); - if (keyCombination === "/" && !isTransitioning && !toggleView) { - firstPersonCamera({ - setIsTransitioning, - state, - camMode, - setCamMode, - switchToFirstPerson, - switchToThirdPerson, - }); - } - }; + return () => { + window.removeEventListener("keydown", handleKeyPress); + window.removeEventListener("keyup", handleKeyUp); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [camMode, isTransitioning, toggleView, state.controls, state.camera, setCamMode]); - window.addEventListener("keydown", handleKeyPress); - return () => { - window.removeEventListener("keydown", handleKeyPress); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ - camMode, - isTransitioning, - toggleView, - state.controls, - state.camera, - setCamMode, - ]); + useFrame(() => { + const { forward, backward, left, right } = get(); + if (!state.controls) return; + if (camMode === "ThirdPerson" || !document.pointerLockElement) return; - useFrame(() => { - const { forward, backward, left, right } = get(); - if (!state.controls) return; - if (camMode === "ThirdPerson" || !document.pointerLockElement) return; + const speedMultiplier = isShiftActive ? 4 : 1; - const speedMultiplier = isShiftActive ? 4 : 1; + if (forward) { + state.controls.forward(CONSTANTS.firstPersonControls.forwardSpeed * speedMultiplier, true); + } + if (backward) { + state.controls.forward(CONSTANTS.firstPersonControls.backwardSpeed * speedMultiplier, true); + } + if (left) { + state.controls.truck(CONSTANTS.firstPersonControls.leftSpeed * speedMultiplier, 0, true); + } + if (right) { + state.controls.truck(CONSTANTS.firstPersonControls.rightSpeed * speedMultiplier, 0, true); + } + }); - if (forward) { - state.controls.forward( - CONSTANTS.firstPersonControls.forwardSpeed * speedMultiplier, - true - ); - } - if (backward) { - state.controls.forward( - CONSTANTS.firstPersonControls.backwardSpeed * speedMultiplier, - true - ); - } - if (left) { - state.controls.truck( - CONSTANTS.firstPersonControls.leftSpeed * speedMultiplier, - 0, - true - ); - } - if (right) { - state.controls.truck( - CONSTANTS.firstPersonControls.rightSpeed * speedMultiplier, - 0, - true - ); - } - }); - - return null; // This component does not render any UI + return null; }; export default CamMode; diff --git a/app/src/modules/scene/camera/switchView.tsx b/app/src/modules/scene/camera/switchView.tsx index ce64e1f..b9501b3 100644 --- a/app/src/modules/scene/camera/switchView.tsx +++ b/app/src/modules/scene/camera/switchView.tsx @@ -1,73 +1,68 @@ -import * as THREE from "three"; -import { useEffect, useRef } from "react"; -import { useToggleView } from "../../../store/builder/store"; +import { useEffect } from "react"; import { useThree } from "@react-three/fiber"; -import { getCamera } from "../../../services/factoryBuilder/camera/getCameraApi"; -import * as CONSTANTS from '../../../types/world/worldConstants'; +import * as THREE from 'three'; +import { PerspectiveCamera, OrthographicCamera, CameraControls } from '@react-three/drei'; import { useParams } from "react-router-dom"; +import * as CONSTANTS from '../../../types/world/worldConstants'; +import { getCamera } from "../../../services/factoryBuilder/camera/getCameraApi"; import { getUserData } from "../../../functions/getUserData"; -import { CameraControls } from "@react-three/drei"; +import { useToggleView } from "../../../store/builder/store"; export default function SwitchView() { - const { toggleView } = useToggleView(); - const state: any = useThree(); - const { set } = useThree(); - const perspectiveCamera = useRef(null); - const orthoCamera = useRef(null); - orthoCamera.current = new THREE.OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 0.01, 1000); - perspectiveCamera.current = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000); - const { projectId } = useParams(); - const { organization } = getUserData(); + const { toggleView } = useToggleView(); + const { controls } = useThree(); + const { projectId } = useParams(); + const { organization } = getUserData(); - useEffect(() => { - if (!perspectiveCamera.current || !orthoCamera.current) return; - if (toggleView) { - orthoCamera.current.zoom = 10; - orthoCamera.current.position.set(...CONSTANTS.twoDimension.defaultPosition); - orthoCamera.current.lookAt(new THREE.Vector3(...CONSTANTS.twoDimension.defaultTarget)); - orthoCamera.current.updateProjectionMatrix(); - set({ camera: orthoCamera.current }); - orthoCamera.current.updateProjectionMatrix(); - } else if (!toggleView) { - perspectiveCamera.current.position.set(...CONSTANTS.threeDimension.defaultPosition); - perspectiveCamera.current.lookAt(new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget)); - set({ camera: perspectiveCamera.current }); - } - }, [toggleView, set]); + useEffect(() => { + if (toggleView && controls) { + (controls as any).mouseButtons.left = CONSTANTS.twoDimension.leftMouse; + (controls as any).mouseButtons.right = CONSTANTS.twoDimension.rightMouse; + } else { + try { + getCamera(organization, localStorage.getItem('userId')!, projectId).then((data) => { + if (data && data.position && data.target) { + (controls as CameraControls)?.setPosition(data.position.x, data.position.y, data.position.z); + (controls as CameraControls)?.setTarget(data.target.x, data.target.y, data.target.z); + } else { + (controls as CameraControls)?.setPosition(...CONSTANTS.threeDimension.defaultPosition); + (controls as CameraControls)?.setTarget(...CONSTANTS.threeDimension.defaultTarget); + } + }); + } catch (error) { + echo.error("Failed to retrieve camera position or target"); + (controls as CameraControls)?.setPosition(...CONSTANTS.threeDimension.defaultPosition); + (controls as CameraControls)?.setTarget(...CONSTANTS.threeDimension.defaultTarget); + } - useEffect(() => { - if (toggleView && state.controls) { - state.controls.mouseButtons.left = CONSTANTS.twoDimension.leftMouse; - state.controls.mouseButtons.right = CONSTANTS.twoDimension.rightMouse; - } else { - try { - getCamera(organization, localStorage.getItem('userId')!, projectId).then((data) => { - if (data && data.position && data.target) { - // state.controls?.setLookAt(data.position.x, data.position.y, data.position.z, data.target.x, data.target.y, data.target.z, true) - state.controls?.setPosition(data.position.x, data.position.y, data.position.z); - state.controls?.setTarget(data.target.x, data.target.y, data.target.z); - } else { - // state.controls?.setLookAt(...CONSTANTS.threeDimension.defaultPosition, ...CONSTANTS.threeDimension.defaultTarget, true); - state.controls?.setPosition(...CONSTANTS.threeDimension.defaultPosition); - state.controls?.setTarget(...CONSTANTS.threeDimension.defaultTarget); - } - }); - } catch (error) { - echo.error("Failed to retrieve camera position or target"); - console.error("Failed to retrieve camera position or target:", error); - // state.controls?.setLookAt(...CONSTANTS.threeDimension.defaultPosition, ...CONSTANTS.threeDimension.defaultTarget, true); - state.controls?.setPosition(...CONSTANTS.threeDimension.defaultPosition); - state.controls?.setTarget(...CONSTANTS.threeDimension.defaultTarget); - } + if (controls) { + (controls as any).mouseButtons.left = CONSTANTS.threeDimension.leftMouse; + (controls as any).mouseButtons.right = CONSTANTS.threeDimension.rightMouse; + } + } + }, [toggleView, controls]); - if (state.controls) { - state.controls.mouseButtons.left = CONSTANTS.threeDimension.leftMouse; - state.controls.mouseButtons.right = CONSTANTS.threeDimension.rightMouse; - } - } - }, [toggleView, state.controls]); - - return ( - <> - ); + return ( + <> + {toggleView ? ( + self.lookAt(new THREE.Vector3(...CONSTANTS.twoDimension.defaultTarget))} + /> + ) : ( + self.lookAt(new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget))} + /> + )} + + ); } \ No newline at end of file diff --git a/app/src/modules/scene/controls/controls.tsx b/app/src/modules/scene/controls/controls.tsx index 77f234c..845a82d 100644 --- a/app/src/modules/scene/controls/controls.tsx +++ b/app/src/modules/scene/controls/controls.tsx @@ -13,16 +13,17 @@ import SelectionControls3D from "./selectionControls/selection3D/selectionContro import TransformControl from "./transformControls/transformControls"; import { useParams } from "react-router-dom"; import { getUserData } from "../../../functions/getUserData"; + import SelectionControls2D from "./selectionControls/selection2D/selectionControls2D"; import UndoRedo2DControls from "./undoRedoControls/undoRedo2D/undoRedo2DControls"; export default function Controls() { const controlsRef = useRef(null); + const state = useThree(); const { toggleView } = useToggleView(); const { resetCamera, setResetCamera } = useResetCamera(); const { socket } = useSocketStore(); - const state = useThree(); const { projectId } = useParams(); const { userId, organization } = getUserData(); @@ -33,7 +34,6 @@ export default function Controls() { } getCamera(organization, userId, projectId).then((data) => { - // console.log('data: ', data); if (data && 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); @@ -41,8 +41,7 @@ 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)); }, []); useEffect(() => { @@ -60,7 +59,6 @@ export default function Controls() { socketId: socket.id, projectId }; - // console.log('CameracamData: ', camData); socket.emit('v1:Camera:set', camData) setResetCamera(false); @@ -130,7 +128,7 @@ export default function Controls() { camera={state.camera} verticalDragToForward={true} boundaryEnclosesCamera={true} - dollyToCursor={toggleView} + dollyDragInverted > diff --git a/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx b/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx index eb8bdae..c72da8b 100644 --- a/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx +++ b/app/src/modules/scene/controls/selectionControls/selection3D/selectionControls3D.tsx @@ -333,6 +333,7 @@ const SelectionControls3D: React.FC = () => { return ( <> + @@ -340,6 +341,7 @@ const SelectionControls3D: React.FC = () => { + ); }; diff --git a/app/src/types/world/worldConstants.ts b/app/src/types/world/worldConstants.ts index 71d9caf..04214c1 100644 --- a/app/src/types/world/worldConstants.ts +++ b/app/src/types/world/worldConstants.ts @@ -206,7 +206,7 @@ export const thirdPersonControls: ThirdPersonControls = { polarRotateSpeed: 1, // Speed of rotation around the polar axis truckSpeed: 2, // Speed of truck movement maxDistance: 100, // Maximum distance from the target - maxPolarAngle: Math.PI / 2 - 0.05, // Maximum polar angle + maxPolarAngle: Math.PI / 2, // Maximum polar angle minZoom: 6, // Minimum zoom level maxZoom: 100, // Maximum zoom level targetOffset: 20, // Offset of the target from the camera