1 /**
  2  * @fileoverview WebAudio.js plugin for tQuery
  3 */
  4 tQuery.World.register('enableWebAudio', function(){
  5 	// sanity check
  6 	console.assert( this.hasWebAudio() === false, "there is already a webaudio" );
  7 	// intenciate a tQuery.World.WebAudio
  8 	var webaudio	= new WebAudio();
  9 	// follow the listener
 10 	var world	= this;
 11 	webaudio.followListener(world);
 12 	// store webaudio in the world
 13 	tQuery.data(this, "webaudio", webaudio);
 14 	// for chained API
 15 	return this;
 16 });
 17 
 18 tQuery.World.register('disabledWebAudio', function(){
 19 	if( this.hasWebAudio() === false )	return this;
 20 	var webaudio	= tQuery.data(this, "webaudio");
 21 	webaudio.destroy();
 22 	tQuery.removeData(this, "webaudio");
 23 	return this;	// for chained API
 24 });
 25 
 26 tQuery.World.register('getWebAudio', function(){
 27 	var webaudio	= tQuery.data(this, "webaudio");
 28 	return webaudio;
 29 });
 30 
 31 tQuery.World.register('hasWebAudio', function(){
 32 	var webaudio	= tQuery.data(this, "webaudio");
 33 	return webaudio ? true : false;
 34 });
 35 
 36 tQuery.World.register('supportWebAudio', function(){
 37 	return WebAudio.isAvailable;
 38 });
 39 
 40 tQuery.register('createSound', function(world, nodeChain){
 41 	world	= world || tQuery.world;
 42 	return new WebAudio.Sound(world.getWebAudio(), nodeChain);
 43 });
 44 
 45 
 46 //////////////////////////////////////////////////////////////////////////////////
 47 //										//
 48 //////////////////////////////////////////////////////////////////////////////////
 49 
 50 WebAudio.fn.followListener	= function(world){
 51 	this._$followListenerCb	= function(deltaTime){
 52 		this._followListenerCb(world.camera(), deltaTime);
 53 	}.bind(this);
 54 	world.loop().hook(this._$followListenerCb);
 55 }
 56 
 57 WebAudio.fn.unfollowListener	= function(world){
 58 	// unhook this._updateCb from this.world.loop()
 59 	world.loop().unhook(this._$followListenerCb);
 60 	this._$followListenerCb	= null;
 61 }
 62 
 63 WebAudio.fn._followListenerCb	= function(object3d, deltaTime){
 64 	var context	= this._ctx;
 65 	// sanity check on parameters
 66 	console.assert( object3d instanceof THREE.Object3D );
 67 	console.assert( typeof(deltaTime) === 'number' );
 68 
 69 	// ensure object3d.matrixWorld is up to date
 70 	object3d.updateMatrixWorld();
 71 	
 72 	////////////////////////////////////////////////////////////////////////
 73 	// set position
 74 	var position	= object3d.matrixWorld.getPosition();
 75 	context.listener.setPosition(position.x, position.y, position.z);
 76 
 77 	////////////////////////////////////////////////////////////////////////
 78 	// set orientation
 79 	var mOrientation= object3d.matrixWorld.clone();
 80 	// zero the translation
 81 	mOrientation.setPosition({x : 0, y: 0, z: 0});
 82 	// Compute Front vector: Multiply the 0,0,1 vector by the world matrix and normalize the result.
 83 	var vFront= new THREE.Vector3(0,0,1);
 84 	mOrientation.multiplyVector3(vFront);
 85 	vFront.normalize();
 86 	// Compute UP vector: Multiply the 0,-1,0 vector by the world matrix and normalize the result.
 87 	var vUp= new THREE.Vector3(0,-1, 0);
 88 	mOrientation.multiplyVector3(vUp);
 89 	vUp.normalize();
 90 	// Set panner orientation
 91 	context.listener.setOrientation(vFront.x, vFront.y, vFront.z, vUp.x, vUp.y, vUp.z);
 92 
 93 	////////////////////////////////////////////////////////////////////////
 94 	// set velocity
 95 	if( this._prevPos === undefined ){
 96 		this._prevPos	= object3d.matrixWorld.getPosition().clone();
 97 	}else{
 98 		var position	= object3d.matrixWorld.getPosition();
 99 		var velocity	= position.clone().subSelf(this._prevPos).divideScalar(deltaTime);
100 		this._prevPos	= object3d.matrixWorld.getPosition().clone();
101 		context.listener.setVelocity(velocity.x, velocity.y, velocity.z);
102 	}
103 }
104 
105 
106