PositionalAudio.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. import { Vector3 } from '../math/Vector3.js';
  5. import { Quaternion } from '../math/Quaternion.js';
  6. import { Audio } from './Audio.js';
  7. import { Object3D } from '../core/Object3D.js';
  8. const _position = new Vector3();
  9. const _quaternion = new Quaternion();
  10. const _scale = new Vector3();
  11. const _orientation = new Vector3();
  12. function PositionalAudio( listener ) {
  13. Audio.call( this, listener );
  14. this.panner = this.context.createPanner();
  15. this.panner.panningModel = 'HRTF';
  16. this.panner.connect( this.gain );
  17. }
  18. PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
  19. constructor: PositionalAudio,
  20. getOutput: function () {
  21. return this.panner;
  22. },
  23. getRefDistance: function () {
  24. return this.panner.refDistance;
  25. },
  26. setRefDistance: function ( value ) {
  27. this.panner.refDistance = value;
  28. return this;
  29. },
  30. getRolloffFactor: function () {
  31. return this.panner.rolloffFactor;
  32. },
  33. setRolloffFactor: function ( value ) {
  34. this.panner.rolloffFactor = value;
  35. return this;
  36. },
  37. getDistanceModel: function () {
  38. return this.panner.distanceModel;
  39. },
  40. setDistanceModel: function ( value ) {
  41. this.panner.distanceModel = value;
  42. return this;
  43. },
  44. getMaxDistance: function () {
  45. return this.panner.maxDistance;
  46. },
  47. setMaxDistance: function ( value ) {
  48. this.panner.maxDistance = value;
  49. return this;
  50. },
  51. setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
  52. this.panner.coneInnerAngle = coneInnerAngle;
  53. this.panner.coneOuterAngle = coneOuterAngle;
  54. this.panner.coneOuterGain = coneOuterGain;
  55. return this;
  56. },
  57. updateMatrixWorld: function ( force ) {
  58. Object3D.prototype.updateMatrixWorld.call( this, force );
  59. if ( this.hasPlaybackControl === true && this.isPlaying === false ) return;
  60. this.matrixWorld.decompose( _position, _quaternion, _scale );
  61. _orientation.set( 0, 0, 1 ).applyQuaternion( _quaternion );
  62. const panner = this.panner;
  63. if ( panner.positionX ) {
  64. // code path for Chrome and Firefox (see #14393)
  65. const endTime = this.context.currentTime + this.listener.timeDelta;
  66. panner.positionX.linearRampToValueAtTime( _position.x, endTime );
  67. panner.positionY.linearRampToValueAtTime( _position.y, endTime );
  68. panner.positionZ.linearRampToValueAtTime( _position.z, endTime );
  69. panner.orientationX.linearRampToValueAtTime( _orientation.x, endTime );
  70. panner.orientationY.linearRampToValueAtTime( _orientation.y, endTime );
  71. panner.orientationZ.linearRampToValueAtTime( _orientation.z, endTime );
  72. } else {
  73. panner.setPosition( _position.x, _position.y, _position.z );
  74. panner.setOrientation( _orientation.x, _orientation.y, _orientation.z );
  75. }
  76. }
  77. } );
  78. export { PositionalAudio };