PositionalAudio.js 2.5 KB

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