import { SpotLight, Vector3, type Object3D } from 'three'; import { FLASHLIGHT } from '../constants/flashlight.ts'; /** Convert nominal lumens into candela over the beam cone. Distance is a render cutoff. */ export function createFlashlight(player: Object3D) { const grip = player.getObjectByName('HeldFlashlight')!; const light = new SpotLight(FLASHLIGHT.color, 0, FLASHLIGHT.distance, FLASHLIGHT.halfAngle, FLASHLIGHT.penumbra, 2); const solidAngle = 2 * Math.PI * (1 - Math.cos(FLASHLIGHT.halfAngle)); light.intensity = FLASHLIGHT.lumens / solidAngle; light.visible = false; const tip = new Vector3(), aim = new Vector3(); return { light, update(on: boolean) { light.visible = on; if (!on) return; grip.updateWorldMatrix(true, false); light.position.copy(tip.set(0, -.27, 0).applyMatrix4(grip.matrixWorld)); light.target.position.copy(aim.set(0, -1.27, 0).applyMatrix4(grip.matrixWorld)); }, dispose() { light.removeFromParent(); light.target.removeFromParent(); light.dispose(); }, }; }