Skip to content
This repository
Browse code

Added 3d sound support plus example.

Thanks to @mikaelemtinger ;)
  • Loading branch information...
commit 741575939264d39440ee595a1703589bd8cf31c7 1 parent 47d69fe
AlteredQualia alteredq authored
422 build/Three.js
215 additions, 207 deletions not shown
143 examples/js/CameraControl.js
... ... @@ -0,0 +1,143 @@
  1 +/**
  2 + * @author mrdoob / http://mrdoob.com/
  3 + * @author alteredq / http://alteredqualia.com/
  4 + * @author paulirish / http://paulirish.com/
  5 + */
  6 +
  7 +function bind( scope, fn ) {
  8 + return function () {
  9 + fn.apply( scope, arguments );
  10 + };
  11 +}
  12 +
  13 +CameraControlWASD = function ( camera, movement_speed, look_speed, nofly, look_vertical ) {
  14 +
  15 + this.movement_speed = movement_speed !== undefined ? movement_speed : 1.0;
  16 + this.look_speed = look_speed !== undefined ? look_speed : 0.005;
  17 +
  18 + this.nofly = nofly;
  19 + this.look_vertical = look_vertical;
  20 +
  21 + this.camera = camera;
  22 +
  23 + this.mouseX = 0;
  24 + this.mouseY = 0;
  25 +
  26 + this.lat = 0;
  27 + this.lon = 0;
  28 + this.phy = 0;
  29 + this.theta = 0;
  30 +
  31 + this.moveForward = false;
  32 + this.moveBackward = false;
  33 + this.moveLeft = false;
  34 + this.moveRight = false;
  35 +
  36 + this.windowHalfX = window.innerWidth / 2;
  37 + this.windowHalfY = window.innerHeight / 2;
  38 +
  39 + this.onDocumentMouseDown = function ( event ) {
  40 +
  41 + event.preventDefault();
  42 + event.stopPropagation();
  43 +
  44 + switch ( event.button ) {
  45 +
  46 + case 0: this.moveForward = true; break;
  47 + case 2: this.moveBackward = true; break;
  48 +
  49 + }
  50 +
  51 + };
  52 +
  53 + this.onDocumentMouseUp = function ( event ) {
  54 +
  55 + event.preventDefault();
  56 + event.stopPropagation();
  57 +
  58 + switch ( event.button ) {
  59 +
  60 + case 0: this.moveForward = false; break;
  61 + case 2: this.moveBackward = false; break;
  62 +
  63 + }
  64 +
  65 + };
  66 +
  67 + this.onDocumentMouseMove = function (event) {
  68 +
  69 + this.mouseX = event.clientX - this.windowHalfX;
  70 + this.mouseY = event.clientY - this.windowHalfY;
  71 +
  72 + };
  73 +
  74 + this.onDocumentKeyDown = function ( event ) {
  75 +
  76 + switch( event.keyCode ) {
  77 +
  78 + case 38: /*up*/
  79 + case 87: /*W*/ this.moveForward = true; break;
  80 +
  81 + case 37: /*left*/
  82 + case 65: /*A*/ this.moveLeft = true; break;
  83 +
  84 + case 40: /*down*/
  85 + case 83: /*S*/ this.moveBackward = true; break;
  86 +
  87 + case 39: /*right*/
  88 + case 68: /*D*/ this.moveRight = true; break;
  89 +
  90 + }
  91 +
  92 + };
  93 +
  94 + this.onDocumentKeyUp = function ( event ) {
  95 +
  96 + switch( event.keyCode ) {
  97 +
  98 + case 38: /*up*/
  99 + case 87: /*W*/ this.moveForward = false; break;
  100 +
  101 + case 37: /*left*/
  102 + case 65: /*A*/ this.moveLeft = false; break;
  103 +
  104 + case 40: /*down*/
  105 + case 83: /*S*/ this.moveBackward = false; break;
  106 +
  107 + case 39: /*right*/
  108 + case 68: /*D*/ this.moveRight = false; break;
  109 +
  110 + }
  111 +
  112 + };
  113 +
  114 + this.update = function() {
  115 +
  116 + if ( this.moveForward ) this.camera.translateZ( - this.movement_speed, this.nofly );
  117 + if ( this.moveBackward ) this.camera.translateZ( this.movement_speed, this.nofly );
  118 + if ( this.moveLeft ) this.camera.translateX( - this.movement_speed, this.nofly );
  119 + if ( this.moveRight ) this.camera.translateX( this.movement_speed, this.nofly );
  120 +
  121 + this.lon += this.mouseX * this.look_speed;
  122 + if( this.look_vertical ) this.lat -= this.mouseY * this.look_speed;
  123 +
  124 + this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
  125 + this.phi = ( 90 - this.lat ) * Math.PI / 180;
  126 + this.theta = this.lon * Math.PI / 180;
  127 +
  128 + this.camera.target.position.x = 100 * Math.sin( this.phi ) * Math.cos( this.theta ) + this.camera.position.x;
  129 + this.camera.target.position.y = 100 * Math.cos( this.phi ) + this.camera.position.y;
  130 + this.camera.target.position.z = 100 * Math.sin( this.phi ) * Math.sin( this.theta ) + this.camera.position.z;
  131 +
  132 + };
  133 +
  134 +
  135 + document.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
  136 +
  137 + document.addEventListener( 'mousemove', bind( this, this.onDocumentMouseMove ), false );
  138 + document.addEventListener( 'mousedown', bind( this, this.onDocumentMouseDown ), false );
  139 + document.addEventListener( 'mouseup', bind( this, this.onDocumentMouseUp ), false );
  140 + document.addEventListener( 'keydown', bind( this, this.onDocumentKeyDown ), false );
  141 + document.addEventListener( 'keyup', bind( this, this.onDocumentKeyUp ), false );
  142 +
  143 +};
