UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in

82 lines (70 loc) 2.58 kB
import { AudioListener as ThreeAudioListener } from "three"; import { Application } from "../engine/engine_application.js"; import { Camera } from "./Camera.js"; import { Behaviour, GameObject } from "./Component.js"; /** * AudioListener represents a listener that can be attached to a GameObject to listen to audio sources in the scene. * @category Multimedia * @group Components */ export class AudioListener extends Behaviour { /** * Gets the existing or creates a new {@link ThreeAudioListener} instance * @returns The {@link ThreeAudioListener} instance */ get listener(): ThreeAudioListener { if (this._listener == null) this._listener = new ThreeAudioListener(); return this._listener; } private _listener: ThreeAudioListener | null = null; /** @internal */ onEnable(): void { Application.registerWaitForInteraction(this.onInteraction); this.addListenerIfItExists(); } /** @internal */ onDisable(): void { Application.unregisterWaitForInteraction(this.onInteraction); this.removeListenerIfItExists(); } private onInteraction = () => { if (this.destroyed) return; const listener = this.listener; if (listener == null) return; this.addListenerIfItExists(); } private addListenerIfItExists() { const listener = this._listener; if (!listener) return; // if the listener is already parented to some object dont change it if (listener?.parent) return; const cam = this.context.mainCameraComponent || GameObject.getComponentInParent(this.gameObject, Camera); if (cam?.threeCamera) { cam.threeCamera.add(listener); } else { this.gameObject.add(listener); } // connect the listeners audio nodes if (!listener.filter) { listener.gain.connect(listener.context.destination); } else { listener.gain.connect(listener.filter); listener.filter.connect(listener.context.destination); } } private removeListenerIfItExists() { const listener = this._listener; if (!listener) return; listener.removeFromParent(); // disconnect the listeners audio nodes if (listener.filter) { listener.filter.disconnect(); } if (listener.gain) { listener.gain.disconnect(); } } }