From ab5ade7bee51db8338f533f366c11b59ac61ded8 Mon Sep 17 00:00:00 2001 From: Vishnu Date: Tue, 29 Apr 2025 13:42:24 +0530 Subject: [PATCH] feat: Enhance camera control and user experience with improved key handling and speed adjustments --- .../components/layout/sidebarRight/Header.tsx | 8 +- app/src/modules/builder/groups/zoneGroup.tsx | 15 +- app/src/modules/scene/camera/camMode.tsx | 220 +++++++++++------- app/src/types/world/worldConstants.ts | 8 +- .../utils/shortcutkeys/handleShortcutKeys.ts | 2 +- 5 files changed, 160 insertions(+), 93 deletions(-) diff --git a/app/src/components/layout/sidebarRight/Header.tsx b/app/src/components/layout/sidebarRight/Header.tsx index a449500..a88baee 100644 --- a/app/src/components/layout/sidebarRight/Header.tsx +++ b/app/src/components/layout/sidebarRight/Header.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import { AppDockIcon } from "../../icons/HeaderIcons"; import orgImg from "../../../assets/orgTemp.png"; import { useActiveUsers } from "../../../store/store"; @@ -8,7 +8,7 @@ import { getAvatarColor } from "../../../modules/collaboration/functions/getAvat const Header: React.FC = () => { const { activeUsers } = useActiveUsers(); - const userName = localStorage.getItem("userName") || "Anonymous"; + const userName = localStorage.getItem("userName") ?? "Anonymous"; const guestUsers: ActiveUser[] = activeUsers.filter( (user: ActiveUser) => user.userName !== userName @@ -23,14 +23,14 @@ const Header: React.FC = () => { )}
-
{ setUserManagement(true); }} > Share -
+ {/*
*/} diff --git a/app/src/modules/builder/groups/zoneGroup.tsx b/app/src/modules/builder/groups/zoneGroup.tsx index d218534..f1818f3 100644 --- a/app/src/modules/builder/groups/zoneGroup.tsx +++ b/app/src/modules/builder/groups/zoneGroup.tsx @@ -69,7 +69,9 @@ const ZoneGroup: React.FC = () => { }, transparent: true, depthWrite: false, - }), []); + }), + [] + ); useEffect(() => { const fetchZones = async () => { @@ -148,6 +150,7 @@ const ZoneGroup: React.FC = () => { } }, [toolMode, toggleView]); + // eslint-disable-next-line react-hooks/exhaustive-deps const addZoneToBackend = async (zone: { zoneId: string; zoneName: string; @@ -503,6 +506,15 @@ const ZoneGroup: React.FC = () => { draggedSphere, movePoint, activeLayer, + raycaster, + pointer, + controls, + plane, + setZones, + setZonePoints, + addZoneToBackend, + handleDeleteZone, + updateZoneToBackend, ]); useFrame(() => { @@ -551,6 +563,7 @@ const ZoneGroup: React.FC = () => { key={index} position={midpoint} rotation={[0, -angle, 0]} + // visible={false} > { - const { camMode, setCamMode } = useCamMode(); - const [, get] = useKeyboardControls() - const [isTransitioning, setIsTransitioning] = useState(false); - const state: any = useThree(); - const { toggleView } = useToggleView(); + 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) { - // console.log('Pointer is locked'); - } else { - // console.log('Pointer is unlocked'); - if (camMode === "FirstPerson" && !toggleView) { - setCamMode("ThirdPerson"); - await switchToThirdPerson(state.controls, state.camera); - } - } - }; - - document.addEventListener('pointerlockchange', handlePointerLockChange); - - return () => { - document.removeEventListener('pointerlockchange', handlePointerLockChange); - }; - }, [camMode, toggleView, setCamMode, state.controls, state.camera]); - - useEffect(() => { - const handleKeyPress = async (event: any) => { - if (!state.controls) return; - - const keyCombination = detectModifierKeys(event); - - if (keyCombination === "/" && !isTransitioning && !toggleView) { - setIsTransitioning(true); - state.controls.mouseButtons.left = CONSTANTS.controlsTransition.leftMouse; - state.controls.mouseButtons.right = CONSTANTS.controlsTransition.rightMouse; - state.controls.mouseButtons.wheel = CONSTANTS.controlsTransition.wheelMouse; - state.controls.mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse; - - if (camMode === 'ThirdPerson') { - setCamMode("FirstPerson"); - await switchToFirstPerson(state.controls, state.camera); - } else if (camMode === "FirstPerson") { - setCamMode("ThirdPerson"); - await switchToThirdPerson(state.controls, state.camera); - } - - setIsTransitioning(false); - } - }; - - window.addEventListener("keydown", handleKeyPress); - return () => { - window.removeEventListener("keydown", handleKeyPress); - }; - }, [camMode, isTransitioning, toggleView, state.controls, state.camera, setCamMode]); - - useFrame(() => { - const { forward, backward, left, right } = get(); - if (!state.controls) return - if (!state.controls || camMode === "ThirdPerson" || !document.pointerLockElement) return; - - if (forward) { - state.controls.forward(CONSTANTS.firstPersonControls.forwardSpeed, true) + useEffect(() => { + const handlePointerLockChange = async () => { + if (document.pointerLockElement && !toggleView) { + // Pointer is locked + } else { + // Pointer is unlocked + if (camMode === "FirstPerson" && !toggleView) { + setCamMode("ThirdPerson"); + await switchToThirdPerson(state.controls, state.camera); } - if (backward) { - state.controls.forward(CONSTANTS.firstPersonControls.backwardSpeed, true) - } - if (left) { - state.controls.truck(CONSTANTS.firstPersonControls.leftSpeed, 0, true) - } - if (right) { - state.controls.truck(CONSTANTS.firstPersonControls.rightSpeed, 0, true) - } - }); + } + }; - return null; // This component does not render any UI + document.addEventListener("pointerlockchange", handlePointerLockChange); + + return () => { + document.removeEventListener( + "pointerlockchange", + handlePointerLockChange + ); + }; + }, [camMode, toggleView, setCamMode, state.controls, state.camera]); + + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Shift") { + setIsShiftActive(true); + } + }; + + const handleKeyUp = (event: KeyboardEvent) => { + if (event.key === "Shift") { + setIsShiftActive(false); + } + }; + + window.addEventListener("keydown", handleKeyDown); + window.addEventListener("keyup", handleKeyUp); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + window.removeEventListener("keyup", handleKeyUp); + }; + }, []); + + useEffect(() => { + const handleKeyPress = async (event: KeyboardEvent) => { + if (!state.controls) return; + + const keyCombination = detectModifierKeys(event); + + if (keyCombination === "/" && !isTransitioning && !toggleView) { + setIsTransitioning(true); + + state.controls.mouseButtons.left = + CONSTANTS.controlsTransition.leftMouse; + state.controls.mouseButtons.right = + CONSTANTS.controlsTransition.rightMouse; + state.controls.mouseButtons.wheel = + CONSTANTS.controlsTransition.wheelMouse; + state.controls.mouseButtons.middle = + CONSTANTS.controlsTransition.middleMouse; + + if (camMode === "ThirdPerson") { + setCamMode("FirstPerson"); + await switchToFirstPerson(state.controls, state.camera); + } else if (camMode === "FirstPerson") { + setCamMode("ThirdPerson"); + await switchToThirdPerson(state.controls, state.camera); + } + + setIsTransitioning(false); + } + }; + + window.addEventListener("keydown", handleKeyPress); + return () => { + window.removeEventListener("keydown", handleKeyPress); + }; + }, [ + 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; + + 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 + ); + } + }); + + return null; // This component does not render any UI }; -export default CamMode; \ No newline at end of file +export default CamMode; diff --git a/app/src/types/world/worldConstants.ts b/app/src/types/world/worldConstants.ts index 924c12c..0374c8a 100644 --- a/app/src/types/world/worldConstants.ts +++ b/app/src/types/world/worldConstants.ts @@ -189,10 +189,10 @@ export const firstPersonControls: Controls = { maxDistance: 0, // Maximum distance from the target maxPolarAngle: Math.PI, // Maximum polar angle leftMouse: 1, // Mouse button for rotation (ROTATE) - forwardSpeed: 0.3, // Speed of forward movement - backwardSpeed: -0.3, // Speed of backward movement - leftSpeed: -0.3, // Speed of left movement - rightSpeed: 0.3, // Speed of right movement + forwardSpeed: 0.1, // Speed of forward movement + backwardSpeed: -0.1, // Speed of backward movement + leftSpeed: -0.1, // Speed of left movement + rightSpeed: 0.1, // Speed of right movement }; export const thirdPersonControls: ThirdPersonControls = { diff --git a/app/src/utils/shortcutkeys/handleShortcutKeys.ts b/app/src/utils/shortcutkeys/handleShortcutKeys.ts index 43ca553..52877b9 100644 --- a/app/src/utils/shortcutkeys/handleShortcutKeys.ts +++ b/app/src/utils/shortcutkeys/handleShortcutKeys.ts @@ -190,7 +190,7 @@ const KeyPressListener: React.FC = () => { return () => { window.removeEventListener("keydown", handleKeyPress); }; - }, [activeModule, toggleUI, toggleView]); // Dependencies to reapply effect if these values change + }, [activeModule, setActiveModule, setActiveSubTool, setActiveTool, setAddAction, setDeleteTool, setIsPlaying, setSelectedWallItem, setToggleThreeD, setToggleUI, setToggleView, setToolMode, toggleUI, toggleView]); // Dependencies to reapply effect if these values change return null; // This component does not render any UI };