PositionalAudio.js 2.4 KB

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