import React, { useRef, useEffect, useState } from 'react'; import { Canvas, useFrame, useThree } from '@react-three/fiber'; import { OrbitControls, Text, Sphere, Line } from '@react-three/drei'; import * as THREE from 'three'; import { motion } from 'framer-motion'; // Emotion space visualization component function EmotionSpace({ analysisData, isActive }) { const meshRef = useRef(); const pointsRef = useRef(); const [emotionHistory, setEmotionHistory] = useState([]); useEffect(() => { if (analysisData && isActive) { setEmotionHistory(prev => [...prev.slice(-50), analysisData]); } }, [analysisData, isActive]); useFrame((state) => { if (meshRef.current) { meshRef.current.rotation.y += 0.005; } }); // Convert emotion probabilities to 3D coordinates const getEmotionCoordinates = (emotions) => { if (!emotions || emotions.length !== 7) return [0, 0, 0]; // Map emotions to 3D space: valence (x), arousal (y), dominance (z) const valence = emotions[3] - emotions[4]; // happy - sad const arousal = (emotions[0] + emotions[2] + emotions[5]) - (emotions[1] + emotions[6]); // angry + fear + surprise - disgust - neutral const dominance = emotions[6] - (emotions[1] + emotions[2]); // neutral - (disgust + fear) return [valence * 2, arousal * 2, dominance * 2]; }; return ( {/* Emotion axes */} {/* Axis labels */} Valence Arousal Dominance {/* Current emotion point */} {analysisData && ( )} {/* Emotion trajectory */} {emotionHistory.length > 1 && ( getEmotionCoordinates(data.emotion?.probabilities))} color="cyan" lineWidth={3} /> )} {/* Emotion labels at corners */} Happy Sad Angry Surprised ); } // Intent visualization component function IntentVisualization({ analysisData, isActive }) { const groupRef = useRef(); const [intentHistory, setIntentHistory] = useState([]); useEffect(() => { if (analysisData && isActive) { setIntentHistory(prev => [...prev.slice(-30), analysisData]); } }, [analysisData, isActive]); useFrame((state) => { if (groupRef.current) { groupRef.current.rotation.z += 0.01; } }); // Convert intent to radial coordinates const getIntentPosition = (intent, index) => { const angle = (index / 5) * Math.PI * 2; const radius = intent * 2; return [Math.cos(angle) * radius, Math.sin(angle) * radius, 0]; }; return ( {/* Intent radar chart */} {analysisData?.intent?.probabilities?.map((prob, idx) => ( ))} {/* Intent labels */} {['Agreement', 'Confusion', 'Hesitation', 'Confidence', 'Neutral'].map((intent, idx) => { const angle = (idx / 5) * Math.PI * 2; const x = Math.cos(angle) * 2.5; const y = Math.sin(angle) * 2.5; return ( {intent} ); })} {/* Connecting lines */} {analysisData?.intent?.probabilities && ( getIntentPosition(prob, idx)), getIntentPosition(analysisData.intent.probabilities[0], 0) // Close the shape ]} color="lime" lineWidth={2} /> )} ); } // Modality fusion visualization function ModalityFusion({ analysisData, isActive }) { const fusionRef = useRef(); useFrame((state) => { if (fusionRef.current) { fusionRef.current.rotation.x += 0.005; fusionRef.current.rotation.y += 0.003; } }); return ( {/* Vision sphere */} {/* Audio sphere */} {/* Text sphere */} {/* Fusion center */} {/* Connection lines */} {/* Labels */} Vision Audio Text Fusion ); } // Main 3D visualization component export default function Advanced3DVisualization({ analysisData, isActive }) { const [activeView, setActiveView] = useState('emotion'); return (
{/* View Controls */}
{[ { key: 'emotion', label: 'Emotion Space', icon: '🧠' }, { key: 'intent', label: 'Intent Radar', icon: '🎯' }, { key: 'fusion', label: 'Modality Fusion', icon: '🔗' } ].map(({ key, label, icon }) => ( setActiveView(key)} className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors ${ activeView === key ? 'bg-cyan-600 text-white' : 'bg-white/10 text-gray-300 hover:bg-white/20' }`} > {icon} {label} ))}
{/* 3D Canvas */} {activeView === 'emotion' && ( )} {activeView === 'intent' && ( )} {activeView === 'fusion' && ( )} {/* Info Panel */}
3D Analysis
{activeView === 'emotion' && 'Visualizing emotion in 3D valence-arousal-dominance space'} {activeView === 'intent' && 'Intent analysis as radar chart with temporal tracking'} {activeView === 'fusion' && 'Multi-modal fusion showing contribution weights'}
Drag to rotate • Scroll to zoom • Right-click to pan
); }