UNPKG

@babylonjs/loaders

Version:

The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.

217 lines 11.1 kB
import { Vector3 } from "@babylonjs/core/Maths/math"; import { Tools } from "@babylonjs/core/Misc/tools"; import { AnimationEvent } from "@babylonjs/core/Animations/animationEvent"; import { Sound } from "@babylonjs/core/Audio/sound"; import { WeightedSound } from "@babylonjs/core/Audio/weightedsound"; import { GLTFLoader, ArrayItem } from "../glTFLoader"; var NAME = "MSFT_audio_emitter"; /** * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter) */ var MSFT_audio_emitter = /** @class */ (function () { /** @hidden */ function MSFT_audio_emitter(loader) { /** The name of this extension. */ this.name = NAME; /** Defines whether this extension is enabled. */ this.enabled = true; this._loader = loader; } /** @hidden */ MSFT_audio_emitter.prototype.dispose = function () { delete this._loader; delete this._clips; delete this._emitters; }; /** @hidden */ MSFT_audio_emitter.prototype.onLoading = function () { var extensions = this._loader.gltf.extensions; if (extensions && extensions[this.name]) { var extension = extensions[this.name]; this._clips = extension.clips; this._emitters = extension.emitters; ArrayItem.Assign(this._clips); ArrayItem.Assign(this._emitters); } }; /** @hidden */ MSFT_audio_emitter.prototype.loadSceneAsync = function (context, scene) { var _this = this; return GLTFLoader.LoadExtensionAsync(context, scene, this.name, function (extensionContext, extension) { var promises = new Array(); promises.push(_this._loader.loadSceneAsync(context, scene)); for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) { var emitterIndex = _a[_i]; var emitter = ArrayItem.Get(extensionContext + "/emitters", _this._emitters, emitterIndex); if (emitter.refDistance != undefined || emitter.maxDistance != undefined || emitter.rolloffFactor != undefined || emitter.distanceModel != undefined || emitter.innerAngle != undefined || emitter.outerAngle != undefined) { throw new Error(extensionContext + ": Direction or Distance properties are not allowed on emitters attached to a scene"); } promises.push(_this._loadEmitterAsync(extensionContext + "/emitters/" + emitter.index, emitter)); } return Promise.all(promises).then(function () { }); }); }; /** @hidden */ MSFT_audio_emitter.prototype.loadNodeAsync = function (context, node, assign) { var _this = this; return GLTFLoader.LoadExtensionAsync(context, node, this.name, function (extensionContext, extension) { var promises = new Array(); return _this._loader.loadNodeAsync(extensionContext, node, function (babylonMesh) { var _loop_1 = function (emitterIndex) { var emitter = ArrayItem.Get(extensionContext + "/emitters", _this._emitters, emitterIndex); promises.push(_this._loadEmitterAsync(extensionContext + "/emitters/" + emitter.index, emitter).then(function () { for (var _i = 0, _a = emitter._babylonSounds; _i < _a.length; _i++) { var sound = _a[_i]; sound.attachToMesh(babylonMesh); if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) { sound.setLocalDirectionToMesh(Vector3.Forward()); sound.setDirectionalCone(2 * Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle), 2 * Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle), 0); } } })); }; for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) { var emitterIndex = _a[_i]; _loop_1(emitterIndex); } assign(babylonMesh); }).then(function (babylonMesh) { return Promise.all(promises).then(function () { return babylonMesh; }); }); }); }; /** @hidden */ MSFT_audio_emitter.prototype.loadAnimationAsync = function (context, animation) { var _this = this; return GLTFLoader.LoadExtensionAsync(context, animation, this.name, function (extensionContext, extension) { return _this._loader.loadAnimationAsync(context, animation).then(function (babylonAnimationGroup) { var promises = new Array(); ArrayItem.Assign(extension.events); for (var _i = 0, _a = extension.events; _i < _a.length; _i++) { var event_1 = _a[_i]; promises.push(_this._loadAnimationEventAsync(extensionContext + "/events/" + event_1.index, context, animation, event_1, babylonAnimationGroup)); } return Promise.all(promises).then(function () { return babylonAnimationGroup; }); }); }); }; MSFT_audio_emitter.prototype._loadClipAsync = function (context, clip) { if (clip._objectURL) { return clip._objectURL; } var promise; if (clip.uri) { promise = this._loader.loadUriAsync(context, clip, clip.uri); } else { var bufferView = ArrayItem.Get(context + "/bufferView", this._loader.gltf.bufferViews, clip.bufferView); promise = this._loader.loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView); } clip._objectURL = promise.then(function (data) { return URL.createObjectURL(new Blob([data], { type: clip.mimeType })); }); return clip._objectURL; }; MSFT_audio_emitter.prototype._loadEmitterAsync = function (context, emitter) { var _this = this; emitter._babylonSounds = emitter._babylonSounds || []; if (!emitter._babylonData) { var clipPromises = new Array(); var name_1 = emitter.name || "emitter" + emitter.index; var options_1 = { loop: false, autoplay: false, volume: emitter.volume == undefined ? 1 : emitter.volume, }; var _loop_2 = function (i) { var clipContext = "#/extensions/" + this_1.name + "/clips"; var clip = ArrayItem.Get(clipContext, this_1._clips, emitter.clips[i].clip); clipPromises.push(this_1._loadClipAsync(clipContext + "/" + emitter.clips[i].clip, clip).then(function (objectURL) { var sound = emitter._babylonSounds[i] = new Sound(name_1, objectURL, _this._loader.babylonScene, null, options_1); sound.refDistance = emitter.refDistance || 1; sound.maxDistance = emitter.maxDistance || 256; sound.rolloffFactor = emitter.rolloffFactor || 1; sound.distanceModel = emitter.distanceModel || 'exponential'; sound._positionInEmitterSpace = true; })); }; var this_1 = this; for (var i = 0; i < emitter.clips.length; i++) { _loop_2(i); } var promise = Promise.all(clipPromises).then(function () { var weights = emitter.clips.map(function (clip) { return clip.weight || 1; }); var weightedSound = new WeightedSound(emitter.loop || false, emitter._babylonSounds, weights); if (emitter.innerAngle) { weightedSound.directionalConeInnerAngle = 2 * Tools.ToDegrees(emitter.innerAngle); } if (emitter.outerAngle) { weightedSound.directionalConeOuterAngle = 2 * Tools.ToDegrees(emitter.outerAngle); } if (emitter.volume) { weightedSound.volume = emitter.volume; } emitter._babylonData.sound = weightedSound; }); emitter._babylonData = { loaded: promise }; } return emitter._babylonData.loaded; }; MSFT_audio_emitter.prototype._getEventAction = function (context, sound, action, time, startOffset) { switch (action) { case "play" /* play */: { return function (currentFrame) { var frameOffset = (startOffset || 0) + (currentFrame - time); sound.play(frameOffset); }; } case "stop" /* stop */: { return function (currentFrame) { sound.stop(); }; } case "pause" /* pause */: { return function (currentFrame) { sound.pause(); }; } default: { throw new Error(context + ": Unsupported action " + action); } } }; MSFT_audio_emitter.prototype._loadAnimationEventAsync = function (context, animationContext, animation, event, babylonAnimationGroup) { var _this = this; if (babylonAnimationGroup.targetedAnimations.length == 0) { return Promise.resolve(); } var babylonAnimation = babylonAnimationGroup.targetedAnimations[0]; var emitterIndex = event.emitter; var emitter = ArrayItem.Get("#/extensions/" + this.name + "/emitters", this._emitters, emitterIndex); return this._loadEmitterAsync(context, emitter).then(function () { var sound = emitter._babylonData.sound; if (sound) { var babylonAnimationEvent = new AnimationEvent(event.time, _this._getEventAction(context, sound, event.action, event.time, event.startOffset)); babylonAnimation.animation.addEvent(babylonAnimationEvent); // Make sure all started audio stops when this animation is terminated. babylonAnimationGroup.onAnimationGroupEndObservable.add(function () { sound.stop(); }); babylonAnimationGroup.onAnimationGroupPauseObservable.add(function () { sound.pause(); }); } }); }; return MSFT_audio_emitter; }()); export { MSFT_audio_emitter }; GLTFLoader.RegisterExtension(NAME, function (loader) { return new MSFT_audio_emitter(loader); }); //# sourceMappingURL=MSFT_audio_emitter.js.map