285 examples/misc_sound.html
... ... @@ -0,0 +1,285 @@
  1 +<!DOCTYPE HTML>
  2 +<html lang="en">
  3 + <head>
  4 + <title>three.js - misc - sound</title>
  5 + <meta charset="utf-8">
  6 + <style type="text/css">
  7 + body {
  8 + background-color: #000000;
  9 + margin: 0px;
  10 + overflow: hidden;
  11 + font-family:Monospace;
  12 + font-size:13px;
  13 + text-align:center;
  14 + font-weight: bold;
  15 + text-align:center;
  16 + }
  17 +
  18 + a {
  19 + color:#0078ff;
  20 + }
  21 +
  22 + #info {
  23 + color:#fff;
  24 + position: absolute;
  25 + top: 0px; width: 100%;
  26 + padding: 5px;
  27 + z-index:100;
  28 + }
  29 + </style>
  30 + </head>
  31 + <body>
  32 +
  33 + <div id="info">
  34 + <a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - webgl 3d sounds example -
  35 + music by <a href="http://www.newgrounds.com/audio/listen/358232" target="_blank">larrylarrybb</a> and
  36 + <a href="http://www.newgrounds.com/audio/listen/376737" target="_blank">skullbeatz</a> <br/><br/>
  37 +
  38 + navigate with WASD / arrows / mouse
  39 + </div>
  40 +
  41 +
  42 + <div id="container"></div>
  43 +
  44 + <script type="text/javascript" src="js/ThreeSound.js"></script>
  45 +
  46 + <script type="text/javascript" src="js/CameraControl.js"></script>
  47 + <script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
  48 + <script type="text/javascript" src="js/Detector.js"></script>
  49 + <script type="text/javascript" src="js/Stats.js"></script>
  50 +
  51 + <script type="text/javascript">
  52 +
  53 + if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
  54 +
  55 + var container, stats;
  56 + var camera, scene, renderer, soundRenderer;
  57 + var light, pointLight;
  58 + var cameraControl;
  59 +
  60 + var mesh;
  61 + var material_sphere1, material_sphere2;
  62 +
  63 + var postprocessing = { enabled: true };
  64 +
  65 + init();
  66 + animate();
  67 +
  68 + function init() {
  69 +
  70 + container = document.getElementById( 'container' );
  71 +
  72 + scene = new THREE.Scene();
  73 + scene.fog = new THREE.FogExp2( 0x000000, 0.0035 );
  74 +
  75 + camera = new THREE.Camera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
  76 + camera.position.set( 0, 25, 0 );
  77 +
  78 + light = new THREE.DirectionalLight( 0xffffff );
  79 + light.position.set( 0, 0.5, 1 );
  80 + light.position.normalize();
  81 + scene.addLight( light );
  82 +
  83 + var sphere = new Sphere( 20, 32, 16 );
  84 +
  85 + material_sphere1 = new THREE.MeshLambertMaterial( { color: 0xffaa00, shading: THREE.FlatShading } );
  86 + material_sphere2 = new THREE.MeshLambertMaterial( { color: 0xff2200, shading: THREE.FlatShading } );
  87 +
  88 + var cube = new Cube( 5, 40, 5 );
  89 + var material_cube = new THREE.MeshLambertMaterial( { color: 0xffff00, shading: THREE.FlatShading } );
  90 + material_cube.color.setHSV( 0.1, 0.7, 1 );
  91 +
  92 + // sound spheres
  93 +
  94 + var s = 1;
  95 +
  96 + var mesh1 = new THREE.Mesh( sphere, material_sphere1 );
  97 + mesh1.position.set( -250, 30, 0 );
  98 + mesh1.scale.set( s, s, s );
  99 +
  100 + var sound1 = new THREE.Sound3D( [ "sounds/358232_j_s_song.mp3", "sounds/358232_j_s_song.ogg" ] , 275, 20, true );
  101 + //var sound1 = new THREE.Sound3D( "sounds/358232_j_s_song.ogg", 275, 20, true );
  102 + sound1.play();
  103 +
  104 + var dbg = new THREE.Mesh( cube, material_cube );
  105 + dbg.position.set( 0, -10 ,0 );
  106 + mesh1.addChild( dbg );
  107 +
  108 + mesh1.addChild( sound1 );
  109 + scene.addObject( mesh1 );
  110 +
  111 +
  112 + var mesh2 = new THREE.Mesh( sphere, material_sphere2 );
  113 + mesh2.position.set( 250, 30, 0 );
  114 + mesh2.scale.set( s, s, s );
  115 +
  116 + var sound2 = new THREE.Sound3D( [ "sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3", "sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg" ], 275, 20, true );
  117 + //var sound2 = new THREE.Sound3D( "sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg", 275, 20, true );
  118 + sound2.play();
  119 +
  120 + var dbg = new THREE.Mesh( cube, material_cube );
  121 + dbg.position.set( 0, -10, 0 );
  122 + mesh2.addChild( dbg );
  123 +
  124 + mesh2.addChild( sound2 );
  125 + scene.addObject( mesh2 );
  126 +
  127 + // ground
  128 +
  129 + var material_wireframe = new THREE.MeshLambertMaterial( { color: 0xffaa00, wireframe: true, wireframe_linewidth: 1 } );
  130 + material_wireframe.color.setHSV( 0.1, 0.2, 0.25 );
  131 +
  132 +
  133 + var plane = new Plane( 1000, 1000, 100, 100 );
  134 + mesh = new THREE.Mesh( plane, material_wireframe );
  135 + mesh.position.y = 0.1;
  136 + mesh.rotation.x = -1.57;
  137 + scene.addObject( mesh );
  138 +
  139 +
  140 + renderer = new THREE.WebGLRenderer( { clearColor: 0x000000, clearAlpha: 1 } );
  141 + renderer.setSize( window.innerWidth, window.innerHeight );
  142 +
  143 + soundRenderer = new THREE.SoundRenderer();
  144 +
  145 + container.innerHTML = "";
  146 + container.appendChild( renderer.domElement );
  147 + container.appendChild( soundRenderer.domElement );
  148 +
  149 + stats = new Stats();
  150 + stats.domElement.style.position = 'absolute';
  151 + stats.domElement.style.top = '0px';
  152 + //container.appendChild( stats.domElement );
  153 +
  154 + cameraControl = new CameraControlWASD( camera, 1, 0.002, true, false );
  155 +
  156 + initPostprocessing();
  157 + renderer.autoClear = false;
  158 +
  159 + }
  160 +
  161 +
  162 + function initPostprocessing() {
  163 +
  164 + postprocessing.scene = new THREE.Scene();
  165 +
  166 + postprocessing.camera = new THREE.Camera();
  167 + postprocessing.camera.projectionMatrix = THREE.Matrix4.makeOrtho( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 );
  168 + postprocessing.camera.position.z = 100;
  169 +
  170 + var pars = { min_filter: THREE.LinearFilter, mag_filter: THREE.LinearFilter };
  171 + postprocessing.rtTexture1 = new THREE.RenderTarget( window.innerWidth, window.innerHeight, pars );
  172 + postprocessing.rtTexture2 = new THREE.RenderTarget( 512, 512, pars );
  173 + postprocessing.rtTexture3 = new THREE.RenderTarget( 512, 512, pars );
  174 +
  175 + var screen_shader = ShaderUtils.lib["screen"];
  176 + var screen_uniforms = Uniforms.clone( screen_shader.uniforms );
  177 +
  178 + screen_uniforms["tDiffuse"].texture = postprocessing.rtTexture1;
  179 + screen_uniforms["opacity"].value = 1.0;
  180 +
  181 + postprocessing.materialScreen = new THREE.MeshShaderMaterial( {
  182 +
  183 + uniforms: screen_uniforms,
  184 + vertex_shader: screen_shader.vertex_shader,
  185 + fragment_shader: screen_shader.fragment_shader,
  186 + blending: THREE.AdditiveBlending
  187 +
  188 + } );
  189 +
  190 + var convolution_shader = ShaderUtils.lib["convolution"];
  191 + var convolution_uniforms = Uniforms.clone( convolution_shader.uniforms );
  192 +
  193 + postprocessing.blurx = new THREE.Vector2( 0.001953125, 0.0 ),
  194 + postprocessing.blury = new THREE.Vector2( 0.0, 0.001953125 );
  195 +
  196 + convolution_uniforms["tDiffuse"].texture = postprocessing.rtTexture1;
  197 + convolution_uniforms["uImageIncrement"].value = postprocessing.blurx;
  198 + convolution_uniforms["cKernel"].value = ShaderUtils.buildKernel( 4.0 );
  199 +
  200 + postprocessing.materialConvolution = new THREE.MeshShaderMaterial( {
  201 +
  202 + uniforms: convolution_uniforms,
  203 + vertex_shader: "#define KERNEL_SIZE 25.0\n" + convolution_shader.vertex_shader,
  204 + fragment_shader: "#define KERNEL_SIZE 25\n" + convolution_shader.fragment_shader
  205 +
  206 + } );
  207 +
  208 + postprocessing.quad = new THREE.Mesh( new Plane( window.innerWidth, window.innerHeight ), postprocessing.materialConvolution );
  209 + postprocessing.quad.position.z = -500;
  210 + postprocessing.scene.addObject( postprocessing.quad );
  211 +
  212 + }
  213 +
  214 + function animate() {
  215 +
  216 + requestAnimationFrame( animate );
  217 +
  218 + render();
  219 + stats.update();
  220 +
  221 + }
  222 +
  223 +
  224 + function render() {
  225 +
  226 + var time = new Date().getTime() * 0.005;
  227 +
  228 + material_sphere1.color.setHSV( 0.0, 0.3 + 0.7 * ( 1 + Math.cos(time) ) / 2, 1 );
  229 + material_sphere2.color.setHSV( 0.1, 0.3 + 0.7 * ( 1 + Math.sin(time) ) / 2, 1 );
  230 +
  231 + cameraControl.update();
  232 +
  233 + if ( postprocessing.enabled ) {
  234 +
  235 + renderer.clear();
  236 +
  237 + // Render scene into texture
  238 +
  239 + renderer.render( scene, camera, postprocessing.rtTexture1 );
  240 +
  241 + // Render quad with blured scene into texture (convolution pass 1)
  242 +
  243 + postprocessing.quad.materials = [ postprocessing.materialConvolution ];
  244 +
  245 + postprocessing.materialConvolution.uniforms.tDiffuse.texture = postprocessing.rtTexture1;
  246 + postprocessing.materialConvolution.uniforms.uImageIncrement.value = postprocessing.blurx;
  247 +
  248 + renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTexture2 );
  249 +
  250 + // Render quad with blured scene into texture (convolution pass 2)
  251 +
  252 + postprocessing.materialConvolution.uniforms.tDiffuse.texture = postprocessing.rtTexture2;
  253 + postprocessing.materialConvolution.uniforms.uImageIncrement.value = postprocessing.blury;
  254 +
  255 + renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTexture3 );
  256 +
  257 + // Render original scene with superimposed blur to texture
  258 +
  259 + postprocessing.quad.materials = [ postprocessing.materialScreen ];
  260 +
  261 + postprocessing.materialScreen.uniforms.tDiffuse.texture = postprocessing.rtTexture3;
  262 + postprocessing.materialScreen.uniforms.opacity.value = 1.3;
  263 +
  264 + renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTexture1, false );
  265 +
  266 + // Render to screen
  267 +
  268 + postprocessing.materialScreen.uniforms.tDiffuse.texture = postprocessing.rtTexture1;
  269 + renderer.render( postprocessing.scene, postprocessing.camera );
  270 +
  271 + } else {
  272 +
  273 + renderer.clear();
  274 + renderer.render( scene, camera );
  275 +
  276 + }
  277 +
  278 + soundRenderer.render( scene, camera );
  279 +
  280 + }
  281 +
  282 + </script>
  283 +
  284 + </body>
  285 +</html>
