Sound3D

From Flare3D Wiki
Jump to: navigation, search

This example shows how to create 3d sounds and attach them to 3d objects.

The sounds are based on a distance radius and only are active when the camera is close enough to the 3d sound, otherwise, they are stopped.

The class also manages loop counting and reactivation of the sounds in case they were stopped.


Usage Example

package
{
	import flare.basic.*;
	import flare.core.*;
	import flare.system.*;
	import flash.display.*;
	import flash.events.*;
	import flash.media.*;
 
	/**
	 * @author Ariel Nehmad
	 */
	public class Sound3DTest extends Sprite 
	{
		[Embed(source = "sound0.mp3")] private var Sound0:Class;
		[Embed(source = "sound1.mp3")] private var Sound1:Class;
		[Embed(source = "sound2.mp3")] private var Sound2:Class;
		[Embed(source = "sound3.mp3")] private var Sound3:Class;
		[Embed(source = "cubes.f3d", mimeType = "application/octet-stream")] private var Cubes:Class;
 
		private var scene:Scene3D;
		private var model:Pivot3D;
 
		public function Sound3DTest() 
		{
			scene = new Viewer3D(stage);
			scene.autoResize = true;
			scene.antialias = 2;
			scene.camera = new Camera3D();
			scene.camera.setPosition( 100, 50, -150 );
			scene.camera.lookAt( 0, 0, 0 );
			scene.addEventListener( Scene3D.COMPLETE_EVENT, completeEvent );
			model = scene.addChildFromFile( new Cubes() );
		}
 
		private function completeEvent(e:Event):void 
		{
			scene.getChildByName( "Cube0" ).addChild( new Sound3D( "s0", new Sound0(), -1, 200 ) );
			scene.getChildByName( "Cube1" ).addChild( new Sound3D( "s1", new Sound1(), -1, 200 ) );
			scene.getChildByName( "Cube2" ).addChild( new Sound3D( "s2", new Sound2(), -1, 200 ) );
			scene.getChildByName( "Cube3" ).addChild( new Sound3D( "s3", new Sound3(), -1, 200 ) );
 
			scene.addEventListener( Scene3D.UPDATE_EVENT, updateEvent );
		}
 
		private function updateEvent(e:Event):void 
		{
			if ( !Input3D.mouseDown ) model.rotateY( 0.4 );
		}
	}
}

Sound3D class

package flare.core 
{
	import flare.core.*;
	import flare.materials.*;
	import flare.system.*;
	import flare.utils.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.media.*;
 
	/**
	 * @author Ariel Nehmad
	 */
	public class Sound3D extends Pivot3D implements IDrawable
	{
		private static var _position:Vector3D = new Vector3D();
 
		private var _soundChannel:SoundChannel;
		private var _soundTransform:SoundTransform;
		private var _loops:int;
		private var _currLoop:int;
 
		public var radius:Number;
		public var smooth:Number;
		public var sound:Sound;
		public var reactivate:Boolean = true;
 
		public function Sound3D( name:String, sound:Sound, loops:int = -1, radius:Number = 500, smooth:Number = 0.3 )
		{
			super( name );
			trace("SOUND");
			this.sound = sound;
			this.smooth = smooth;
			this.radius = radius;
 
			_loops = loops;
			_currLoop = loops;
			_soundTransform = new SoundTransform( 0, 0 );
		}
 
		private function soundPlayEvent(e:Event = null):Boolean
		{
			if ( _currLoop != 0 ) {
				_soundChannel = sound.play();
				_soundChannel.addEventListener( Event.SOUND_COMPLETE, soundPlayEvent );
			}
			else {
				if ( _soundChannel ) _soundChannel.stop();
				_soundChannel = null;
				return false;
			}
 
			_currLoop--;
 
			return true;
		}
 
		public override function draw( includeChildren:Boolean = true, material:Material3D = null ):void
		{
			super.draw(includeChildren);
			// gets the sound global position.
			world.copyColumnTo( 3, _position );
 
			// transform to the camera space.
			scene.camera.globalToLocal( _position, _position );
 
			// calculates the volume using the sound to camera distance.
			var volume:Number = ( radius - _position.length ) / radius;
 
			if ( volume > 0 ) {
				if ( !_soundChannel && soundPlayEvent() == false ) return;
			} else 
			{
				if ( reactivate ) _currLoop = _loops;
				if ( _soundChannel ) _soundChannel.stop();
				_soundChannel = null;
				return;
			}
 
			// updates the sound panning.
			var pan:Number = _position.x / (radius );
			if ( pan > 1 ) pan = 1 else if ( pan < -1 ) pan = -1;
 
			// update the sound and smooth interpolate the values.
			_soundTransform.volume += ( volume - _soundTransform.volume ) * smooth;
			_soundTransform.pan += ( pan - _soundTransform.pan ) * smooth;
 
			_soundChannel.soundTransform = _soundTransform;
		}
	}
}
blog comments powered by Disqus