import React, { useMemo, useRef } from 'react'; import { useFrame } from '@react-three/fiber'; import { SceneData, SceneEdge } from './Generator'; import * as THREE from 'three'; import { Line } from '@react-three/drei'; // A single CatmullRomCurve3 cable with particles moving along it const Cable: React.FC<{ edge: SceneEdge }> = ({ edge }) => { const points = useMemo(() => edge.path.map(p => new THREE.Vector3(p[0], p[1], p[2])), [edge.path]); const curve = useMemo(() => new THREE.CatmullRomCurve3(points), [points]); // We extract the line points for rendering the static line const linePoints = useMemo(() => curve.getPoints(20), [curve]); const linePositions = useMemo(() => linePoints.flatMap(p => [p.x, p.y, p.z]), [linePoints]); const particleRef = useRef(null!); const timeRef = useRef(Math.random()); // Random offset for particles useFrame((state, delta) => { if (!particleRef.current) return; // Move particle along the curve. Speed based on edge type. const speed = edge.type === 'transmission' ? 0.3 : 0.15; timeRef.current = (timeRef.current + delta * speed) % 1; const pos = curve.getPointAt(timeRef.current); particleRef.current.position.copy(pos); }); return ( {/* The actual cable. Underground cables can just be transparent or slightly visible */} {edge.type === 'transmission' && ( )} {/* The glowing particle */} ); }; const TransmissionLines: React.FC<{ data: SceneData }> = ({ data }) => { return ( {data.edges.map(edge => ( ))} ); }; export default TransmissionLines;