diff --git a/GEMstack/onboard/visualization/sr_viz/threeD/.gitignore b/GEMstack/onboard/visualization/sr_viz/threeD/.gitignore index 4a7f73a2e..5ef6a5207 100644 --- a/GEMstack/onboard/visualization/sr_viz/threeD/.gitignore +++ b/GEMstack/onboard/visualization/sr_viz/threeD/.gitignore @@ -1,24 +1,41 @@ -# Nuxt dev/build outputs -.output -.data -.nuxt -.nitro -.cache -dist - -# Node dependencies -node_modules - -# Logs -logs -*.log - -# Misc +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc .DS_Store -.fleet -.idea +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel -# Local env files -.env -.env.* -!.env.example +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/GEMstack/onboard/visualization/sr_viz/threeD/legacy/.gitignore b/GEMstack/onboard/visualization/sr_viz/threeD/legacy/.gitignore new file mode 100644 index 000000000..4a7f73a2e --- /dev/null +++ b/GEMstack/onboard/visualization/sr_viz/threeD/legacy/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/GEMstack/onboard/visualization/sr_viz/threeD/src/components/ControlPanel.tsx b/GEMstack/onboard/visualization/sr_viz/threeD/src/components/ControlPanel.tsx index c2b62df99..97122e70c 100644 --- a/GEMstack/onboard/visualization/sr_viz/threeD/src/components/ControlPanel.tsx +++ b/GEMstack/onboard/visualization/sr_viz/threeD/src/components/ControlPanel.tsx @@ -31,6 +31,14 @@ export default function ControlPanel({ reset }: { reset: () => void }) { console.error("❌ Failed to parse log file:", err); } }; + const handleContextMenu = (event: React.MouseEvent) => { + event.preventDefault(); + if (isOpen) { + setIsOpen(false); + } else { + setIsOpen(true); + } + } return ( <> @@ -38,6 +46,7 @@ export default function ControlPanel({ reset }: { reset: () => void }) { className={`fixed top-0 left-0 h-full w-64 bg-black/80 text-white shadow-lg transform transition-transform duration-500 ease-in-out z-40 ${ isOpen ? "translate-x-0" : "-translate-x-full" }`} + onContextMenu={handleContextMenu} > {isOpen && ( <> @@ -80,6 +89,7 @@ export default function ControlPanel({ reset }: { reset: () => void }) { onClick={() => setIsOpen(true)} className="fixed top-1/2 left-0 -translate-y-1/2 z-50 bg-black/80 text-white w-3 h-8 flex items-center justify-center rounded-r hover:bg-black border-l border-white/20" title="Open Panel" + onContextMenu={(e) => e.preventDefault()} > ⟩ diff --git a/GEMstack/onboard/visualization/sr_viz/threeD/src/components/Scrubber.tsx b/GEMstack/onboard/visualization/sr_viz/threeD/src/components/Scrubber.tsx index 459984bf2..a1a15b6ae 100644 --- a/GEMstack/onboard/visualization/sr_viz/threeD/src/components/Scrubber.tsx +++ b/GEMstack/onboard/visualization/sr_viz/threeD/src/components/Scrubber.tsx @@ -1,5 +1,5 @@ "use client"; -import React, { useState, useRef } from "react"; +import React, { useState } from "react"; import { IconButton, Slider, Menu, MenuItem } from "@mui/material"; import PlayArrowIcon from "@mui/icons-material/PlayArrow"; import PauseIcon from "@mui/icons-material/Pause"; @@ -13,7 +13,7 @@ export default function Scrubber({ restart, setPlaybackSpeed, moveToTime, - duration + duration, }: { time: number; play: boolean; @@ -27,6 +27,7 @@ export default function Scrubber({ const [selectedSpeed, setSelectedSpeed] = useState(1); const speedOptions = [0.5, 1, 1.5, 2, 3]; const open = Boolean(anchorEl); + const [isDragging, setIsDragging] = useState(false); const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; @@ -38,32 +39,64 @@ export default function Scrubber({ setPlaybackSpeed(speed); handleClose(); }; - const handleSliderChange = (_: Event, newValue: number | number[]) => { - if (typeof newValue === "number") { - moveToTime(newValue); - } + const handleSliderChange = (_: Event, newValue: number) => { + moveToTime(newValue); }; + const handleSliderChangeCommitted = () => { + setIsDragging(false); + } const formatDuration = (time: number) => { const minutes = Math.floor(time / 60); const seconds = Math.floor(time % 60); - return `${minutes < 10 ? "0" : ""}${minutes}:${seconds < 10 ? "0" : ""}${seconds}`; - } + return `${minutes < 10 ? "0" : ""}${minutes}:${ + seconds < 10 ? "0" : "" + }${seconds}`; + }; + const handleContextMenu = (event: React.MouseEvent) => { + event.preventDefault(); + }; return ( - - + + {play ? ( ) : ( )} - - {time < duration ? formatDuration(time) : formatDuration(duration)} - + + + {time < duration + ? formatDuration(time) + : formatDuration(duration)} + + setIsDragging(true)} + onChangeCommitted={handleSliderChangeCommitted} + value={time} + /> {formatDuration(duration)} - - + + ))} - + diff --git a/GEMstack/onboard/visualization/sr_viz/threeD/src/config/cameraConfig.ts b/GEMstack/onboard/visualization/sr_viz/threeD/src/config/cameraConfig.ts index 6de374087..b235ede20 100644 --- a/GEMstack/onboard/visualization/sr_viz/threeD/src/config/cameraConfig.ts +++ b/GEMstack/onboard/visualization/sr_viz/threeD/src/config/cameraConfig.ts @@ -10,7 +10,7 @@ type CameraConfigMap = { const cameraConfig: CameraConfigMap = { first: { - position: [0, 1.5, -0.3], // on top of vehicle + position: [0.2, 1.5, -0.3], // on top of vehicle lookAt: [2, 1.5, 0], // looking forward (+Z) damping: 0.1, }, diff --git a/GEMstack/onboard/visualization/sr_viz/threeD/src/config/groundConfig.ts b/GEMstack/onboard/visualization/sr_viz/threeD/src/config/groundConfig.ts index d3c653c9f..751a789f7 100644 --- a/GEMstack/onboard/visualization/sr_viz/threeD/src/config/groundConfig.ts +++ b/GEMstack/onboard/visualization/sr_viz/threeD/src/config/groundConfig.ts @@ -14,7 +14,7 @@ export interface GroundConfig { } const groundConfig: GroundConfig = { - size: [20000, 20000], + size: [1000, 1000], position: [0, 0, 0], rotation: [0, 0, 0], cellSize: 1,