BIN  examples/sounds/358232_j_s_song.mp3
Binary file not shown
BIN  examples/sounds/358232_j_s_song.ogg
Binary file not shown
BIN  examples/sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3
Binary file not shown
BIN  examples/sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg
Binary file not shown
8 examples/sounds/readme.txt
... ... @@ -0,0 +1,8 @@
  1 +Music from Newgrounds Audio portal, licensed under
  2 +Creative Commons Attribution Noncommercial Share Alike
  3 +
  4 +Bad Cat [Master Version] by Skullbeatz
  5 +http://www.newgrounds.com/audio/listen/376737
  6 +
  7 +The Sound of Epicness by larrylarrybb
  8 +http://www.newgrounds.com/audio/listen/358232
8 src/cameras/Camera.js
@@ -24,11 +24,13 @@ THREE.Camera = function( FOV, aspect, zNear, zFar, renderer, target ) {
24 24
25 25 this.tmpVec = new THREE.Vector3();
26 26
27   - this.translateX = function ( amount ) {
  27 + this.translateX = function ( amount, nofly ) {
28 28
29 29 this.tmpVec.sub( this.target.position, this.position ).normalize().multiplyScalar( amount );
30 30 this.tmpVec.crossSelf( this.up );
31 31
  32 + if ( nofly ) this.tmpVec.y = 0;
  33 +
32 34 this.position.addSelf( this.tmpVec );
33 35 this.target.position.addSelf( this.tmpVec );
34 36
@@ -40,10 +42,12 @@ THREE.Camera = function( FOV, aspect, zNear, zFar, renderer, target ) {
40 42 };
41 43 */
42 44
43   - this.translateZ = function ( amount ) {
  45 + this.translateZ = function ( amount, nofly ) {
44 46
45 47 this.tmpVec.sub( this.target.position, this.position ).normalize().multiplyScalar( amount );
46 48
  49 + if ( nofly ) this.tmpVec.y = 0;
  50 +
47 51 this.position.subSelf( this.tmpVec );
48 52 this.target.position.subSelf( this.tmpVec );
49 53
8 src/core/Matrix4.js
@@ -591,6 +591,14 @@ THREE.Matrix4.prototype = {
591 591
592 592 },
593 593
  594 + extractPositionVector: function( v ) {
  595 +
  596 + v.x = this.n14;
  597 + v.y = this.n24;
  598 + v.z = this.n34;
  599 +
  600 + },
  601 +
594 602 toString: function() {
595 603
596 604 return "| " + this.n11 + " " + this.n12 + " " + this.n13 + " " + this.n14 + " |\n" +
201 src/objects/Sound3D.js
... ... @@ -0,0 +1,201 @@
  1 +/**
  2 + * @author mikael emtinger / http://gomo.se/
  3 + */
  4 +
  5 +THREE.Sound3D = function( sources, radius, volume, loop ) {
  6 +
  7 + THREE.Object3D.call( this );
  8 +
  9 + // flags
  10 +
  11 + this.isLoaded = false;
  12 + this.isAddedToDOM = false;
  13 + this.isPlaying = false;
  14 + this.duration = -1;
  15 + this.radius = radius !== undefined ? Math.abs( radius ) : 100;
  16 + this.volume = Math.min( 1, Math.max( 0, volume !== undefined ? volume : 1 ) );
  17 +
  18 +
  19 + // dom
  20 +
  21 + this.domElement = document.createElement( "audio" );
  22 + this.domElement.volume = 0;
  23 + this.domElement.pan = 0;
  24 + this.domElement.loop = loop !== undefined ? loop : true;
  25 +
  26 +
  27 + // init sources
  28 +
  29 + this.sources = sources instanceof Array ? sources : [ sources ];
  30 +
  31 + var element, source, type,
  32 + s, sl = this.sources.length;
  33 +
  34 + for( s = 0; s < sl; s++ ) {
  35 +
  36 + source = this.sources[ s ];
  37 + source.toLowerCase();
  38 +
  39 + if( source.indexOf( ".mp3" ) !== -1 ) type = "audio/mpeg";
  40 + else if( source.indexOf( ".ogg" ) !== -1 ) type = "audio/ogg";
  41 + else if( source.indexOf( ".wav" ) !== -1 ) type = "audio/wav";
  42 +
  43 + if( this.domElement.canPlayType( type ) ) {
  44 +
  45 + element = document.createElement( "source" );
  46 + element.src = this.sources[ s ];
  47 +
  48 + this.domElement.THREESound3D = this;
  49 + this.domElement.appendChild( element );
  50 + this.domElement.addEventListener( "canplay", this.onLoad, true );
  51 + this.domElement.load();
  52 +
  53 + break;
  54 +
  55 + }
  56 +
  57 + }
  58 +
  59 +};
  60 +
  61 +
  62 +THREE.Sound3D.prototype = new THREE.Object3D();
  63 +THREE.Sound3D.prototype.constructor = THREE.Sound3D;
  64 +THREE.Sound3D.prototype.supr = THREE.Object3D.prototype;
  65 +
  66 +
  67 +/*
  68 + * OnLoad
  69 + */
  70 +
  71 +THREE.Sound3D.prototype.onLoad = function( ) {
  72 +
  73 + var sound3D = this.THREESound3D;
  74 +
  75 + if( sound3D.isLoaded )
  76 + return;
  77 +
  78 + this.removeEventListener( "canplay", this.onLoad, true );
  79 +
  80 + sound3D.isLoaded = true;
  81 + sound3D.duration = this.duration;
  82 +
  83 + if( sound3D.isPlaying )
  84 + sound3D.play();
  85 +
  86 +};
  87 +
  88 +/*
  89 + * Add To DOM
  90 + */
  91 +
  92 +THREE.Sound3D.prototype.addToDOM = function( parent ) {
  93 +
  94 + this.isAddedToDOM = true;
  95 + parent.appendChild( this.domElement );
  96 +
  97 +};
  98 +
  99 +
  100 +/*
  101 + * Play
  102 + */
  103 +
  104 +THREE.Sound3D.prototype.play = function( startTime ) {
  105 +
  106 + this.isPlaying = true;
  107 +
  108 + if( this.isLoaded ) {
  109 +
  110 + this.domElement.play();
  111 +
  112 + if( startTime )
  113 + this.domElement.currentTime = startTime % this.duration;
  114 +
  115 + }
  116 +
  117 +};
  118 +
  119 +
  120 +/*
  121 + * Pause
  122 + */
  123 +
  124 +THREE.Sound3D.prototype.pause = function() {
  125 +
  126 + this.isPlaying = false;
  127 + this.domElement.pause();
  128 +
  129 +};
  130 +
  131 +
  132 +/*
  133 + * Stop
  134 + */
  135 +
  136 +THREE.Sound3D.prototype.stop = function(){
  137 +
  138 + this.isPlaying = false;
  139 + this.domElement.pause();
  140 + this.domElement.currentTime = 0;
  141 +
  142 +};
  143 +
  144 +/*
  145 + * Calculate Volume and Pan
  146 + */
  147 +
  148 +THREE.Sound3D.prototype.calculateVolumeAndPan = function( cameraRelativePosition ) {
  149 +
  150 + var distance = cameraRelativePosition.length();
  151 +
  152 + if( distance <= this.radius )
  153 + this.domElement.volume = this.volume * ( 1 - distance / this.radius );
  154 + else
  155 + this.domElement.volume = 0;
  156 +
  157 +};
  158 +
  159 +
  160 +/*
  161 + * Update
  162 + */
  163 +
  164 +THREE.Sound3D.prototype.update = function( parentGlobalMatrix, forceUpdate, camera ) {
  165 +
  166 + // update local (rotation/scale is not used)
  167 +
  168 + if( this.matrixAutoUpdate ) {
  169 +
  170 + this.localMatrix.setPosition( this.position );
  171 + forceUpdate = true;
  172 +
  173 + }
  174 +
  175 +
  176 + // update global
  177 +
  178 + if( forceUpdate || this.matrixNeedsUpdate ) {
  179 +
  180 + if( parentGlobalMatrix )
  181 + this.globalMatrix.multiply( parentGlobalMatrix, this.localMatrix );
  182 + else
  183 + this.globalMatrix.copy( this.localMatrix );
  184 +
  185 + this.matrixNeedsUpdate = false;
  186 + forceUpdate = true;
  187 +
  188 + }
  189 +
  190 +
  191 + // update children
  192 +
  193 + var i, l = this.children.length;
  194 +
  195 + for( i = 0; i < l; i++ )
  196 + this.children[ i ].update( this.globalMatrix, forceUpdate, camera );
  197 +
  198 +};
  199 +
  200 +
  201 +
53 src/renderers/SoundRenderer.js
... ... @@ -0,0 +1,53 @@
  1 +/**
  2 + * @author mikael emtinger / http://gomo.se/
  3 + */
  4 +
  5 +
  6 +THREE.SoundRenderer = function() {
  7 +
  8 + this.volume = 1;
  9 + this.domElement = document.createElement( "div" );
  10 + this.domElement.id = "THREESound";
  11 +
  12 + this.cameraPosition = new THREE.Vector3();
  13 + this.soundPosition = new THREE.Vector3();
  14 +
  15 + /*
  16 + * Render
  17 + */
  18 +
  19 + this.render = function( scene, camera, callSceneUpdate ) {
  20 +
  21 + if( callSceneUpdate )
  22 + scene.update( undefined, false, camera );
  23 +
  24 +
  25 + // loop through all sounds
  26 +
  27 + var sound;
  28 + var sounds = scene.sounds;
  29 + var s, l = sounds.length;
  30 +
  31 + //camera.globalMatrix.extractPositionVector( this.cameraPosition );
  32 +
  33 + for( s = 0; s < l; s++ ) {
  34 +
  35 + sound = sounds[ s ];
  36 +
  37 + sound.globalMatrix.extractPositionVector( this.soundPosition );
  38 + this.soundPosition.subSelf( camera.position );
  39 +
  40 + if( sound.isPlaying && sound.isLoaded ) {
  41 +
  42 + if( !sound.isAddedToDOM )
  43 + sound.addToDOM( this.domElement );
  44 +
  45 + sound.calculateVolumeAndPan( this.soundPosition );
  46 +
  47 + }
  48 +
  49 + }
  50 +
  51 + }
  52 +
  53 +}
14 src/scenes/Scene.js
@@ -13,6 +13,7 @@ THREE.Scene = function() {
13 13
14 14 this.objects = [];
15 15 this.lights = [];
  16 + this.sounds = [];
16 17 this.fog = null;
17 18
18 19 };
@@ -34,12 +35,16 @@ THREE.Scene.prototype.addChild = function( child ) {
34 35
35 36 THREE.Scene.prototype.addChildRecurse = function( child ) {
36 37
37   -
38 38 if( child instanceof THREE.Light ) {
39 39
40 40 if( this.lights.indexOf( child ) === -1 )
41 41 this.lights.push( child );
42 42
  43 + } else if( child instanceof THREE.Sound3D ) {
  44 +
  45 + if( this.sounds.indexOf( child ) === -1 )
  46 + this.sounds.push( child );
  47 +
43 48 } else if( !( child instanceof THREE.Camera || child instanceof THREE.Bone ) ) {
44 49
45 50 if( this.objects.indexOf( child ) === -1 )
@@ -73,6 +78,13 @@ THREE.Scene.prototype.removeChildRecurse = function( child ) {
73 78 if( i !== -1 )
74 79 this.lights.splice( i, 1 );
75 80
  81 + } else if( child instanceof THREE.Sound3D ) {
  82 +
  83 + var i = this.sounds.indexOf( child );
  84 +
  85 + if( i !== -1 )
  86 + this.sounds.splice( i, 1 );
  87 +
76 88 } else if( !( child instanceof THREE.Camera ) ) {
77 89
78 90 var i = this.objects.indexOf( child );
2  utils/build.py
@@ -64,6 +64,7 @@
64 64 'objects/Bone.js',
65 65 'objects/SkinnedMesh.js',
66 66 'objects/Ribbon.js',
  67 +'objects/Sound3D.js',
67 68 'scenes/Scene.js',
68 69 'scenes/Fog.js',
69 70 'scenes/FogExp2.js',
@@ -72,6 +73,7 @@
72 73 'renderers/CanvasRenderer.js',
73 74 'renderers/SVGRenderer.js',
74 75 'renderers/WebGLRenderer.js',
  76 +'renderers/SoundRenderer.js',
75 77 'renderers/renderables/RenderableObject.js',
76 78 'renderers/renderables/RenderableFace3.js',
77 79 'renderers/renderables/RenderableParticle.js',

0 comments on commit 7415759

Please sign in to comment.
Something went wrong with that request. Please try again.