UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

202 lines (171 loc) 5.27 kB
import store, { createEffect, Reactive } from "@lincode/reactivity" import { AudioListener, PositionalAudio } from "three" import PositionedItem from "../api/core/PositionedItem" import mainCamera from "../engine/mainCamera" import scene from "../engine/scene" import { onSelectionTarget, emitSelectionTarget } from "../events/onSelectionTarget" import IAudio, { audioDefaults, audioSchema } from "../interface/IAudio" import { getCameraRendered } from "../states/useCameraRendered" import makeAudioSprite from "./core/utils/makeAudioSprite" import loadAudio from "./utils/loaders/loadAudio" const [setAudioListener, getAudioListener] = store<AudioListener | undefined>( undefined ) createEffect(() => { const audioListener = getAudioListener() if (!audioListener) return const cam = getCameraRendered() cam.add(audioListener) return () => { cam.remove(audioListener) } }, [getCameraRendered, getAudioListener]) export default class Audio extends PositionedItem<PositionalAudio> implements IAudio { public static componentName = "audio" public static defaults = audioDefaults public static schema = audioSchema public constructor() { !getAudioListener() && setAudioListener(new AudioListener()) const sound = new PositionalAudio(getAudioListener()!) super(sound) scene.add(sound) this.createEffect(() => { if (getCameraRendered() !== mainCamera) return const sprite = makeAudioSprite() this.outerObject3d.add(sprite.outerObject3d) const handle = onSelectionTarget(({ target }) => { target === sprite && emitSelectionTarget(this) }) return () => { sprite.dispose() handle.cancel() } }, [getCameraRendered]) const [setReady, getReady] = store(false) this.createEffect(() => { const src = this.srcState.get() if (!src) return let proceed = true loadAudio(src).then((buffer) => { if (!proceed) return sound.setBuffer(buffer) setReady(true) }) return () => { proceed = false setReady(false) } }, [this.srcState.get]) this.createEffect(() => { if ( !getReady() || !this.autoplayState.get() || this.pausedState.get() || this.stoppedState.get() ) return sound.play() return () => { this.stoppedState.get() ? sound.stop() : sound.pause() } }, [ getReady, this.autoplayState.get, this.pausedState.get, this.stoppedState.get ]) } public override dispose() { if (this.done) return this super.dispose() this.outerObject3d.buffer && this.outerObject3d.disconnect() return this } public play() { this.autoplay = true this.paused = false this.stopped = false } public pause() { this.paused = true } public stop() { this.stopped = true } private srcState = new Reactive<string | undefined>(undefined) public get src() { return this.srcState.get() } public set src(val) { this.srcState.set(val) } private autoplayState = new Reactive(false) public get autoplay() { return this.autoplayState.get() } public set autoplay(val) { this.autoplayState.set(val) } private pausedState = new Reactive(false) public get paused() { return this.pausedState.get() } public set paused(val) { this.pausedState.set(val) } private stoppedState = new Reactive(false) public get stopped() { return this.stoppedState.get() } public set stopped(val) { this.stoppedState.set(val) } public get loop() { return this.outerObject3d.loop } public set loop(val) { this.outerObject3d.loop = val } public get volume() { return this.outerObject3d.getVolume() } public set volume(val) { this.outerObject3d.setVolume(val) } public get playbackRate() { return this.outerObject3d.playbackRate } public set playbackRate(val) { this.outerObject3d.playbackRate = val } public get distance() { return this.outerObject3d.getRefDistance() } public set distance(val) { this.outerObject3d.setRefDistance(val) } public get distanceModel() { return this.outerObject3d.getDistanceModel() } public set distanceModel(val) { this.outerObject3d.setDistanceModel(val) } public get maxDistance() { return this.outerObject3d.getMaxDistance() } public set maxDistance(val) { this.outerObject3d.setMaxDistance(val) } public get rolloffFactor() { return this.outerObject3d.getRolloffFactor() } public set rolloffFactor(val) { this.outerObject3d.setRolloffFactor(val) } }