Michael Herzog 10 месяцев назад
Родитель
Сommit
1e395f5c11

+ 339 - 0
src/audio/Audio.js

@@ -1,48 +1,239 @@
 import { Object3D } from '../core/Object3D.js';
 
+/**
+ * Represents a non-positional ( global ) audio object.
+ *
+ * This and related audio module make use of the [Web Audio API]{@link https://www.w3.org/TR/webaudio-1.1/}.
+ *
+ * ```js
+ * // create an AudioListener and add it to the camera
+ * const listener = new THREE.AudioListener();
+ * camera.add( listener );
+ *
+ * // create a global audio source
+ * const sound = new THREE.Audio( listener );
+ *
+ * // load a sound and set it as the Audio object's buffer
+ * const audioLoader = new THREE.AudioLoader();
+ * audioLoader.load( 'sounds/ambient.ogg', function( buffer ) {
+ * 	sound.setBuffer( buffer );
+ * 	sound.setLoop( true );
+ * 	sound.setVolume( 0.5 );
+ * 	sound.play();
+ * });
+ * ```
+ *
+ * @augments Object3D
+ */
 class Audio extends Object3D {
 
+	/**
+	 * Constructs a new audio.
+	 *
+	 * @param {AudioListener} listener - The global audio listener.
+	 */
 	constructor( listener ) {
 
 		super();
 
 		this.type = 'Audio';
 
+		/**
+		 * The global audio listener.
+		 *
+		 * @type {AudioListener}
+		 * @readonly
+		 */
 		this.listener = listener;
+
+		/**
+		 * The audio context.
+		 *
+		 * @type {AudioContext}
+		 * @readonly
+		 */
 		this.context = listener.context;
 
+		/**
+		 * The gain node used for volume control.
+		 *
+		 * @type {GainNode}
+		 * @readonly
+		 */
 		this.gain = this.context.createGain();
 		this.gain.connect( listener.getInput() );
 
+		/**
+		 * Whether to start playback automatically or not.
+		 *
+		 * @type {boolean}
+		 * @default false
+		 */
 		this.autoplay = false;
 
+		/**
+		 * A reference to an audio buffer.
+		 *
+		 * Defined via {@link Audio#setBuffer}.
+		 *
+		 * @type {?AudioBuffer}
+		 * @default null
+		 * @readonly
+		 */
 		this.buffer = null;
+
+		/**
+		 * Modify pitch, measured in cents. +/- 100 is a semitone.
+		 * +/- 1200 is an octave.
+		 *
+		 * Defined via {@link Audio#setDetune}.
+		 *
+		 * @type {number}
+		 * @default 0
+		 * @readonly
+		 */
 		this.detune = 0;
+
+		/**
+		 * Whether the audio should loop or not.
+		 *
+		 * Defined via {@link Audio#setLoop}.
+		 *
+		 * @type {boolean}
+		 * @default false
+		 * @readonly
+		 */
 		this.loop = false;
+
+		/**
+		 * Defines where in the audio buffer the replay should
+		 * start, in seconds.
+		 *
+		 * @type {number}
+		 * @default 0
+		 */
 		this.loopStart = 0;
+
+		/**
+		 * Defines where in the audio buffer the replay should
+		 * stop, in seconds.
+		 *
+		 * @type {number}
+		 * @default 0
+		 */
 		this.loopEnd = 0;
+
+		/**
+		 * An offset to the time within the audio buffer the playback
+		 * should begin, in seconds.
+		 *
+		 * @type {number}
+		 * @default 0
+		 */
 		this.offset = 0;
+
+		/**
+		 * Overrides the default duration of the audio.
+		 *
+		 * @type {undefined|number}
+		 * @default undefined
+		 */
 		this.duration = undefined;
+
+		/**
+		 * The playback speed.
+		 *
+		 * Defined via {@link Audio#setPlaybackRate}.
+		 *
+		 * @type {number}
+		 * @readonly
+		 * @default 1
+		 */
 		this.playbackRate = 1;
+
+		/**
+		 * Indicates whether the audio is playing or not.
+		 *
+		 * This flag will be automatically set when using {@link Audio#play},
+		 * {@link Audio#pause}, {@link Audio#stop}.
+		 *
+		 * @type {boolean}
+		 * @readonly
+		 * @default false
+		 */
 		this.isPlaying = false;
+
+		/**
+		 * Indicates whether the audio playback can be controlled
+		 * with method like {@link Audio#play} or {@link Audio#pause}.
+		 *
+		 * This flag will be automatically set when audio sources are
+		 * defined.
+		 *
+		 * @type {boolean}
+		 * @readonly
+		 * @default true
+		 */
 		this.hasPlaybackControl = true;
+
+		/**
+		 * Holds a reference to the current audio source.
+		 *
+		 * The property is automatically by one of the `set*()` methods.
+		 *
+		 * @type {?AudioNode}
+		 * @readonly
+		 * @default null
+		 */
 		this.source = null;
+
+		/**
+		 * Defines the source type.
+		 *
+		 * The property is automatically by one of the `set*()` methods.
+		 *
+		 * @type {('empty'|'audioNode'|'mediaNode'|'mediaStreamNode'|'buffer')}
+		 * @readonly
+		 * @default 'empty'
+		 */
 		this.sourceType = 'empty';
 
 		this._startedAt = 0;
 		this._progress = 0;
 		this._connected = false;
 
+		/**
+		 * Can be used to apply a variety of low-order filters to create
+		 * more complex sound effects e.g. via `BiquadFilterNode`.
+		 *
+		 * The property is automatically set by {@link Audio#setFilters}.
+		 *
+		 * @type {Array<AudioNode>}
+		 * @readonly
+		 */
 		this.filters = [];
 
 	}
 
+	/**
+	 * Returns the output audio node.
+	 *
+	 * @return {GainNode} The output node.
+	 */
 	getOutput() {
 
 		return this.gain;
 
 	}
 
+	/**
+	 * Sets the given audio node as the source of this instance.
+	 *
+	 * {@link Audio#sourceType} is set to `audioNode` and {@link Audio#hasPlaybackControl} to `false`.
+	 *
+	 * @param {AudioNode} audioNode - The audio node like an instance of `OscillatorNode`.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setNodeSource( audioNode ) {
 
 		this.hasPlaybackControl = false;
@@ -54,6 +245,14 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Sets the given media element as the source of this instance.
+	 *
+	 * {@link Audio#sourceType} is set to `mediaNode` and {@link Audio#hasPlaybackControl} to `false`.
+	 *
+	 * @param {HTMLMediaElement} mediaElement - The media element.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setMediaElementSource( mediaElement ) {
 
 		this.hasPlaybackControl = false;
@@ -65,6 +264,14 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Sets the given media stream as the source of this instance.
+	 *
+	 * {@link Audio#sourceType} is set to `mediaStreamNode` and {@link Audio#hasPlaybackControl} to `false`.
+	 *
+	 * @param {MediaStream} mediaStream - The media stream.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setMediaStreamSource( mediaStream ) {
 
 		this.hasPlaybackControl = false;
@@ -76,6 +283,14 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Sets the given audio buffer as the source of this instance.
+	 *
+	 * {@link Audio#sourceType} is set to `buffer` and {@link Audio#hasPlaybackControl} to `true`.
+	 *
+	 * @param {AudioBuffer} audioBuffer - The audio buffer.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setBuffer( audioBuffer ) {
 
 		this.buffer = audioBuffer;
@@ -87,6 +302,14 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Starts the playback of the audio.
+	 *
+	 * Can only be used with compatible audio sources that allow playback control.
+	 *
+	 * @param {number} [delay=0] - The delay, in seconds, at which the audio should start playing.
+	 * @return {Audio} A reference to this instance.
+	 */
 	play( delay = 0 ) {
 
 		if ( this.isPlaying === true ) {
@@ -124,6 +347,13 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Pauses the playback of the audio.
+	 *
+	 * Can only be used with compatible audio sources that allow playback control.
+	 *
+	 * @return {Audio} A reference to this instance.
+	 */
 	pause() {
 
 		if ( this.hasPlaybackControl === false ) {
@@ -158,6 +388,14 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Stops the playback of the audio.
+	 *
+	 * Can only be used with compatible audio sources that allow playback control.
+	 *
+	 * @param {number} [delay=0] - The delay, in seconds, at which the audio should stop playing.
+	 * @return {Audio} A reference to this instance.
+	 */
 	stop( delay = 0 ) {
 
 		if ( this.hasPlaybackControl === false ) {
@@ -182,6 +420,12 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Connects to the audio source. This is used internally on
+	 * initialisation and when setting / removing filters.
+	 *
+	 * @return {Audio} A reference to this instance.
+	 */
 	connect() {
 
 		if ( this.filters.length > 0 ) {
@@ -208,6 +452,12 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Disconnects to the audio source. This is used internally on
+	 * initialisation and when setting / removing filters.
+	 *
+	 * @return {Audio} A reference to this instance.
+	 */
 	disconnect() {
 
 		if ( this._connected === false ) {
@@ -240,12 +490,23 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Returns the current set filters.
+	 *
+	 * @return {Array<AudioNode>} The list of filters.
+	 */
 	getFilters() {
 
 		return this.filters;
 
 	}
 
+	/**
+	 * Sets an array of filters and connects them with the audio source.
+	 *
+	 * @param {Array<AudioNode>} [value] - A list of filters.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setFilters( value ) {
 
 		if ( ! value ) value = [];
@@ -266,6 +527,12 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Defines the detuning of oscillation in cents.
+	 *
+	 * @param {number} value - The detuning of oscillation in cents.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setDetune( value ) {
 
 		this.detune = value;
@@ -280,24 +547,48 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Returns the detuning of oscillation in cents.
+	 *
+	 * @return {number} The detuning of oscillation in cents.
+	 */
 	getDetune() {
 
 		return this.detune;
 
 	}
 
+	/**
+	 * Returns the first filter in the list of filters.
+	 *
+	 * @return {AudioNode|undefined} The first filter in the list of filters.
+	 */
 	getFilter() {
 
 		return this.getFilters()[ 0 ];
 
 	}
 
+	/**
+	 * Applies a single filter node to the audio.
+	 *
+	 * @param {AudioNode} [filter] - The filter to set.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setFilter( filter ) {
 
 		return this.setFilters( filter ? [ filter ] : [] );
 
 	}
 
+	/**
+	 * Sets the playback rate.
+	 *
+	 * Can only be used with compatible audio sources that allow playback control.
+	 *
+	 * @param {number} [value] - The playback rate to set.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setPlaybackRate( value ) {
 
 		if ( this.hasPlaybackControl === false ) {
@@ -319,12 +610,20 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Returns the current playback rate.
+
+	 * @return {number} The playback rate.
+	 */
 	getPlaybackRate() {
 
 		return this.playbackRate;
 
 	}
 
+	/**
+	 * Automatically called when playback finished.
+	 */
 	onEnded() {
 
 		this.isPlaying = false;
@@ -332,6 +631,13 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Returns the loop flag.
+	 *
+	 * Can only be used with compatible audio sources that allow playback control.
+	 *
+	 * @return {boolean} Whether the audio should loop or not.
+	 */
 	getLoop() {
 
 		if ( this.hasPlaybackControl === false ) {
@@ -345,6 +651,14 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Sets the loop flag.
+	 *
+	 * Can only be used with compatible audio sources that allow playback control.
+	 *
+	 * @param {boolean} value - Whether the audio should loop or not.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setLoop( value ) {
 
 		if ( this.hasPlaybackControl === false ) {
@@ -366,6 +680,13 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Sets the loop start value which defines where in the audio buffer the replay should
+	 * start, in seconds.
+	 *
+	 * @param {number} value - The loop start value.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setLoopStart( value ) {
 
 		this.loopStart = value;
@@ -374,6 +695,13 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Sets the loop end value which defines where in the audio buffer the replay should
+	 * stop, in seconds.
+	 *
+	 * @param {number} value - The loop end value.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setLoopEnd( value ) {
 
 		this.loopEnd = value;
@@ -382,12 +710,23 @@ class Audio extends Object3D {
 
 	}
 
+	/**
+	 * Returns the volume.
+	 *
+	 * @return {number} The volume.
+	 */
 	getVolume() {
 
 		return this.gain.gain.value;
 
 	}
 
+	/**
+	 * Sets the volume.
+	 *
+	 * @param {number} value - The volume to set.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setVolume( value ) {
 
 		this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );

+ 58 - 1
src/audio/AudioAnalyser.js

@@ -1,17 +1,69 @@
+/**
+ * This class can be used to analyse audio data.
+ *
+ * ```js
+ * // create an AudioListener and add it to the camera
+ * const listener = new THREE.AudioListener();
+ * camera.add( listener );
+ *
+ * // create an Audio source
+ * const sound = new THREE.Audio( listener );
+ *
+ * // load a sound and set it as the Audio object's buffer
+ * const audioLoader = new THREE.AudioLoader();
+ * audioLoader.load( 'sounds/ambient.ogg', function( buffer ) {
+ * 	sound.setBuffer( buffer );
+ * 	sound.setLoop(true);
+ * 	sound.setVolume(0.5);
+ * 	sound.play();
+ * });
+ *
+ * // create an AudioAnalyser, passing in the sound and desired fftSize
+ * const analyser = new THREE.AudioAnalyser( sound, 32 );
+ *
+ * // get the average frequency of the sound
+ * const data = analyser.getAverageFrequency();
+ * ```
+ */
 class AudioAnalyser {
 
+	/**
+	 * Constructs a new audio analyzer.
+	 *
+	 * @param {Audio} audio - The audio to analyze.
+	 * @param {Audio} [fftSize=2048] - The window size in samples that is used when performing a Fast Fourier Transform (FFT) to get frequency domain data.
+	 */
 	constructor( audio, fftSize = 2048 ) {
 
+		/**
+		 * The global audio listener.
+		 *
+		 * @type {AnalyserNode}
+		 */
 		this.analyser = audio.context.createAnalyser();
 		this.analyser.fftSize = fftSize;
 
+		/**
+		 * Holds the analyzed data.
+		 *
+		 * @type {Uint8Array}
+		 */
 		this.data = new Uint8Array( this.analyser.frequencyBinCount );
 
 		audio.getOutput().connect( this.analyser );
 
 	}
 
-
+	/**
+	 * Returns an array with frequency data of the audio.
+	 *
+	 * Each item in the array represents the decibel value for a specific frequency.
+	 * The frequencies are spread linearly from 0 to 1/2 of the sample rate.
+	 * For example, for 48000 sample rate, the last item of the array will represent
+	 * the decibel value for 24000 Hz.
+	 *
+	 * @return {Uint8Array} The frequency data.
+	 */
 	getFrequencyData() {
 
 		this.analyser.getByteFrequencyData( this.data );
@@ -20,6 +72,11 @@ class AudioAnalyser {
 
 	}
 
+	/**
+	 * Returns the average of the frequencies returned by {@link AudioAnalyser#getFrequencyData}.
+	 *
+	 * @return {number} The average frequency.
+	 */
 	getAverageFrequency() {
 
 		let value = 0;

+ 15 - 0
src/audio/AudioContext.js

@@ -1,7 +1,17 @@
 let _context;
 
+/**
+ * Manages the global audio context in the engine.
+ *
+ * @hideconstructor
+ */
 class AudioContext {
 
+	/**
+	 * Returns the global native audio context.
+	 *
+	 * @return {AudioContext} The native audio context.
+	 */
 	static getContext() {
 
 		if ( _context === undefined ) {
@@ -14,6 +24,11 @@ class AudioContext {
 
 	}
 
+	/**
+	 * Allows to set the global native audio context from outside.
+	 *
+	 * @param {AudioContext} value - The native context to set.
+	 */
 	static setContext( value ) {
 
 		_context = value;

+ 75 - 0
src/audio/AudioListener.js

@@ -9,21 +9,61 @@ const _quaternion = /*@__PURE__*/ new Quaternion();
 const _scale = /*@__PURE__*/ new Vector3();
 const _orientation = /*@__PURE__*/ new Vector3();
 
+/**
+ * The class represents a virtual listern of the all positional and non-positional audio effects
+ * in the scene. A three.js application usually creates a single listener. It is a mandatory
+ * constructor parameter for audios entities like {@link Audio} and {@link PositionalAudio}.
+ *
+ * In most cases, the listener object is a child of the camera. So the 3D transformation of the
+ * camera represents the 3D transformation of the listener.
+ *
+ * @augments Object3D
+ */
 class AudioListener extends Object3D {
 
+	/**
+	 * Constructs a new audio listener.
+	 */
 	constructor() {
 
 		super();
 
 		this.type = 'AudioListener';
 
+		/**
+		 * The native audio context.
+		 *
+		 * @type {AudioContext}
+		 * @readonly
+		 */
 		this.context = AudioContext.getContext();
 
+		/**
+		 * The gain node used for volume control.
+		 *
+		 * @type {GainNode}
+		 * @readonly
+		 */
 		this.gain = this.context.createGain();
 		this.gain.connect( this.context.destination );
 
+		/**
+		 * An optional filter.
+		 *
+		 * Defined via {@AudioListener#setFilter}.
+		 *
+		 * @type {?AudioNode}
+		 * @readonly
+		 */
 		this.filter = null;
 
+		/**
+		 * Time delta values required for `linearRampToValueAtTime()` usage.
+		 *
+		 * @type {number}
+		 * @default 0
+		 * @readonly
+		 */
 		this.timeDelta = 0;
 
 		// private
@@ -32,12 +72,24 @@ class AudioListener extends Object3D {
 
 	}
 
+	/**
+	 * Returns the listener's input node.
+	 *
+	 * This method is used by other audio nodes to connect to this listener.
+	 *
+	 * @return {GainNode} The input node.
+	 */
 	getInput() {
 
 		return this.gain;
 
 	}
 
+	/**
+	 * Removes the current filter from this listener.
+	 *
+	 * @return {AudioListener} A reference to this listener.
+	 */
 	removeFilter() {
 
 		if ( this.filter !== null ) {
@@ -53,12 +105,23 @@ class AudioListener extends Object3D {
 
 	}
 
+	/**
+	 * Returns the current set filter.
+	 *
+	 * @return {AudioNode} The filter.
+	 */
 	getFilter() {
 
 		return this.filter;
 
 	}
 
+	/**
+	 * Sets the given filter to this listener.
+	 *
+	 * @param {AudioNode} value - The filter to set.
+	 * @return {AudioListener} A reference to this listener.
+	 */
 	setFilter( value ) {
 
 		if ( this.filter !== null ) {
@@ -80,12 +143,24 @@ class AudioListener extends Object3D {
 
 	}
 
+	/**
+	 * Returns the applications master volume.
+	 *
+	 * @return {number} The master volume.
+	 */
 	getMasterVolume() {
 
 		return this.gain.gain.value;
 
 	}
 
+	/**
+	 * Sets the applications master volume. This volume setting affects
+	 * all audio nodes in the scene.
+	 *
+	 * @param {number} value - The master volume to set.
+	 * @return {AudioListener} A reference to this listener.
+	 */
 	setMasterVolume( value ) {
 
 		this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );

+ 107 - 0
src/audio/PositionalAudio.js

@@ -7,12 +7,54 @@ const _quaternion = /*@__PURE__*/ new Quaternion();
 const _scale = /*@__PURE__*/ new Vector3();
 const _orientation = /*@__PURE__*/ new Vector3();
 
+/**
+ * Represents a positional audio object.
+ *
+ * ```js
+ * // create an AudioListener and add it to the camera
+ * const listener = new THREE.AudioListener();
+ * camera.add( listener );
+ *
+ * // create the PositionalAudio object (passing in the listener)
+ * const sound = new THREE.PositionalAudio( listener );
+ *
+ * // load a sound and set it as the PositionalAudio object's buffer
+ * const audioLoader = new THREE.AudioLoader();
+ * audioLoader.load( 'sounds/song.ogg', function( buffer ) {
+ * 	sound.setBuffer( buffer );
+ * 	sound.setRefDistance( 20 );
+ * 	sound.play();
+ * });
+ *
+ * // create an object for the sound to play from
+ * const sphere = new THREE.SphereGeometry( 20, 32, 16 );
+ * const material = new THREE.MeshPhongMaterial( { color: 0xff2200 } );
+ * const mesh = new THREE.Mesh( sphere, material );
+ * scene.add( mesh );
+ *
+ * // finally add the sound to the mesh
+ * mesh.add( sound );
+ *
+ * @augments Audio
+ */
 class PositionalAudio extends Audio {
 
+	/**
+	 * Constructs a positional audio.
+	 *
+	 * @param {AudioListener} listener - The global audio listener.
+	 */
 	constructor( listener ) {
 
 		super( listener );
 
+		/**
+		 * The panner node represents the location, direction, and behavior of an audio
+		 * source in 3D space.
+		 *
+		 * @type {PannerNode}
+		 * @readonly
+		 */
 		this.panner = this.context.createPanner();
 		this.panner.panningModel = 'HRTF';
 		this.panner.connect( this.gain );
@@ -25,6 +67,8 @@ class PositionalAudio extends Audio {
 
 		this.panner.connect( this.gain );
 
+		return this;
+
 	}
 
 	disconnect() {
@@ -33,6 +77,8 @@ class PositionalAudio extends Audio {
 
 		this.panner.disconnect( this.gain );
 
+		return this;
+
 	}
 
 	getOutput() {
@@ -41,12 +87,25 @@ class PositionalAudio extends Audio {
 
 	}
 
+	/**
+	 * Returns the current reference distance.
+	 *
+	 * @return {number} The reference distance.
+	 */
 	getRefDistance() {
 
 		return this.panner.refDistance;
 
 	}
 
+	/**
+	 * Defines the reference distance for reducing volume as the audio source moves
+	 * further from the listener – i.e. the distance at which the volume reduction
+	 * starts taking effect.
+	 *
+	 * @param {number} value - The reference distance to set.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setRefDistance( value ) {
 
 		this.panner.refDistance = value;
@@ -55,12 +114,23 @@ class PositionalAudio extends Audio {
 
 	}
 
+	/**
+	 * Returns the current rolloff factor.
+	 *
+	 * @return {number} The rolloff factor.
+	 */
 	getRolloffFactor() {
 
 		return this.panner.rolloffFactor;
 
 	}
 
+	/**
+	 * Defines how quickly the volume is reduced as the source moves away from the listener.
+	 *
+	 * @param {number} value - The rolloff factor.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setRolloffFactor( value ) {
 
 		this.panner.rolloffFactor = value;
@@ -69,12 +139,27 @@ class PositionalAudio extends Audio {
 
 	}
 
+	/**
+	 * Returns the current distance model.
+	 *
+	 * @return {('linear'|'inverse'|'exponential')} The distance model.
+	 */
 	getDistanceModel() {
 
 		return this.panner.distanceModel;
 
 	}
 
+	/**
+	 * Defines which algorithm to use to reduce the volume of the audio source
+	 * as it moves away from the listener.
+	 *
+	 * Read [the spec]{@link https://www.w3.org/TR/webaudio-1.1/#enumdef-distancemodeltype}
+	 * for more details.
+	 *
+	 * @param {('linear'|'inverse'|'exponential')} value - The distance model to set.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setDistanceModel( value ) {
 
 		this.panner.distanceModel = value;
@@ -83,12 +168,26 @@ class PositionalAudio extends Audio {
 
 	}
 
+	/**
+	 * Returns the current max distance.
+	 *
+	 * @return {number} The max distance.
+	 */
 	getMaxDistance() {
 
 		return this.panner.maxDistance;
 
 	}
 
+	/**
+	 * Defines the maximum distance between the audio source and the listener,
+	 * after which the volume is not reduced any further.
+	 *
+	 * This value is used only by the `linear` distance model.
+	 *
+	 * @param {number} value - The max distance.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setMaxDistance( value ) {
 
 		this.panner.maxDistance = value;
@@ -97,6 +196,14 @@ class PositionalAudio extends Audio {
 
 	}
 
+	/**
+	 * Sets the directional cone in which the audio can be listened.
+	 *
+	 * @param {number} coneInnerAngle - An angle, in degrees, of a cone inside of which there will be no volume reduction.
+	 * @param {number} coneOuterAngle - An angle, in degrees, of a cone outside of which the volume will be reduced by a constant value, defined by the `coneOuterGain` parameter.
+	 * @param {number} coneOuterGain - The amount of volume reduction outside the cone defined by the `coneOuterAngle`. When set to `0`, no sound can be heard.
+	 * @return {Audio} A reference to this instance.
+	 */
 	setDirectionalCone( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
 
 		this.panner.coneInnerAngle = coneInnerAngle;

+ 5 - 1
utils/docs/jsdoc.config.json

@@ -4,12 +4,16 @@
             "encoding": "utf8",
             "package": "package.json",
             "recurse": true,
-            "template": "utils/docs/template"
+            "template": "utils/docs/template",
+            "themeOpts": {
+                "ignoreInheritedSymbols": true
+            }
     },
     "plugins": [ "plugins/markdown" ],
     "source": {
         "include": [
             "examples/jsm/tsl",
+            "src/audio",
             "src/cameras",
             "src/core/Object3D.js",
             "src/core/EventDispatcher.js",

+ 2 - 0
utils/docs/template/publish.js

@@ -16,6 +16,7 @@ let data;
 let view;
 
 let outdir = path.normalize( env.opts.destination );
+const themeOpts = ( env.opts.themeOpts ) || {};
 
 function mkdirSync( filepath ) {
 
@@ -723,6 +724,7 @@ exports.publish = ( taffyData, opts, tutorials ) => {
 	view.resolveAuthorLinks = resolveAuthorLinks;
 	view.htmlsafe = htmlsafe;
 	view.outputSourceFiles = outputSourceFiles;
+	view.ignoreInheritedSymbols = themeOpts.ignoreInheritedSymbols;
 
 	// once for all
 	view.nav = buildNav( members );

+ 8 - 7
utils/docs/template/tmpl/container.tmpl

@@ -74,6 +74,7 @@
     <?js } ?>
 
     <?js
+        var ignoreInheritedSymbols = { ...(self.ignoreInheritedSymbols ? { inherited: {isUndefined: true} } : {}) };
         var classes = self.find({kind: 'class', memberof: doc.longname});
         if (!isGlobalPage && classes && classes.length) {
     ?>
@@ -86,7 +87,7 @@
     <?js } ?>
 
     <?js
-        var interfaces = self.find({kind: 'interface', memberof: doc.longname});
+        var interfaces = self.find({kind: 'interface', memberof: doc.longname, ...ignoreInheritedSymbols});
         if (!isGlobalPage && interfaces && interfaces.length) {
     ?>
         <h3 class="subsection-title">Interfaces</h3>
@@ -98,7 +99,7 @@
     <?js } ?>
 
     <?js
-        var mixins = self.find({kind: 'mixin', memberof: doc.longname});
+        var mixins = self.find({kind: 'mixin', memberof: doc.longname, ...ignoreInheritedSymbols});
         if (!isGlobalPage && mixins && mixins.length) {
     ?>
         <h3 class="subsection-title">Mixins</h3>
@@ -110,7 +111,7 @@
     <?js } ?>
 
     <?js
-        var namespaces = self.find({kind: 'namespace', memberof: doc.longname});
+        var namespaces = self.find({kind: 'namespace', memberof: doc.longname, ...ignoreInheritedSymbols});
         if (!isGlobalPage && namespaces && namespaces.length) {
     ?>
         <h3 class="subsection-title">Namespaces</h3>
@@ -122,7 +123,7 @@
     <?js } ?>
 
     <?js
-        var members = self.find({kind: 'member', memberof: isGlobalPage ? {isUndefined: true} : doc.longname});
+        var members = self.find({kind: 'member', memberof: isGlobalPage ? {isUndefined: true} : doc.longname, ...ignoreInheritedSymbols});
 
         // symbols that are assigned to module.exports are not globals, even though they're not a memberof anything
         if (isGlobalPage && members && members.length && members.forEach) {
@@ -140,7 +141,7 @@
     <?js } ?>
 
     <?js
-        var methods = self.find({kind: 'function', memberof: isGlobalPage ? {isUndefined: true} : doc.longname});
+        var methods = self.find({kind: 'function', memberof: isGlobalPage ? {isUndefined: true} : doc.longname, ...ignoreInheritedSymbols});
         if (methods && methods.length && methods.forEach) {
     ?>
         <h3 class="subsection-title">Methods</h3>
@@ -151,7 +152,7 @@
     <?js } ?>
 
     <?js
-        var typedefs = self.find({kind: 'typedef', memberof: isGlobalPage ? {isUndefined: true} : doc.longname});
+        var typedefs = self.find({kind: 'typedef', memberof: isGlobalPage ? {isUndefined: true} : doc.longname, ...ignoreInheritedSymbols});
         if (typedefs && typedefs.length && typedefs.forEach) {
     ?>
         <h3 class="subsection-title">Type Definitions</h3>
@@ -171,7 +172,7 @@
     <?js } ?>
 
     <?js
-        var events = self.find({kind: 'event', memberof: isGlobalPage ? {isUndefined: true} : doc.longname});
+        var events = self.find({kind: 'event', memberof: isGlobalPage ? {isUndefined: true} : doc.longname, ...ignoreInheritedSymbols});
         if (events && events.length && events.forEach) {
     ?>
         <h3 class="subsection-title">Events</h3>

粤ICP备19079148号