'use client' import { type SpawnNode, useLiveTransforms, useRegistry } from '@pascal-app/core' import { useNodeEvents, useViewer } from '@pascal-app/viewer' import { useMemo, useRef } from 'react' import { Color, type Group, Shape } from 'three' const SPAWN_COLOR = new Color('#22c55e') /** * Registry-driven spawn renderer. Behaviorally identical to the legacy * `@pascal-app/viewer/components/renderers/spawn/spawn-renderer.tsx` — same * geometry, same colors, same event surface. When the spawn definition lands * in `builtinPlugin.nodes`, the Phase 0 dispatch shims switch the renderer * here and the legacy one is short-circuited. * * Lives in `@pascal-app/nodes` (not viewer) so the kind owns its own render * code. Phase 5's batch migration applies the same pattern to every node. */ const SpawnRenderer = ({ node }: { node: SpawnNode }) => { const ref = useRef(null!) const handlers = useNodeEvents(node, 'spawn') const liveTransform = useLiveTransforms((state) => state.get(node.id)) const walkthroughMode = useViewer((state) => state.walkthroughMode) useRegistry(node.id, 'spawn', ref) const materialProps = useMemo( () => ({ color: SPAWN_COLOR, emissive: SPAWN_COLOR, emissiveIntensity: 0.08, metalness: 0.03, roughness: 0.42, }), [], ) const arrowShape = useMemo(() => { const shape = new Shape() shape.moveTo(0, 0.24) shape.lineTo(-0.18, -0.14) shape.lineTo(0.18, -0.14) shape.closePath() return shape }, []) return ( ) } export default SpawnRenderer