From 2d294de69ad96827098defc93e42820be7ac1031 Mon Sep 17 00:00:00 2001 From: Matthias Puchstein Date: Thu, 17 Jul 2025 03:36:20 +0200 Subject: [PATCH] refactored `DreamVR` to simplify component structure, integrate `OrbitControls` for non-VR mode, enhance lighting, and optimize render logic for improved performance and maintainability Signed-off-by: Matthias Puchstein --- src/components/DreamVR.tsx | 184 +++++++++++++++---------------------- 1 file changed, 72 insertions(+), 112 deletions(-) diff --git a/src/components/DreamVR.tsx b/src/components/DreamVR.tsx index ddea9ef..535c684 100644 --- a/src/components/DreamVR.tsx +++ b/src/components/DreamVR.tsx @@ -1,17 +1,13 @@ import React, {useMemo, useRef} from 'react'; import {Canvas, useFrame} from '@react-three/fiber'; -import {createXRStore, XR} from '@react-three/xr'; -import {PerspectiveCamera} from '@react-three/drei'; +import {createXRStore, useXR, XR} from '@react-three/xr'; +import {OrbitControls, PerspectiveCamera} from '@react-three/drei'; import * as THREE from 'three'; import type Dream from '../types/Dream'; // Neural Node component representing a synapse in the neural network const NeuralNode = ({position, color, scale, pulseSpeed, pulseIntensity}: { - position: [number, number, number], - color: string, - scale: number, - pulseSpeed: number, - pulseIntensity: number + position: [number, number, number], color: string, scale: number, pulseSpeed: number, pulseIntensity: number }) => { const nodeRef = useRef(null); const initialScale = scale; @@ -24,18 +20,10 @@ const NeuralNode = ({position, color, scale, pulseSpeed, pulseIntensity}: { } }); - return ( - - - - - ); + return ( + + + ); }; // Neural Connection component representing connections between synapses @@ -51,60 +39,36 @@ const NeuralConnection = ({start, end, color, thickness, pulseSpeed, pulseIntens // Create a cylinder between two points const direction = useMemo(() => { - return new THREE.Vector3( - end[0] - start[0], - end[1] - start[1], - end[2] - start[2] - ); + return new THREE.Vector3(end[0] - start[0], end[1] - start[1], end[2] - start[2]); }, [start, end]); const length = useMemo(() => direction.length(), [direction]); // Calculate rotation to align cylinder with direction - const rotationMatrix = useMemo(() => { + useMemo(() => { const normalizedDirection = direction.clone().normalize(); const quaternion = new THREE.Quaternion(); - quaternion.setFromUnitVectors( - new THREE.Vector3(0, 1, 0), // Default cylinder orientation - normalizedDirection - ); + quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), // Default cylinder orientation + normalizedDirection); return new THREE.Matrix4().makeRotationFromQuaternion(quaternion); }, [direction]); - // Calculate position (midpoint between start and end) const position = useMemo(() => { - return [ - (start[0] + end[0]) / 2, - (start[1] + end[1]) / 2, - (start[2] + end[2]) / 2 - ] as [number, number, number]; + return [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2, (start[2] + end[2]) / 2] as [number, number, number]; }, [start, end]); useFrame(({clock}) => { if (connectionRef.current) { // Create a pulsing effect for the connection - const pulse = Math.sin(clock.getElapsedTime() * pulseSpeed + - (start[0] + start[1] + start[2])) * pulseIntensity + 1; + const pulse = Math.sin(clock.getElapsedTime() * pulseSpeed + (start[0] + start[1] + start[2])) * pulseIntensity + 1; connectionRef.current.scale.set(thickness * pulse, length / 2, thickness * pulse); } }); - return ( - - - - - ); + return ( + + + ); }; // Neural Network component that generates nodes and connections @@ -147,11 +111,7 @@ const NeuralNetwork = ({dream}: { dream: Dream }) => { const pulseIntensity = 0.1 + (chipInput.bewegung[i % chipInput.bewegung.length] * 2); nodes.push({ - position: [x, y, z] as [number, number, number], - color, - scale, - pulseSpeed, - pulseIntensity + position: [x, y, z] as [number, number, number], color, scale, pulseSpeed, pulseIntensity }); } @@ -185,34 +145,50 @@ const NeuralNetwork = ({dream}: { dream: Dream }) => { return connections; }, [nodes, dream]); - return ( - <> + return (<> {/* Render all nodes */} - {nodes.map((node, index) => ( - ( - ))} + />))} {/* Render all connections */} - {connections.map((connection, index) => ( - ( - ))} - - ); + />))} + ); +}; + +// Camera Controls component that handles XR and non-XR states +const CameraControls = () => { + const {session} = useXR(); + + // Only enable OrbitControls when NOT in VR session + if (session) { + return null; // Let XR handle camera in VR mode + } + + return (); }; // Main DreamVR component @@ -229,61 +205,45 @@ const DreamVR: React.FC = ({dream, height = '500px'}) => { // Only render VR for dream with chip input type if (dream.input.inputType !== 'chip') { - return ( -
-

- VR-Visualisierung ist nur für Träume mit Chip-Eingabe verfügbar. -

-
- ); + return (
+ VR-Visualisierung ist nur für Träume mit Chip-Eingabe verfügbar. +
); } - return ( -
+ return (
{/* VR Entry Button */} -
- -
+ - + {/* Camera setup */} - + + + {/* Camera Controls - only active outside VR */} + {/* Lighting */} - - - + + + {/* Neural network visualization */} {/* Background */} - + + + + -
- ); +
); }; export default DreamVR; \ No newline at end of file