From 4a0c88819f6e5223a771323975ebb03807be033e Mon Sep 17 00:00:00 2001 From: yushiang Date: Fri, 3 May 2024 20:16:02 +0800 Subject: [PATCH] feature: add real-time data monitor. --- src/App.jsx | 119 +++++++++++++++++++++++++++++++++++++++++------- src/ThreeApp.js | 11 +++-- 2 files changed, 111 insertions(+), 19 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 1ffdbd8..23c61d7 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,12 +1,51 @@ import React, { useEffect, useRef, useState } from "react"; import ThreeApp from "./ThreeApp"; import { LineChart } from "@mui/x-charts"; + +function densityDecay(distance) { + return distance; +} const FullScreenCanvas = () => { + const [isPause, setIsPause] = useState(true); const [chartData, setChartData] = useState(null); const [core, setCore] = useState(null); const [isTeleport, setIsTeleport] = useState(false); const canvasRef = useRef(null); + useEffect(() => { + if (!core) return; + if (isPause) return; + const timer = setInterval(() => { + setChartData((data) => { + const newChart = data || []; + const sensors = core.getSensors(); + sensors.forEach(({ position, color }, index) => { + if (!newChart[index]) { + newChart[index] = { + data: [], + color: `#${color.getHexString()}`, + curve: "linear", + }; + } + const distance = densityDecay( + core.getFpvCamera().position.distanceTo(position) + ); + newChart[index].data.unshift(distance); + if (newChart[index].data.length > 20) { + newChart[index].data.pop(); + } + }); + return [...newChart]; + }); + }, 5e2); + return () => clearInterval(timer); + }, [core, isPause]); + + useEffect(() => { + if (!core) return; + core.animator.setIsPause(isPause); + }, [isPause, core]); + useEffect(() => { const canvas = canvasRef.current; const threeApp = new ThreeApp(canvas); @@ -33,22 +72,26 @@ const FullScreenCanvas = () => { const path = core.findPathTo(point); if (path) { - const sensors = core.getSensors(); - const distanceToSensor = sensors.map(({ position, color }) => { - return { - data: path.map((point) => point.distanceTo(position)), - color: `#${color.getHexString()}`, - curve: "linear", - }; - }); - setChartData(distanceToSensor); - core.setCamera( [path[0].x, path[0].y, path[0].z], [path[1].x, path[1].y, path[1].z] ); core.setPath(path); - core.animator.setTargets(path); + if (!isPause) { + core.animator.setTargets(path); + } else { + const sensors = core.getSensors(); + const distanceToSensor = sensors.map(({ position, color }) => { + return { + data: path.map((point) => + densityDecay(point.distanceTo(position)) + ), + color: `#${color.getHexString()}`, + curve: "linear", + }; + }); + setChartData(distanceToSensor); + } } } }; @@ -62,18 +105,62 @@ const FullScreenCanvas = () => { canvas.addEventListener("pointerdown", core.onSelectSensor); canvas.removeEventListener("pointerup", onPointerUp); }; - }, [core, isTeleport]); + }, [core, isTeleport, isPause]); + + const rawData = chartData?.map(({ data, color }) => ({ + sensor: color, + distance: data[0], + })); return ( <> -
+ {!isPause && ( +
+ +
+ )} + +
+ - {chartData && ( index) }]} + xAxis={[ + { + data: chartData[0].data.map((_, index) => index), + label: "Steps", + }, + ]} + yAxis={[ + { + label: "Sensor Distance", + max: 15, + min: 0, + }, + ]} series={chartData} width={Math.min(500, document.documentElement.clientWidth)} height={300} diff --git a/src/ThreeApp.js b/src/ThreeApp.js index 609bf65..2be97e8 100644 --- a/src/ThreeApp.js +++ b/src/ThreeApp.js @@ -71,7 +71,7 @@ function ThreeApp(canvas) { }; })(); - const { setCamera, fpvCameraAgent, fpvCamera } = (() => { + const { setCamera, fpvCameraAgent, fpvCamera, getFpvCamera } = (() => { const agent = new THREE.Object3D(); const walkThroughViewCamera = new THREE.PerspectiveCamera( @@ -102,8 +102,11 @@ function ThreeApp(canvas) { agent.position.set(x, y, z); agent.lookAt(lookAtX, lookAtY, lookAtZ); }; + + const getFpvCamera = () => agent; return { setCamera, + getFpvCamera, fpvCameraAgent: agent, fpvCamera: walkThroughViewCamera, }; @@ -288,8 +291,9 @@ function ThreeApp(canvas) { renderer.setScissor(0, 0, viewportWidth, viewportHeight); renderer.render(scene, camera); - renderer.setViewport(0, 0, viewportWidth / 3, viewportHeight / 3); - renderer.setScissor(0, 0, viewportWidth / 3, viewportHeight / 3); + const size = 1 / 4; + renderer.setViewport(0, 0, viewportWidth * size, viewportHeight * size); + renderer.setScissor(0, 0, viewportWidth * size, viewportHeight * size); renderer.render(scene, fpvCamera); }; @@ -314,6 +318,7 @@ function ThreeApp(canvas) { setCamera, setPath, getSensors, + getFpvCamera, onSelectSensor, }; }