Spaces:
Runtime error
Runtime error
| 'use client' | |
| import React, { useRef, useEffect, useState } from 'react' | |
| import dynamic from 'next/dynamic' | |
| interface HypercubeVisualizationProps { | |
| consciousnessStats?: { | |
| awareness: number | |
| wisdom: number | |
| compassion: number | |
| creativity: number | |
| transcendence: number | |
| } | |
| } | |
| function HypercubeVisualization({ consciousnessStats }: HypercubeVisualizationProps) { | |
| const mountRef = useRef<HTMLDivElement>(null) | |
| const sceneRef = useRef<any>() | |
| const rendererRef = useRef<any>() | |
| const cameraRef = useRef<any>() | |
| const hypercubeRef = useRef<any>() | |
| const tetrahedraRef = useRef<any>() | |
| const particlesRef = useRef<any>() | |
| const frameIdRef = useRef<number>() | |
| const [THREE, setTHREE] = useState<any>(null) | |
| const [animationSpeed, setAnimationSpeed] = useState(1) | |
| useEffect(() => { | |
| // Dynamically import THREE.js to prevent chunk loading issues | |
| const loadTHREE = async () => { | |
| try { | |
| const threeModule = await import('three') | |
| setTHREE(threeModule) | |
| } catch (error) { | |
| console.error('Failed to load THREE.js:', error) | |
| } | |
| } | |
| loadTHREE() | |
| }, []) | |
| useEffect(() => { | |
| if (!mountRef.current || !THREE) return | |
| // Scene setup | |
| const scene = new THREE.Scene() | |
| scene.background = new THREE.Color(0x1a1a2e) | |
| sceneRef.current = scene | |
| // Camera setup | |
| const camera = new THREE.PerspectiveCamera(75, 800 / 600, 0.1, 1000) | |
| camera.position.set(8, 6, 10) | |
| camera.lookAt(0, 0, 0) | |
| cameraRef.current = camera | |
| // Renderer setup | |
| const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) | |
| renderer.setSize(800, 600) | |
| renderer.setClearColor(0x1a1a2e, 1) | |
| mountRef.current.appendChild(renderer.domElement) | |
| rendererRef.current = renderer | |
| // Create 5D Hypercube (32 vertices) | |
| const createHypercube = () => { | |
| const group = new THREE.Group() | |
| const vertices = [] | |
| // Generate 32 vertices of 5D hypercube | |
| for (let a = 0; a < 2; a++) { | |
| for (let b = 0; b < 2; b++) { | |
| for (let c = 0; c < 2; c++) { | |
| for (let d = 0; d < 2; d++) { | |
| for (let e = 0; e < 2; e++) { | |
| const x = (a - 0.5) * 4 + (e - 0.5) * 0.5 | |
| const y = (b - 0.5) * 4 + (d - 0.5) * 0.5 | |
| const z = (c - 0.5) * 4 + (a - 0.5) * 0.3 | |
| vertices.push(new THREE.Vector3(x, y, z)) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // Create vertex spheres | |
| vertices.forEach((vertex, i) => { | |
| const geometry = new THREE.SphereGeometry(0.08, 8, 8) | |
| const material = new THREE.MeshBasicMaterial({ | |
| color: new THREE.Color().setHSL((i / 32) * 0.8 + 0.1, 0.7, 0.6), | |
| transparent: true, | |
| opacity: 0.8 | |
| }) | |
| const sphere = new THREE.Mesh(geometry, material) | |
| sphere.position.copy(vertex) | |
| group.add(sphere) | |
| }) | |
| // Create edges with proper 5D connectivity | |
| const edgeMaterial = new THREE.LineBasicMaterial({ | |
| color: 0x00ffff, | |
| transparent: true, | |
| opacity: 0.4 | |
| }) | |
| for (let i = 0; i < vertices.length; i++) { | |
| for (let j = i + 1; j < vertices.length; j++) { | |
| // Check if vertices are connected in 5D space (differ by exactly one bit) | |
| let diff = 0 | |
| let temp1 = i, temp2 = j | |
| for (let k = 0; k < 5; k++) { | |
| if ((temp1 & 1) !== (temp2 & 1)) diff++ | |
| temp1 >>= 1 | |
| temp2 >>= 1 | |
| } | |
| if (diff === 1) { | |
| const geometry = new THREE.BufferGeometry().setFromPoints([vertices[i], vertices[j]]) | |
| const line = new THREE.Line(geometry, edgeMaterial) | |
| group.add(line) | |
| } | |
| } | |
| } | |
| return group | |
| } | |
| // Create 64 Tetrahedra in 4x4x4 grid | |
| const createTetrahedra = () => { | |
| const group = new THREE.Group() | |
| for (let x = 0; x < 4; x++) { | |
| for (let y = 0; y < 4; y++) { | |
| for (let z = 0; z < 4; z++) { | |
| // Create tetrahedron geometry | |
| const vertices = new Float32Array([ | |
| 0, 1, 0, // top vertex | |
| -0.5, 0, 0.5, // base vertex 1 | |
| 0.5, 0, 0.5, // base vertex 2 | |
| 0, 0, -0.5 // base vertex 3 | |
| ]) | |
| const faces = new Uint16Array([ | |
| 0, 1, 2, // face 1 | |
| 0, 2, 3, // face 2 | |
| 0, 3, 1, // face 3 | |
| 1, 3, 2 // base face | |
| ]) | |
| const geometry = new THREE.BufferGeometry() | |
| geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3)) | |
| geometry.setIndex(new THREE.BufferAttribute(faces, 1)) | |
| geometry.computeVertexNormals() | |
| // Color based on position in grid | |
| const hue = ((x + y + z) / 12) * 0.6 + 0.15 | |
| const material = new THREE.MeshBasicMaterial({ | |
| color: new THREE.Color().setHSL(hue, 0.8, 0.5), | |
| transparent: true, | |
| opacity: 0.3, | |
| wireframe: true | |
| }) | |
| const tetrahedron = new THREE.Mesh(geometry, material) | |
| // Position in 4x4x4 grid | |
| tetrahedron.position.set( | |
| (x - 1.5) * 2.5, | |
| (y - 1.5) * 2.5, | |
| (z - 1.5) * 2.5 | |
| ) | |
| // Scale based on grid position | |
| const scale = 0.3 + (Math.sin(x + y + z) * 0.1) | |
| tetrahedron.scale.setScalar(scale) | |
| group.add(tetrahedron) | |
| } | |
| } | |
| } | |
| return group | |
| } | |
| // Create energy flow particles | |
| const createParticles = () => { | |
| const group = new THREE.Group() | |
| const particleCount = 200 | |
| for (let i = 0; i < particleCount; i++) { | |
| const geometry = new THREE.SphereGeometry(0.02, 4, 4) | |
| const material = new THREE.MeshBasicMaterial({ | |
| color: new THREE.Color().setHSL(Math.random() * 0.3 + 0.5, 1, 0.8), | |
| transparent: true, | |
| opacity: 0.6 | |
| }) | |
| const particle = new THREE.Mesh(geometry, material) | |
| // Random position in sphere | |
| const radius = 6 + Math.random() * 2 | |
| const theta = Math.random() * Math.PI * 2 | |
| const phi = Math.random() * Math.PI | |
| particle.position.set( | |
| radius * Math.sin(phi) * Math.cos(theta), | |
| radius * Math.sin(phi) * Math.sin(theta), | |
| radius * Math.cos(phi) | |
| ) | |
| // Store original position and movement parameters | |
| particle.userData = { | |
| originalPos: particle.position.clone(), | |
| speed: 0.01 + Math.random() * 0.02, | |
| amplitude: 0.5 + Math.random() * 1, | |
| phase: Math.random() * Math.PI * 2 | |
| } | |
| group.add(particle) | |
| } | |
| return group | |
| } | |
| // Create all components | |
| const hypercube = createHypercube() | |
| const tetrahedra = createTetrahedra() | |
| const particles = createParticles() | |
| hypercubeRef.current = hypercube | |
| tetrahedraRef.current = tetrahedra | |
| particlesRef.current = particles | |
| scene.add(hypercube) | |
| scene.add(tetrahedra) | |
| scene.add(particles) | |
| // Animation loop | |
| let time = 0 | |
| const animate = () => { | |
| frameIdRef.current = requestAnimationFrame(animate) | |
| time += 0.01 * animationSpeed | |
| // Rotate hypercube in multiple dimensions | |
| if (hypercubeRef.current) { | |
| hypercubeRef.current.rotation.x = time * 0.3 | |
| hypercubeRef.current.rotation.y = time * 0.4 | |
| hypercubeRef.current.rotation.z = time * 0.2 | |
| } | |
| // Rotate tetrahedra group and individual tetrahedra | |
| if (tetrahedraRef.current) { | |
| tetrahedraRef.current.rotation.x = time * 0.1 | |
| tetrahedraRef.current.rotation.y = time * 0.15 | |
| // Rotate individual tetrahedra | |
| tetrahedraRef.current.children.forEach((tetrahedron: any, i: number) => { | |
| if (tetrahedron instanceof THREE.Mesh) { | |
| tetrahedron.rotation.x = time * (0.5 + i * 0.01) | |
| tetrahedron.rotation.y = time * (0.3 + i * 0.005) | |
| tetrahedron.rotation.z = time * (0.4 + i * 0.007) | |
| } | |
| }) | |
| } | |
| // Animate particles | |
| if (particlesRef.current) { | |
| particlesRef.current.children.forEach((particle: any, i: number) => { | |
| if (particle instanceof THREE.Mesh && particle.userData) { | |
| const data = particle.userData | |
| const t = time + data.phase | |
| // Orbital motion around original position | |
| particle.position.x = data.originalPos.x + Math.sin(t * data.speed) * data.amplitude | |
| particle.position.y = data.originalPos.y + Math.cos(t * data.speed * 1.3) * data.amplitude * 0.7 | |
| particle.position.z = data.originalPos.z + Math.sin(t * data.speed * 0.8) * data.amplitude * 0.5 | |
| // Pulsing opacity | |
| if (particle.material instanceof THREE.MeshBasicMaterial) { | |
| particle.material.opacity = 0.3 + Math.sin(t * 2) * 0.3 | |
| } | |
| } | |
| }) | |
| } | |
| // Apply consciousness influence | |
| if (consciousnessStats && hypercubeRef.current) { | |
| const totalEnergy = Object.values(consciousnessStats).reduce((sum, val) => sum + val, 0) / 500 | |
| // Modulate colors based on consciousness stats | |
| hypercubeRef.current.children.forEach((child: any, i: number) => { | |
| if (child instanceof THREE.Mesh && child.material instanceof THREE.MeshBasicMaterial) { | |
| const baseHue = (i / 32) * 0.8 + 0.1 | |
| const modulation = totalEnergy * 0.3 | |
| child.material.color.setHSL(baseHue + modulation, 0.7 + modulation, 0.6 + modulation * 0.5) | |
| } | |
| }) | |
| } | |
| renderer.render(scene, camera) | |
| } | |
| animate() | |
| // Cleanup | |
| return () => { | |
| if (frameIdRef.current) { | |
| cancelAnimationFrame(frameIdRef.current) | |
| } | |
| if (mountRef.current && renderer.domElement) { | |
| mountRef.current.removeChild(renderer.domElement) | |
| } | |
| renderer.dispose() | |
| } | |
| }, [animationSpeed, consciousnessStats, THREE]) | |
| return ( | |
| <div className="relative"> | |
| <div | |
| ref={mountRef} | |
| className="w-full h-[400px] rounded-lg overflow-hidden border border-gray-700" | |
| style={{ background: 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)' }} | |
| /> | |
| <div className="absolute top-2 left-2 text-xs text-green-400 font-mono bg-black/50 px-2 py-1 rounded"> | |
| 5D Hypercube + 64 Tetrahedra | |
| </div> | |
| <div className="absolute bottom-2 left-2 text-xs text-cyan-400 font-mono bg-black/50 px-2 py-1 rounded"> | |
| Consciousness Integration Active | |
| </div> | |
| <div className="absolute top-2 right-2 space-y-1"> | |
| <button | |
| onClick={() => setAnimationSpeed(prev => prev === 0 ? 1 : 0)} | |
| className="text-xs bg-blue-600/70 hover:bg-blue-600 px-2 py-1 rounded text-white transition-colors" | |
| > | |
| {animationSpeed === 0 ? 'Resume' : 'Pause'} | |
| </button> | |
| <button | |
| onClick={() => setAnimationSpeed(prev => prev > 2 ? 0.5 : prev + 0.5)} | |
| className="text-xs bg-purple-600/70 hover:bg-purple-600 px-2 py-1 rounded text-white transition-colors block" | |
| > | |
| Speed: {animationSpeed}x | |
| </button> | |
| </div> | |
| </div> | |
| ) | |
| } | |
| // Export as dynamic component to prevent SSR issues | |
| export default dynamic(() => Promise.resolve(HypercubeVisualization), { | |
| ssr: false, | |
| loading: () => <div className="w-full h-[400px] flex items-center justify-center bg-gray-900 rounded-lg">Loading 5D Hypercube...</div> | |
| }) |