Some checks failed
Deploy Nexus / deploy (push) Failing after 4s
Co-authored-by: Claude (Opus 4.6) <claude@hermes.local> Co-committed-by: Claude (Opus 4.6) <claude@hermes.local>
57 lines
1.6 KiB
JavaScript
57 lines
1.6 KiB
JavaScript
/**
|
|
* energy-beam.js — Vertical energy beam above the Batcave terminal
|
|
*
|
|
* Category: DATA-TETHERED AESTHETIC
|
|
* Data source: state.activeAgentCount (0 = faint, 3+ = full intensity)
|
|
*
|
|
* A glowing cyan cylinder rising from the Batcave area.
|
|
* Intensity and pulse amplitude are driven by the number of active agents.
|
|
*/
|
|
|
|
import * as THREE from 'three';
|
|
|
|
const BEAM_RADIUS = 0.2;
|
|
const BEAM_HEIGHT = 50;
|
|
const BEAM_X = -10;
|
|
const BEAM_Y = 0;
|
|
const BEAM_Z = -10;
|
|
|
|
let _state = null;
|
|
let _beamMaterial = null;
|
|
let _pulse = 0;
|
|
|
|
/**
|
|
* @param {THREE.Scene} scene
|
|
* @param {object} state Shared state bus (reads state.activeAgentCount)
|
|
* @param {object} theme Theme bus (reads theme.colors.accent)
|
|
*/
|
|
export function init(scene, state, theme) {
|
|
_state = state;
|
|
|
|
const accentColor = theme?.colors?.accent ?? 0x4488ff;
|
|
|
|
const geo = new THREE.CylinderGeometry(BEAM_RADIUS, BEAM_RADIUS * 2.5, BEAM_HEIGHT, 32, 16, true);
|
|
_beamMaterial = new THREE.MeshBasicMaterial({
|
|
color: accentColor,
|
|
transparent: true,
|
|
opacity: 0.6,
|
|
blending: THREE.AdditiveBlending,
|
|
side: THREE.DoubleSide,
|
|
depthWrite: false,
|
|
});
|
|
const beam = new THREE.Mesh(geo, _beamMaterial);
|
|
beam.position.set(BEAM_X, BEAM_Y + BEAM_HEIGHT / 2, BEAM_Z);
|
|
scene.add(beam);
|
|
}
|
|
|
|
export function update(_elapsed, _delta) {
|
|
if (!_beamMaterial) return;
|
|
|
|
_pulse += 0.02;
|
|
|
|
const agentCount = _state?.activeAgentCount ?? 0;
|
|
const agentIntensity = agentCount === 0 ? 0.1 : Math.min(0.1 + agentCount * 0.3, 1.0);
|
|
const pulseEffect = Math.sin(_pulse) * 0.15 * agentIntensity;
|
|
_beamMaterial.opacity = agentIntensity * 0.6 + pulseEffect;
|
|
}
|