PageRenderTime 23ms CodeModel.GetById 15ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/src/away3d/audio/SoundTransform3D.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 169 lines | 104 code | 32 blank | 33 comment | 6 complexity | 9c3e1646a9fe454e3de92254b446ca70 MD5 | raw file
  1package away3d.audio
  2{
  3	import away3d.containers.ObjectContainer3D;
  4	
  5	import flash.geom.Matrix3D;
  6	import flash.geom.Vector3D;
  7	import flash.media.SoundTransform;
  8	
  9	/**
 10	 * SoundTransform3D is a convinience class that helps adjust a Soundtransform's volume and pan according
 11	 * position and distance of a listener and emitter object. See SimplePanVolumeDriver for the limitations
 12	 * of this method.
 13	 */
 14	public class SoundTransform3D
 15	{
 16		
 17		private var _scale:Number;
 18		private var _volume:Number;
 19		private var _soundTransform:SoundTransform;
 20		
 21		private var _emitter:ObjectContainer3D;
 22		private var _listener:ObjectContainer3D;
 23		
 24		private var _refv:Vector3D;
 25		private var _inv_ref_mtx:Matrix3D;
 26		private var _r:Number;
 27		private var _r2:Number;
 28		private var _azimuth:Number;
 29		
 30		/**
 31		 * Creates a new SoundTransform3D.
 32		 * @param emitter the ObjectContainer3D from which the sound originates.
 33		 * @param listener the ObjectContainer3D considered to be to position of the listener (usually, the camera)
 34		 * @param volume the maximum volume used.
 35		 * @param scale the distance that the sound covers.
 36		 *
 37		 */
 38		public function SoundTransform3D(emitter:ObjectContainer3D = null, listener:ObjectContainer3D = null, volume:Number = 1, scale:Number = 1000)
 39		{
 40			
 41			_emitter = emitter;
 42			_listener = listener;
 43			_volume = volume;
 44			_scale = scale;
 45			
 46			_inv_ref_mtx = new Matrix3D();
 47			_refv = new Vector3D();
 48			_soundTransform = new SoundTransform(volume);
 49			
 50			_r = 0;
 51			_r2 = 0;
 52			_azimuth = 0;
 53		
 54		}
 55		
 56		/**
 57		 * updates the SoundTransform based on the emitter and listener.
 58		 */
 59		public function update():void
 60		{
 61			
 62			if (_emitter && _listener) {
 63				_inv_ref_mtx.rawData = _listener.sceneTransform.rawData;
 64				_inv_ref_mtx.invert();
 65				_refv = _inv_ref_mtx.deltaTransformVector(_listener.position);
 66				_refv = _emitter.scenePosition.subtract(_refv);
 67			}
 68			
 69			updateFromVector3D(_refv);
 70		}
 71		
 72		/**
 73		 * udpates the SoundTransform based on the vector representing the distance and
 74		 * angle between the emitter and listener.
 75		 *
 76		 * @param v Vector3D
 77		 *
 78		 */
 79		public function updateFromVector3D(v:Vector3D):void
 80		{
 81			
 82			_azimuth = Math.atan2(v.x, v.z);
 83			if (_azimuth < -1.5707963)
 84				_azimuth = -(1.5707963 + (_azimuth%1.5707963));
 85			else if (_azimuth > 1.5707963)
 86				_azimuth = 1.5707963 - (_azimuth%1.5707963);
 87			
 88			// Divide by a number larger than pi/2, to make sure
 89			// that pan is never full +/-1.0, muting one channel
 90			// completely, which feels very unnatural. 
 91			_soundTransform.pan = (_azimuth/1.7);
 92			
 93			// Offset radius so that max value for volume curve is 1,
 94			// (i.e. y~=1 for r=0.) Also scale according to configured
 95			// driver scale value.
 96			_r = (v.length/_scale) + 0.28209479;
 97			_r2 = _r*_r;
 98			
 99			// Volume is calculated according to the formula for
100			// sound intensity, I = P / (4 * pi * r^2)
101			// Avoid division by zero.
102			if (_r2 > 0)
103				_soundTransform.volume = (1/(12.566*_r2)); // 1 / 4pi * r^2
104			else
105				_soundTransform.volume = 1;
106			
107			// Alter according to user-specified volume
108			_soundTransform.volume *= _volume;
109		
110		}
111		
112		public function get soundTransform():SoundTransform
113		{
114			
115			return _soundTransform;
116		}
117		
118		public function set soundTransform(value:SoundTransform):void
119		{
120			_soundTransform = value;
121			update();
122		}
123		
124		public function get scale():Number
125		{
126			return _scale;
127		}
128		
129		public function set scale(value:Number):void
130		{
131			_scale = value;
132			update();
133		}
134		
135		public function get volume():Number
136		{
137			return _volume;
138		}
139		
140		public function set volume(value:Number):void
141		{
142			_volume = value;
143			update();
144		}
145		
146		public function get emitter():ObjectContainer3D
147		{
148			return _emitter;
149		}
150		
151		public function set emitter(value:ObjectContainer3D):void
152		{
153			_emitter = value;
154			update();
155		}
156		
157		public function get listener():ObjectContainer3D
158		{
159			return _listener;
160		}
161		
162		public function set listener(value:ObjectContainer3D):void
163		{
164			_listener = value;
165			update();
166		}
167	
168	}
169}