Spaces:
Sleeping
Sleeping
Komalpreet Kaur
feat: Overhaul Soma UI to premium Neural Gloss aesthetic with single-screen optimization
cdcf600 unverified | import { useEffect, useMemo, useRef, useState } from 'react'; | |
| import * as THREE from 'three'; | |
| import './CognitiveBrainScene.css'; | |
| const REGIONS = [ | |
| { | |
| id: 'sensory_cortex', | |
| label: 'Sensory Cortex', | |
| shortLabel: 'Sensory', | |
| color: '#4d9fff', | |
| position: [-2.3, 0.95, 0.9], | |
| scale: [1.25, 0.78, 0.92], | |
| description: 'Receives the raw language signal and begins perceptual parsing.', | |
| phases: ['perception'], | |
| }, | |
| { | |
| id: 'thalamus', | |
| label: 'Thalamus', | |
| shortLabel: 'Thalamus', | |
| color: '#18b8a6', | |
| position: [0.0, 0.1, 0.55], | |
| scale: [0.7, 0.62, 0.72], | |
| description: 'Scores salience, routes signals, and suppresses low-priority recalls.', | |
| phases: ['attention', 'routing', 'inhibition'], | |
| }, | |
| { | |
| id: 'amygdala', | |
| label: 'Amygdala', | |
| shortLabel: 'Amygdala', | |
| color: '#ef5a55', | |
| position: [-0.85, -0.88, 0.7], | |
| scale: [0.48, 0.38, 0.46], | |
| description: 'Flags emotional intensity and urgency in the incoming message.', | |
| phases: ['emotion'], | |
| }, | |
| { | |
| id: 'hippocampus', | |
| label: 'Hippocampus', | |
| shortLabel: 'Hippocampus', | |
| color: '#2fca84', | |
| position: [0.78, -0.95, 0.58], | |
| scale: [0.82, 0.33, 0.48], | |
| description: 'Retrieves relevant conversational and vector memories.', | |
| phases: ['working_memory', 'recall'], | |
| }, | |
| { | |
| id: 'prefrontal_cortex', | |
| label: 'Prefrontal Cortex', | |
| shortLabel: 'Prefrontal', | |
| color: '#9a67ff', | |
| position: [2.1, 0.95, 0.82], | |
| scale: [1.22, 0.88, 0.95], | |
| description: 'Builds intent, predicts needs, and plans the response strategy.', | |
| phases: ['prediction', 'reflection', 'reasoning'], | |
| }, | |
| { | |
| id: 'language_cortex', | |
| label: 'Language Cortex', | |
| shortLabel: 'Language', | |
| color: '#ff5f9a', | |
| position: [2.25, -0.25, 0.75], | |
| scale: [0.96, 0.6, 0.8], | |
| description: 'Converts the response plan into natural language output.', | |
| phases: ['language'], | |
| }, | |
| ]; | |
| const DEFAULT_REGION_ID = 'prefrontal_cortex'; | |
| const DEFAULT_PHASE = 'idle'; | |
| const PHASE_MOODS = { | |
| idle: { | |
| accent: '#86dbff', | |
| glow: 'rgba(77, 159, 255, 0.18)', | |
| glowSecondary: 'rgba(255, 95, 154, 0.16)', | |
| glowTertiary: 'rgba(31, 211, 180, 0.16)', | |
| backgroundStart: '#050d16', | |
| backgroundMid: '#08121e', | |
| backgroundEnd: '#071522', | |
| fog: '#07111d', | |
| keyLight: '#8cc8ff', | |
| rimLight: '#ff7fc0', | |
| floorLight: '#1fd3b4', | |
| particle: '#90bbff', | |
| }, | |
| perception: { | |
| accent: '#76b8ff', | |
| glow: 'rgba(118, 184, 255, 0.24)', | |
| glowSecondary: 'rgba(116, 203, 255, 0.12)', | |
| glowTertiary: 'rgba(29, 109, 255, 0.14)', | |
| backgroundStart: '#06101d', | |
| backgroundMid: '#0a1a30', | |
| backgroundEnd: '#081a2a', | |
| fog: '#081826', | |
| keyLight: '#84beff', | |
| rimLight: '#50b7ff', | |
| floorLight: '#1b82ff', | |
| particle: '#94c8ff', | |
| }, | |
| attention: { | |
| accent: '#5fe8d5', | |
| glow: 'rgba(28, 214, 184, 0.24)', | |
| glowSecondary: 'rgba(89, 231, 201, 0.14)', | |
| glowTertiary: 'rgba(92, 167, 255, 0.12)', | |
| backgroundStart: '#061115', | |
| backgroundMid: '#0a1e25', | |
| backgroundEnd: '#081922', | |
| fog: '#09171d', | |
| keyLight: '#57e2d0', | |
| rimLight: '#8dc8ff', | |
| floorLight: '#17b89d', | |
| particle: '#80f2e0', | |
| }, | |
| routing: { | |
| accent: '#79f2b7', | |
| glow: 'rgba(70, 227, 154, 0.22)', | |
| glowSecondary: 'rgba(27, 208, 255, 0.12)', | |
| glowTertiary: 'rgba(125, 220, 255, 0.14)', | |
| backgroundStart: '#07140f', | |
| backgroundMid: '#0b211a', | |
| backgroundEnd: '#081a16', | |
| fog: '#0a1713', | |
| keyLight: '#76f2b8', | |
| rimLight: '#4ec6ff', | |
| floorLight: '#24df84', | |
| particle: '#8ff0c6', | |
| }, | |
| emotion: { | |
| accent: '#ff8f8a', | |
| glow: 'rgba(239, 90, 85, 0.28)', | |
| glowSecondary: 'rgba(255, 149, 94, 0.18)', | |
| glowTertiary: 'rgba(255, 110, 154, 0.18)', | |
| backgroundStart: '#16070b', | |
| backgroundMid: '#251018', | |
| backgroundEnd: '#1c0a13', | |
| fog: '#180b10', | |
| keyLight: '#ff8f8a', | |
| rimLight: '#ff6d8f', | |
| floorLight: '#ff9a5e', | |
| particle: '#ffb0a9', | |
| }, | |
| prediction: { | |
| accent: '#b896ff', | |
| glow: 'rgba(154, 103, 255, 0.25)', | |
| glowSecondary: 'rgba(120, 170, 255, 0.14)', | |
| glowTertiary: 'rgba(205, 142, 255, 0.14)', | |
| backgroundStart: '#0d0819', | |
| backgroundMid: '#181028', | |
| backgroundEnd: '#110a1e', | |
| fog: '#110c1a', | |
| keyLight: '#b896ff', | |
| rimLight: '#7ca9ff', | |
| floorLight: '#c982ff', | |
| particle: '#ccb1ff', | |
| }, | |
| working_memory: { | |
| accent: '#a5bcc9', | |
| glow: 'rgba(148, 170, 184, 0.22)', | |
| glowSecondary: 'rgba(126, 149, 167, 0.12)', | |
| glowTertiary: 'rgba(83, 194, 255, 0.12)', | |
| backgroundStart: '#0b1015', | |
| backgroundMid: '#121a21', | |
| backgroundEnd: '#0d141b', | |
| fog: '#0d141a', | |
| keyLight: '#aec4d2', | |
| rimLight: '#6ca4d8', | |
| floorLight: '#8aa0ad', | |
| particle: '#bfd4df', | |
| }, | |
| recall: { | |
| accent: '#63dd9b', | |
| glow: 'rgba(47, 202, 132, 0.24)', | |
| glowSecondary: 'rgba(104, 237, 186, 0.14)', | |
| glowTertiary: 'rgba(89, 220, 255, 0.12)', | |
| backgroundStart: '#07130f', | |
| backgroundMid: '#0d2219', | |
| backgroundEnd: '#0a1814', | |
| fog: '#0b1712', | |
| keyLight: '#63dd9b', | |
| rimLight: '#76e9cf', | |
| floorLight: '#1fd3b4', | |
| particle: '#86efbc', | |
| }, | |
| inhibition: { | |
| accent: '#ffb46e', | |
| glow: 'rgba(249, 115, 22, 0.24)', | |
| glowSecondary: 'rgba(255, 180, 110, 0.16)', | |
| glowTertiary: 'rgba(255, 223, 129, 0.12)', | |
| backgroundStart: '#161009', | |
| backgroundMid: '#26170d', | |
| backgroundEnd: '#1d120b', | |
| fog: '#17110c', | |
| keyLight: '#ffb46e', | |
| rimLight: '#ffd579', | |
| floorLight: '#ff8f4d', | |
| particle: '#ffd09d', | |
| }, | |
| reflection: { | |
| accent: '#c28dff', | |
| glow: 'rgba(168, 85, 247, 0.24)', | |
| glowSecondary: 'rgba(194, 141, 255, 0.16)', | |
| glowTertiary: 'rgba(119, 182, 255, 0.12)', | |
| backgroundStart: '#10081a', | |
| backgroundMid: '#1b0f2d', | |
| backgroundEnd: '#120a1f', | |
| fog: '#130b1c', | |
| keyLight: '#c28dff', | |
| rimLight: '#9f7dff', | |
| floorLight: '#d77bff', | |
| particle: '#d8b6ff', | |
| }, | |
| association: { | |
| accent: '#ffce72', | |
| glow: 'rgba(245, 158, 11, 0.24)', | |
| glowSecondary: 'rgba(255, 205, 119, 0.16)', | |
| glowTertiary: 'rgba(255, 158, 84, 0.12)', | |
| backgroundStart: '#171108', | |
| backgroundMid: '#2a1a0b', | |
| backgroundEnd: '#1d130a', | |
| fog: '#18120b', | |
| keyLight: '#ffce72', | |
| rimLight: '#ffb84f', | |
| floorLight: '#f59e0b', | |
| particle: '#ffe2a2', | |
| }, | |
| reasoning: { | |
| accent: '#ff93d5', | |
| glow: 'rgba(236, 72, 153, 0.24)', | |
| glowSecondary: 'rgba(255, 147, 213, 0.16)', | |
| glowTertiary: 'rgba(154, 103, 255, 0.14)', | |
| backgroundStart: '#180a14', | |
| backgroundMid: '#291120', | |
| backgroundEnd: '#1c0b16', | |
| fog: '#170c14', | |
| keyLight: '#ff93d5', | |
| rimLight: '#bb90ff', | |
| floorLight: '#ff5ea3', | |
| particle: '#ffb5e3', | |
| }, | |
| language: { | |
| accent: '#ff91b7', | |
| glow: 'rgba(255, 95, 154, 0.24)', | |
| glowSecondary: 'rgba(255, 145, 183, 0.16)', | |
| glowTertiary: 'rgba(255, 204, 116, 0.12)', | |
| backgroundStart: '#180a13', | |
| backgroundMid: '#2b1320', | |
| backgroundEnd: '#1d0d16', | |
| fog: '#170c14', | |
| keyLight: '#ff91b7', | |
| rimLight: '#ffcb74', | |
| floorLight: '#ff5f9a', | |
| particle: '#ffbfd3', | |
| }, | |
| memory: { | |
| accent: '#aab7c6', | |
| glow: 'rgba(148, 163, 184, 0.24)', | |
| glowSecondary: 'rgba(122, 140, 160, 0.16)', | |
| glowTertiary: 'rgba(47, 202, 132, 0.12)', | |
| backgroundStart: '#0c1016', | |
| backgroundMid: '#161c24', | |
| backgroundEnd: '#0d1218', | |
| fog: '#0d1318', | |
| keyLight: '#b8c5d4', | |
| rimLight: '#75d5a2', | |
| floorLight: '#8fa0b5', | |
| particle: '#d2dbe5', | |
| }, | |
| graph: { | |
| accent: '#7ceaff', | |
| glow: 'rgba(6, 182, 212, 0.24)', | |
| glowSecondary: 'rgba(124, 234, 255, 0.16)', | |
| glowTertiary: 'rgba(77, 159, 255, 0.14)', | |
| backgroundStart: '#071116', | |
| backgroundMid: '#0b1d25', | |
| backgroundEnd: '#08161d', | |
| fog: '#09141a', | |
| keyLight: '#7ceaff', | |
| rimLight: '#75a5ff', | |
| floorLight: '#06b6d4', | |
| particle: '#a8f2ff', | |
| }, | |
| }; | |
| function makePulseMaterial(color) { | |
| return new THREE.MeshPhysicalMaterial({ | |
| color, | |
| roughness: 0.22, | |
| metalness: 0.08, | |
| transmission: 0.02, | |
| transparent: true, | |
| opacity: 0.9, | |
| emissive: new THREE.Color(color), | |
| emissiveIntensity: 0.18, | |
| clearcoat: 1, | |
| clearcoatRoughness: 0.24, | |
| }); | |
| } | |
| function findLatestRegionEvent(brainEvents, regionId) { | |
| for (let index = brainEvents.length - 1; index >= 0; index -= 1) { | |
| if (brainEvents[index].region === regionId) return brainEvents[index]; | |
| } | |
| return null; | |
| } | |
| function getActiveEvent(brainEvents) { | |
| return brainEvents.length ? brainEvents[brainEvents.length - 1] : null; | |
| } | |
| function buildTimeline(brainEvents) { | |
| return [...brainEvents].slice(-7).reverse(); | |
| } | |
| function getPhaseMood(phase) { | |
| return PHASE_MOODS[phase || DEFAULT_PHASE] || PHASE_MOODS[DEFAULT_PHASE]; | |
| } | |
| function formatPhaseLabel(phase) { | |
| return (phase || 'idle').replace(/_/g, ' '); | |
| } | |
| function formatRegionLabel(regionId) { | |
| return REGIONS.find((region) => region.id === regionId)?.label || regionId.replace(/_/g, ' '); | |
| } | |
| function formatTimestamp(timestamp) { | |
| if (!timestamp) return 'Unavailable'; | |
| const date = new Date(timestamp); | |
| if (Number.isNaN(date.getTime())) return timestamp; | |
| return date.toLocaleTimeString([], { | |
| hour: '2-digit', | |
| minute: '2-digit', | |
| second: '2-digit', | |
| }); | |
| } | |
| function getSelectedRegion(regions, selectedRegionId) { | |
| return regions.find((region) => region.id === selectedRegionId) || regions.find((region) => region.id === DEFAULT_REGION_ID); | |
| } | |
| function createBrainShellMaterial(color, opacity = 0.12) { | |
| return new THREE.MeshPhysicalMaterial({ | |
| color, | |
| roughness: 0.3, | |
| metalness: 0, | |
| transparent: true, | |
| opacity, | |
| transmission: 0.55, | |
| thickness: 0.8, | |
| emissive: new THREE.Color('#4d9fff'), | |
| emissiveIntensity: 0.05, | |
| clearcoat: 1, | |
| clearcoatRoughness: 0.18, | |
| side: THREE.DoubleSide, | |
| }); | |
| } | |
| function buildHemisphere(side) { | |
| const group = new THREE.Group(); | |
| const shellColor = side === 'left' ? '#d5e4ff' : '#dbe8ff'; | |
| const lateralShift = side === 'left' ? -1 : 1; | |
| const shellMaterial = createBrainShellMaterial(shellColor, 0.11); | |
| const lobeDefinitions = [ | |
| { position: [1.35 * lateralShift, 0.52, 0.08], scale: [1.26, 0.95, 0.98] }, | |
| { position: [0.7 * lateralShift, 1.06, 0.12], scale: [0.9, 0.78, 0.82] }, | |
| { position: [0.9 * lateralShift, -0.18, 0.18], scale: [1.02, 0.8, 0.9] }, | |
| { position: [1.62 * lateralShift, 0.15, -0.32], scale: [0.7, 0.66, 0.7] }, | |
| ]; | |
| lobeDefinitions.forEach((lobe) => { | |
| const mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 44, 44), shellMaterial.clone()); | |
| mesh.position.set(...lobe.position); | |
| mesh.scale.set(...lobe.scale); | |
| group.add(mesh); | |
| }); | |
| const grooveMaterial = new THREE.MeshBasicMaterial({ | |
| color: side === 'left' ? '#c7dfff' : '#dbe9ff', | |
| transparent: true, | |
| opacity: 0.16, | |
| }); | |
| const grooveArcs = [ | |
| [ | |
| new THREE.Vector3(2.0 * lateralShift, 1.25, 0.3), | |
| new THREE.Vector3(1.4 * lateralShift, 0.72, 0.82), | |
| new THREE.Vector3(1.15 * lateralShift, 0.05, 0.98), | |
| new THREE.Vector3(1.58 * lateralShift, -0.66, 0.58), | |
| ], | |
| [ | |
| new THREE.Vector3(1.52 * lateralShift, 1.45, -0.22), | |
| new THREE.Vector3(0.95 * lateralShift, 0.85, 0.15), | |
| new THREE.Vector3(0.82 * lateralShift, 0.1, 0.38), | |
| new THREE.Vector3(1.26 * lateralShift, -0.72, 0.08), | |
| ], | |
| [ | |
| new THREE.Vector3(0.76 * lateralShift, 1.28, 0.22), | |
| new THREE.Vector3(0.42 * lateralShift, 0.64, 0.52), | |
| new THREE.Vector3(0.35 * lateralShift, -0.1, 0.4), | |
| new THREE.Vector3(0.68 * lateralShift, -0.74, 0.12), | |
| ], | |
| ]; | |
| grooveArcs.forEach((points) => { | |
| const curve = new THREE.CatmullRomCurve3(points); | |
| const groove = new THREE.Mesh(new THREE.TubeGeometry(curve, 44, 0.03, 10, false), grooveMaterial.clone()); | |
| group.add(groove); | |
| }); | |
| return group; | |
| } | |
| function makeSignalPulse(color) { | |
| return new THREE.Mesh( | |
| new THREE.SphereGeometry(0.09, 18, 18), | |
| new THREE.MeshBasicMaterial({ | |
| color, | |
| transparent: true, | |
| opacity: 0.95, | |
| }) | |
| ); | |
| } | |
| function CognitiveBrainScene({ brainState }) { | |
| const mountRef = useRef(null); | |
| const connectorsRef = useRef([]); | |
| const hoveredIdRef = useRef(null); | |
| const selectedIdRef = useRef(DEFAULT_REGION_ID); | |
| const activeEventRef = useRef(null); | |
| const labelRefs = useRef(new Map()); | |
| const [hoveredRegionId, setHoveredRegionId] = useState(null); | |
| const [selectedRegionId, setSelectedRegionId] = useState(DEFAULT_REGION_ID); | |
| const brainEvents = brainState.brainEvents || []; | |
| const activeEvent = getActiveEvent(brainEvents); | |
| const currentMood = useMemo(() => getPhaseMood(activeEvent?.phase), [activeEvent?.phase]); | |
| const selectedRegion = useMemo(() => getSelectedRegion(REGIONS, selectedRegionId), [selectedRegionId]); | |
| const selectedEvent = useMemo(() => findLatestRegionEvent(brainEvents, selectedRegion.id), [brainEvents, selectedRegion.id]); | |
| const timeline = useMemo(() => buildTimeline(brainEvents), [brainEvents]); | |
| const selectedInputs = selectedEvent?.inputs_used || []; | |
| const selectedTargets = (selectedEvent?.next_regions || []).map(formatRegionLabel); | |
| const selectedDataEntries = Object.entries(selectedEvent?.data || {}).slice(0, 4); | |
| useEffect(() => { | |
| selectedIdRef.current = selectedRegionId; | |
| }, [selectedRegionId]); | |
| useEffect(() => { | |
| activeEventRef.current = activeEvent; | |
| if (activeEvent?.region) { | |
| setSelectedRegionId(activeEvent.region); | |
| } | |
| }, [activeEvent]); | |
| useEffect(() => { | |
| const mount = mountRef.current; | |
| if (!mount) return undefined; | |
| const scene = new THREE.Scene(); | |
| scene.background = new THREE.Color('#07111d'); | |
| scene.fog = new THREE.Fog('#07111d', 8, 18); | |
| const camera = new THREE.PerspectiveCamera(34, 1, 0.1, 100); | |
| camera.position.set(0, 0.65, 11.5); | |
| camera.lookAt(0.2, 0, 0); | |
| const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); | |
| renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); | |
| renderer.outputColorSpace = THREE.SRGBColorSpace; | |
| mount.appendChild(renderer.domElement); | |
| const ambientLight = new THREE.AmbientLight('#ffffff', 1.2); | |
| const keyLight = new THREE.PointLight('#8cc8ff', 18, 30, 2); | |
| keyLight.position.set(5.5, 4.5, 6); | |
| const rimLight = new THREE.PointLight('#ff7fc0', 9, 24, 2); | |
| rimLight.position.set(-6.2, -2.8, 5); | |
| const floorLight = new THREE.PointLight('#1fd3b4', 7, 22, 2); | |
| floorLight.position.set(0, -5, 7); | |
| scene.add(ambientLight, keyLight, rimLight, floorLight); | |
| const brainGroup = new THREE.Group(); | |
| scene.add(brainGroup); | |
| const leftHemisphere = buildHemisphere('left'); | |
| const rightHemisphere = buildHemisphere('right'); | |
| brainGroup.add(leftHemisphere, rightHemisphere); | |
| const bridge = new THREE.Mesh( | |
| new THREE.CapsuleGeometry(0.42, 1.4, 10, 20), | |
| new THREE.MeshPhysicalMaterial({ | |
| color: '#9ec7ff', | |
| roughness: 0.35, | |
| metalness: 0.04, | |
| transparent: true, | |
| opacity: 0.1, | |
| emissive: new THREE.Color('#1fd3b4'), | |
| emissiveIntensity: 0.04, | |
| }) | |
| ); | |
| bridge.rotation.z = Math.PI / 2; | |
| bridge.position.set(0, -0.15, 0.05); | |
| brainGroup.add(bridge); | |
| const cerebellum = new THREE.Mesh( | |
| new THREE.SphereGeometry(1.02, 34, 34), | |
| new THREE.MeshPhysicalMaterial({ | |
| color: '#b8d0ff', | |
| roughness: 0.36, | |
| metalness: 0.02, | |
| transparent: true, | |
| opacity: 0.14, | |
| emissive: new THREE.Color('#6aa8ff'), | |
| emissiveIntensity: 0.05, | |
| }) | |
| ); | |
| cerebellum.position.set(0.05, -1.62, -0.78); | |
| cerebellum.scale.set(1.55, 0.72, 0.85); | |
| brainGroup.add(cerebellum); | |
| const brainStem = new THREE.Mesh( | |
| new THREE.CapsuleGeometry(0.22, 1.18, 8, 16), | |
| new THREE.MeshPhysicalMaterial({ | |
| color: '#9bc4ff', | |
| roughness: 0.28, | |
| metalness: 0.03, | |
| transparent: true, | |
| opacity: 0.16, | |
| emissive: new THREE.Color('#28d3c8'), | |
| emissiveIntensity: 0.06, | |
| }) | |
| ); | |
| brainStem.position.set(0, -2.0, -0.1); | |
| brainStem.rotation.x = -0.18; | |
| brainGroup.add(brainStem); | |
| const particlesGeometry = new THREE.BufferGeometry(); | |
| const particleCount = 150; | |
| const positions = new Float32Array(particleCount * 3); | |
| for (let i = 0; i < particleCount; i += 1) { | |
| const angle = Math.random() * Math.PI * 2; | |
| const radius = 3.1 + Math.random() * 2.2; | |
| positions[i * 3] = Math.cos(angle) * radius; | |
| positions[i * 3 + 1] = (Math.random() - 0.5) * 5; | |
| positions[i * 3 + 2] = (Math.random() - 0.5) * 4; | |
| } | |
| particlesGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); | |
| const particleMaterial = new THREE.PointsMaterial({ | |
| color: '#90bbff', | |
| size: 0.035, | |
| transparent: true, | |
| opacity: 0.55, | |
| }); | |
| const particles = new THREE.Points(particlesGeometry, particleMaterial); | |
| scene.add(particles); | |
| const regionMeshes = new Map(); | |
| REGIONS.forEach((region) => { | |
| const mesh = new THREE.Mesh(new THREE.IcosahedronGeometry(1, 6), makePulseMaterial(region.color)); | |
| mesh.scale.set(...region.scale); | |
| mesh.position.set(...region.position); | |
| mesh.userData.regionId = region.id; | |
| mesh.userData.baseScale = region.scale; | |
| mesh.userData.baseColor = region.color; | |
| const outline = new THREE.Mesh( | |
| new THREE.SphereGeometry(1.03, 28, 28), | |
| new THREE.MeshBasicMaterial({ | |
| color: region.color, | |
| transparent: true, | |
| opacity: 0.12, | |
| side: THREE.BackSide, | |
| }) | |
| ); | |
| mesh.add(outline); | |
| brainGroup.add(mesh); | |
| regionMeshes.set(region.id, mesh); | |
| }); | |
| const raycaster = new THREE.Raycaster(); | |
| const pointer = new THREE.Vector2(); | |
| function clearConnectors() { | |
| connectorsRef.current.forEach((connector) => { | |
| scene.remove(connector.tube); | |
| connector.tube.geometry.dispose(); | |
| connector.tube.material.dispose(); | |
| connector.pulses.forEach((pulse) => { | |
| scene.remove(pulse); | |
| pulse.geometry.dispose(); | |
| pulse.material.dispose(); | |
| }); | |
| }); | |
| connectorsRef.current = []; | |
| } | |
| function rebuildConnectors(event) { | |
| clearConnectors(); | |
| if (!event?.region || !event.next_regions?.length) return; | |
| const sourceMesh = regionMeshes.get(event.region); | |
| if (!sourceMesh) return; | |
| event.next_regions.forEach((nextRegionId) => { | |
| const targetMesh = regionMeshes.get(nextRegionId); | |
| if (!targetMesh) return; | |
| const points = [ | |
| sourceMesh.position.clone(), | |
| sourceMesh.position.clone().lerp(targetMesh.position, 0.5).add(new THREE.Vector3(0, 0.65, 0.35)), | |
| targetMesh.position.clone(), | |
| ]; | |
| const curve = new THREE.CatmullRomCurve3(points); | |
| const geometry = new THREE.TubeGeometry(curve, 24, 0.035, 10, false); | |
| const material = new THREE.MeshBasicMaterial({ | |
| color: '#c8e4ff', | |
| transparent: true, | |
| opacity: 0.48, | |
| }); | |
| const tube = new THREE.Mesh(geometry, material); | |
| scene.add(tube); | |
| const pulseColor = '#9fd9ff'; | |
| const pulses = [0, 0.32, 0.64].map((offset, index) => { | |
| const pulse = makeSignalPulse(index === 1 ? '#ffffff' : pulseColor); | |
| pulse.userData.offset = offset; | |
| pulse.userData.speed = 0.12 + index * 0.025; | |
| scene.add(pulse); | |
| return pulse; | |
| }); | |
| connectorsRef.current.push({ | |
| tube, | |
| curve, | |
| pulses, | |
| sourceRegionId: event.region, | |
| targetRegionId: nextRegionId, | |
| }); | |
| }); | |
| } | |
| function resize() { | |
| const width = mount.clientWidth; | |
| const height = mount.clientHeight; | |
| renderer.setSize(width, height); | |
| camera.aspect = width / height; | |
| camera.updateProjectionMatrix(); | |
| } | |
| function onPointerMove(event) { | |
| const rect = renderer.domElement.getBoundingClientRect(); | |
| pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; | |
| pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; | |
| } | |
| function onPointerLeave() { | |
| pointer.x = 2; | |
| pointer.y = 2; | |
| hoveredIdRef.current = null; | |
| setHoveredRegionId(null); | |
| } | |
| function onClick() { | |
| if (hoveredIdRef.current) { | |
| setSelectedRegionId(hoveredIdRef.current); | |
| } | |
| } | |
| renderer.domElement.addEventListener('pointermove', onPointerMove); | |
| renderer.domElement.addEventListener('pointerleave', onPointerLeave); | |
| renderer.domElement.addEventListener('click', onClick); | |
| window.addEventListener('resize', resize); | |
| resize(); | |
| const clock = new THREE.Clock(); | |
| function animate() { | |
| const elapsed = clock.getElapsedTime(); | |
| requestAnimationFrame(animate); | |
| const mood = getPhaseMood(activeEventRef.current?.phase); | |
| scene.background.lerp(new THREE.Color(mood.fog), 0.06); | |
| scene.fog.color.lerp(new THREE.Color(mood.fog), 0.06); | |
| keyLight.color.lerp(new THREE.Color(mood.keyLight), 0.08); | |
| rimLight.color.lerp(new THREE.Color(mood.rimLight), 0.08); | |
| floorLight.color.lerp(new THREE.Color(mood.floorLight), 0.08); | |
| keyLight.intensity += (17.5 - keyLight.intensity + Math.sin(elapsed * 1.4) * 1.4) * 0.05; | |
| rimLight.intensity += (9.5 - rimLight.intensity + Math.sin(elapsed * 1.7 + 1.2) * 1.1) * 0.05; | |
| floorLight.intensity += (7.2 - floorLight.intensity + Math.sin(elapsed * 1.9 + 2.4) * 0.9) * 0.05; | |
| particleMaterial.color.lerp(new THREE.Color(mood.particle), 0.08); | |
| particleMaterial.opacity += ((activeEventRef.current ? 0.72 : 0.5) - particleMaterial.opacity) * 0.04; | |
| brainGroup.rotation.y = Math.sin(elapsed * 0.12) * 0.08 - 0.35; | |
| brainGroup.rotation.x = Math.sin(elapsed * 0.08) * 0.03; | |
| particles.rotation.y = elapsed * 0.012; | |
| raycaster.setFromCamera(pointer, camera); | |
| const regionList = [...regionMeshes.values()]; | |
| const intersections = raycaster.intersectObjects(regionList, false); | |
| const hoveredId = intersections[0]?.object?.userData?.regionId || null; | |
| if (hoveredId !== hoveredIdRef.current) { | |
| hoveredIdRef.current = hoveredId; | |
| setHoveredRegionId(hoveredId); | |
| } | |
| const currentEvent = activeEventRef.current; | |
| if (currentEvent?.region !== animate.lastRegion || currentEvent?.timestamp !== animate.lastTimestamp) { | |
| animate.lastRegion = currentEvent?.region || null; | |
| animate.lastTimestamp = currentEvent?.timestamp || null; | |
| rebuildConnectors(currentEvent); | |
| } | |
| connectorsRef.current.forEach((connector, connectorIndex) => { | |
| connector.tube.material.opacity = currentEvent ? 0.44 + Math.sin(elapsed * 2.4 + connectorIndex) * 0.12 : 0.28; | |
| connector.pulses.forEach((pulse, pulseIndex) => { | |
| const travel = (elapsed * pulse.userData.speed + pulse.userData.offset) % 1; | |
| const position = connector.curve.getPointAt(travel); | |
| pulse.position.copy(position); | |
| const scale = 1 + Math.sin(elapsed * 7 + pulseIndex + connectorIndex) * 0.22; | |
| pulse.scale.setScalar(scale); | |
| pulse.material.opacity = 0.68 + Math.sin(elapsed * 6 + pulseIndex) * 0.16; | |
| }); | |
| }); | |
| regionMeshes.forEach((mesh, regionId) => { | |
| const activation = currentEvent?.region === regionId ? (currentEvent.activation || 0) / 100 : 0; | |
| const isNext = currentEvent?.next_regions?.includes(regionId); | |
| const isSelected = selectedIdRef.current === regionId; | |
| const isHovered = hoveredIdRef.current === regionId; | |
| const transferPulse = isNext ? 0.12 + Math.max(0, Math.sin(elapsed * 5.2 + mesh.position.x)) * 0.22 : 0; | |
| const intensity = 0.18 + activation * 1.3 + transferPulse + (isSelected ? 0.22 : 0) + (isHovered ? 0.12 : 0); | |
| const pulse = 1 + Math.sin(elapsed * 3.2 + mesh.position.x) * 0.03 * Math.max(activation, isSelected ? 0.6 : 0.25); | |
| const [baseX, baseY, baseZ] = mesh.userData.baseScale; | |
| mesh.scale.set(baseX * pulse, baseY * pulse, baseZ * pulse); | |
| mesh.material.emissiveIntensity = intensity; | |
| mesh.material.opacity = 0.68 + activation * 0.26 + (isSelected ? 0.05 : 0); | |
| mesh.material.color.set(isSelected ? '#ffffff' : mesh.userData.baseColor); | |
| mesh.rotation.y = Math.sin(elapsed * 0.7 + mesh.position.x) * 0.1; | |
| }); | |
| REGIONS.forEach((region) => { | |
| const labelEl = labelRefs.current.get(region.id); | |
| const mesh = regionMeshes.get(region.id); | |
| if (!labelEl || !mesh) return; | |
| const anchor = mesh.position.clone().add(new THREE.Vector3(0, mesh.userData.baseScale[1] + 0.28, 0)); | |
| anchor.project(camera); | |
| const x = (anchor.x * 0.5 + 0.5) * mount.clientWidth; | |
| const y = (-anchor.y * 0.5 + 0.5) * mount.clientHeight; | |
| const isVisible = anchor.z < 1; | |
| const isActive = currentEvent?.region === region.id; | |
| const isSelected = selectedIdRef.current === region.id; | |
| const isHovered = hoveredIdRef.current === region.id; | |
| const isNext = currentEvent?.next_regions?.includes(region.id); | |
| const opacity = isVisible ? (isActive || isSelected || isHovered || isNext ? 1 : 0.55) : 0; | |
| const scale = isActive || isSelected ? 1 : 0.94; | |
| labelEl.style.transform = `translate(${x}px, ${y}px) translate(-50%, -50%) scale(${scale})`; | |
| labelEl.style.opacity = `${opacity}`; | |
| labelEl.dataset.flow = isNext ? 'next' : isActive ? 'active' : isSelected ? 'selected' : ''; | |
| }); | |
| renderer.render(scene, camera); | |
| } | |
| animate.lastRegion = null; | |
| animate.lastTimestamp = null; | |
| animate(); | |
| return () => { | |
| renderer.domElement.removeEventListener('pointermove', onPointerMove); | |
| renderer.domElement.removeEventListener('pointerleave', onPointerLeave); | |
| renderer.domElement.removeEventListener('click', onClick); | |
| window.removeEventListener('resize', resize); | |
| clearConnectors(); | |
| particlesGeometry.dispose(); | |
| particleMaterial.dispose(); | |
| renderer.dispose(); | |
| mount.removeChild(renderer.domElement); | |
| }; | |
| }, []); | |
| return ( | |
| <div | |
| className="cbs-shell" | |
| data-phase={activeEvent?.phase || DEFAULT_PHASE} | |
| style={{ | |
| '--cbs-accent': currentMood.accent, | |
| '--cbs-glow': currentMood.glow, | |
| '--cbs-glow-secondary': currentMood.glowSecondary, | |
| '--cbs-glow-tertiary': currentMood.glowTertiary, | |
| '--cbs-bg-start': currentMood.backgroundStart, | |
| '--cbs-bg-mid': currentMood.backgroundMid, | |
| '--cbs-bg-end': currentMood.backgroundEnd, | |
| }} | |
| > | |
| <div className="cbs-canvas" ref={mountRef} /> | |
| <div className="cbs-label-layer"> | |
| {REGIONS.map((region) => { | |
| const isActive = activeEvent?.region === region.id; | |
| const isSelected = selectedRegion.id === region.id; | |
| return ( | |
| <button | |
| key={region.id} | |
| ref={(node) => { | |
| if (node) labelRefs.current.set(region.id, node); | |
| else labelRefs.current.delete(region.id); | |
| }} | |
| type="button" | |
| className={`cbs-floating-label ${isActive ? 'active' : ''} ${isSelected ? 'selected' : ''}`} | |
| onClick={() => setSelectedRegionId(region.id)} | |
| > | |
| <span className="cbs-floating-dot" style={{ background: region.color }} /> | |
| <span>{region.label}</span> | |
| </button> | |
| ); | |
| })} | |
| </div> | |
| <div className="cbs-hud"> | |
| <section className="cbs-card cbs-card-main"> | |
| <span className="t-label">Realtime Brain Trace</span> | |
| <h3>{activeEvent?.phase ? activeEvent.phase.replace(/_/g, ' ') : 'Idle State'}</h3> | |
| <p className="cbs-region">{activeEvent?.region_label || 'Dormant network'}</p> | |
| <p className="cbs-reason"> | |
| {activeEvent?.reason || 'Soma is waiting for the next cognitive trigger.'} | |
| </p> | |
| <div className="cbs-chip-row"> | |
| <div className="cbs-chip"> | |
| <span className="t-label">Activation</span> | |
| <strong>{activeEvent?.activation ?? 0}%</strong> | |
| </div> | |
| <div className="cbs-chip"> | |
| <span className="t-label">Events</span> | |
| <strong>{brainEvents.length}</strong> | |
| </div> | |
| <div className="cbs-chip"> | |
| <span className="t-label">Next</span> | |
| <strong>{activeEvent?.next_regions?.length || 0}</strong> | |
| </div> | |
| </div> | |
| </section> | |
| {brainState.reflection && ( | |
| <section className="cbs-card cbs-card-reflection"> | |
| <span className="t-label">Internal Reflection</span> | |
| <p>{brainState.reflection}</p> | |
| </section> | |
| )} | |
| <section className="cbs-card cbs-card-detail"> | |
| <div className="cbs-detail-head"> | |
| <div> | |
| <span className="t-label">Region Detail</span> | |
| <h4>{selectedRegion.label}</h4> | |
| </div> | |
| <div className="cbs-detail-badge"> | |
| <span className="t-label">Signal</span> | |
| <strong>{selectedEvent?.activation ?? 0}%</strong> | |
| </div> | |
| </div> | |
| <p className="cbs-detail-copy">{selectedRegion.description}</p> | |
| <div className="cbs-detail-grid"> | |
| <div> | |
| <span className="t-label">Last Phase</span> | |
| <strong>{formatPhaseLabel(selectedEvent?.phase)}</strong> | |
| </div> | |
| <div> | |
| <span className="t-label">Timestamp</span> | |
| <strong>{formatTimestamp(selectedEvent?.timestamp)}</strong> | |
| </div> | |
| <div> | |
| <span className="t-label">Inputs Used</span> | |
| <strong>{selectedInputs.length || 0}</strong> | |
| </div> | |
| <div> | |
| <span className="t-label">Next Regions</span> | |
| <strong>{selectedTargets.length || 0}</strong> | |
| </div> | |
| </div> | |
| <p className="cbs-detail-reason"> | |
| {selectedEvent?.reason || 'This region has not fired in the current cycle yet.'} | |
| </p> | |
| <div className="cbs-drawer-grid"> | |
| <div className="cbs-drawer-block"> | |
| <span className="t-label">Signal Destinations</span> | |
| {selectedTargets.length > 0 ? ( | |
| <div className="cbs-mini-list"> | |
| {selectedTargets.map((target) => ( | |
| <span key={target} className="cbs-mini-pill">{target}</span> | |
| ))} | |
| </div> | |
| ) : ( | |
| <p className="cbs-drawer-empty">No downstream regions for this event.</p> | |
| )} | |
| </div> | |
| <div className="cbs-drawer-block"> | |
| <span className="t-label">Inputs Used</span> | |
| {selectedInputs.length > 0 ? ( | |
| <div className="cbs-mini-list"> | |
| {selectedInputs.map((input) => ( | |
| <span key={input} className="cbs-mini-pill">{input.replace(/_/g, ' ')}</span> | |
| ))} | |
| </div> | |
| ) : ( | |
| <p className="cbs-drawer-empty">No explicit input metadata recorded.</p> | |
| )} | |
| </div> | |
| </div> | |
| <div className="cbs-drawer-block"> | |
| <span className="t-label">Trace Payload</span> | |
| {selectedDataEntries.length > 0 ? ( | |
| <div className="cbs-payload-list"> | |
| {selectedDataEntries.map(([key, value]) => ( | |
| <div key={key} className="cbs-payload-row"> | |
| <span className="cbs-payload-key">{key.replace(/_/g, ' ')}</span> | |
| <span className="cbs-payload-value"> | |
| {typeof value === 'string' | |
| ? value | |
| : Array.isArray(value) | |
| ? `${value.length} item${value.length === 1 ? '' : 's'}` | |
| : typeof value === 'object' && value !== null | |
| ? `${Object.keys(value).length} fields` | |
| : String(value)} | |
| </span> | |
| </div> | |
| ))} | |
| </div> | |
| ) : ( | |
| <p className="cbs-drawer-empty">No structured payload for this region event.</p> | |
| )} | |
| </div> | |
| </section> | |
| <section className="cbs-card cbs-card-regions"> | |
| <span className="t-label">Region Map</span> | |
| <div className="cbs-region-grid"> | |
| {REGIONS.map((region) => { | |
| const isActive = activeEvent?.region === region.id; | |
| const isSelected = selectedRegion.id === region.id; | |
| const isHovered = hoveredRegionId === region.id; | |
| return ( | |
| <button | |
| key={region.id} | |
| className={`cbs-region-pill ${isActive ? 'active' : ''} ${isSelected ? 'selected' : ''} ${isHovered ? 'hovered' : ''}`} | |
| onClick={() => setSelectedRegionId(region.id)} | |
| type="button" | |
| > | |
| <span className="cbs-region-dot" style={{ background: region.color }} /> | |
| <span>{region.shortLabel}</span> | |
| </button> | |
| ); | |
| })} | |
| </div> | |
| </section> | |
| <section className="cbs-card cbs-card-timeline"> | |
| <span className="t-label">Cognitive Timeline</span> | |
| <div className="cbs-timeline"> | |
| {timeline.length === 0 ? ( | |
| <p className="cbs-empty">Send a message to watch the brain perform cognition step by step.</p> | |
| ) : ( | |
| timeline.map((event, index) => ( | |
| <button | |
| key={`${event.timestamp}-${index}`} | |
| type="button" | |
| className={`cbs-timeline-item ${selectedRegion.id === event.region ? 'selected' : ''}`} | |
| onClick={() => setSelectedRegionId(event.region)} | |
| > | |
| <div className="cbs-timeline-top"> | |
| <span className="cbs-timeline-phase">{event.phase.replace(/_/g, ' ')}</span> | |
| <span className="cbs-timeline-activation">{event.activation}%</span> | |
| </div> | |
| <div className="cbs-timeline-region">{event.region_label}</div> | |
| <div className="cbs-timeline-reason">{event.reason}</div> | |
| </button> | |
| )) | |
| )} | |
| </div> | |
| </section> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| export default CognitiveBrainScene; | |