فهرست منبع

Implemented THREE.Audio and THREE.AudioListener. See #5128.

Mr.doob 11 سال پیش
والد
کامیت
5ba54f7166
5فایلهای تغییر یافته به همراه135 افزوده شده و 55 حذف شده
  1. 11 55
      examples/misc_sound.html
  2. 74 0
      src/extras/audio/Audio.js
  3. 47 0
      src/extras/audio/AudioListener.js
  4. 1 0
      utils/build/externs/common.js
  5. 2 0
      utils/build/includes/extras.json

+ 11 - 55
examples/misc_sound.html

@@ -59,49 +59,8 @@
 			var mesh;
 			var material_sphere1, material_sphere2;
 
-			var sound1, sound2;
-
 			var clock = new THREE.Clock();
 
-			var Sound = function ( sources, radius, volume ) {
-
-				var audio = document.createElement( 'audio' );
-
-				for ( var i = 0; i < sources.length; i ++ ) {
-
-					var source = document.createElement( 'source' );
-					source.src = sources[ i ];
-
-					audio.appendChild( source );
-
-				}
-
-				this.position = new THREE.Vector3();
-
-				this.play = function () {
-
-					audio.play();
-
-				}
-
-				this.update = function ( camera ) {
-
-					var distance = this.position.distanceTo( camera.position );
-
-					if ( distance <= radius ) {
-
-						audio.volume = volume * ( 1 - distance / radius );
-
-					} else {
-
-						audio.volume = 0;
-
-					}
-
-				}
-
-			}
-
 			init();
 			animate();
 
@@ -112,6 +71,9 @@
 				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
 				camera.position.set( 0, 25, 0 );
 
+				var listener = new THREE.AudioListener();
+				camera.add( listener );
+
 				controls = new THREE.FirstPersonControls( camera );
 
 				controls.movementSpeed = 70;
@@ -133,28 +95,25 @@
 
 				// sound spheres
 
-				var s = 1;
-
 				var mesh1 = new THREE.Mesh( sphere, material_sphere1 );
 				mesh1.position.set( -250, 30, 0 );
-				mesh1.scale.set( s, s, s );
 				scene.add( mesh1 );
 
-				sound1 = new Sound( [ 'sounds/358232_j_s_song.mp3', 'sounds/358232_j_s_song.ogg' ], 275, 1 );
-				sound1.position.copy( mesh1.position );
-				sound1.play();
+				var sound1 = new THREE.Audio( listener );
+				sound1.load( 'sounds/358232_j_s_song.ogg' );
+				sound1.setRefDistance( 20 );
+				mesh1.add( sound1 );
 
 				//
 
 				var mesh2 = new THREE.Mesh( sphere, material_sphere2 );
 				mesh2.position.set( 250, 30, 0 );
-				mesh2.scale.set( s, s, s );
 				scene.add( mesh2 );
 
-				sound2 = new Sound( [ 'sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3', 'sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg' ], 275, 1 );
-				sound2.position.copy( mesh2.position );
-				sound2.play();
-
+				var sound2 = new THREE.Audio( listener );
+				sound2.load( 'sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg' );
+				sound2.setRefDistance( 20 );
+				mesh2.add( sound2 );
 
 				// ground
 
@@ -210,9 +169,6 @@
 
 				renderer.render( scene, camera );
 
-				sound1.update( camera );
-				sound2.update( camera );
-
 			}
 
 		</script>

+ 74 - 0
src/extras/audio/Audio.js

@@ -0,0 +1,74 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.Audio = function ( listener ) {
+
+	THREE.Object3D.call( this );
+
+	this.type = 'Audio';
+
+	this.context = listener.context;
+	this.source = this.context.createBufferSource();
+
+	this.gain = this.context.createGain();
+	this.gain.connect( this.context.destination );
+
+	this.panner = this.context.createPanner();
+	this.panner.connect( this.gain );
+
+};
+
+THREE.Audio.prototype = Object.create( THREE.Object3D.prototype );
+
+THREE.Audio.prototype.load = function ( file ) {
+
+	var scope = this;
+
+	var request = new XMLHttpRequest();
+	request.open( 'GET', file, true );
+	request.responseType = 'arraybuffer';
+	request.onload = function ( e ) {
+
+		scope.context.decodeAudioData( this.response, function ( buffer ) {
+
+			scope.source.buffer = buffer;
+			scope.source.connect( scope.panner );
+			scope.source.start();
+
+		} );
+
+	};
+	request.send();
+
+	return this;
+
+};
+
+THREE.Audio.prototype.setRefDistance = function ( value ) {
+
+	this.panner.refDistance = value;
+
+};
+
+THREE.Audio.prototype.setRolloffFactor = function ( value ) {
+
+	this.panner.rolloffFactor = value;
+
+};
+
+THREE.Audio.prototype.updateMatrixWorld = ( function () {
+	
+	var position = new THREE.Vector3();
+
+	return function ( force ) {
+
+		THREE.Object3D.prototype.updateMatrixWorld.call( this, force );
+
+		position.setFromMatrixPosition( this.matrixWorld );
+
+		this.panner.setPosition( position.x, position.y, position.z );
+
+	};
+
+} )();

+ 47 - 0
src/extras/audio/AudioListener.js

@@ -0,0 +1,47 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.AudioListener = function () {
+
+	THREE.Object3D.call( this );
+
+	this.type = 'AudioListener';
+
+	this.context = new AudioContext();
+
+};
+
+THREE.AudioListener.prototype = Object.create( THREE.Object3D.prototype );
+
+THREE.AudioListener.prototype.updateMatrixWorld = ( function () {
+
+	var position = new THREE.Vector3();
+	var quaternion = new THREE.Quaternion();
+	var scale = new THREE.Vector3();
+
+	var orientation = new THREE.Vector3();
+	var velocity = new THREE.Vector3();
+
+	var positionPrev = new THREE.Vector3();
+
+	return function ( force ) {
+	
+		THREE.Object3D.prototype.updateMatrixWorld.call( this, force );
+
+		var listener = this.context.listener;
+
+		this.matrixWorld.decompose( position, quaternion, scale );
+
+		orientation.set( 0, 0, -1 ).applyQuaternion( quaternion );
+		velocity.subVectors( position, positionPrev );
+
+		listener.setPosition( position.x, position.y, position.z );
+		listener.setOrientation( orientation.x, orientation.y, orientation.z, this.up.x, this.up.y, this.up.z );
+		listener.setVelocity( velocity.x, velocity.y, velocity.z );
+
+		positionPrev.copy( position );
+
+	};
+
+} )();

+ 1 - 0
utils/build/externs/common.js

@@ -1,3 +1,4 @@
+var AudioContext;
 var console;
 var module;
 var JSON;

+ 2 - 0
utils/build/includes/extras.json

@@ -3,6 +3,8 @@
 	"src/extras/ImageUtils.js",
 	"src/extras/SceneUtils.js",
 	"src/extras/FontUtils.js",
+	"src/extras/audio/Audio.js",
+	"src/extras/audio/AudioListener.js",
 	"src/extras/core/Curve.js",
 	"src/extras/core/CurvePath.js",
 	"src/extras/core/Gyroscope.js",