| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 | import {	BufferGeometry,	BufferAttribute,	LineBasicMaterial,	Line,	MathUtils} from '../../../build/three.module.js';class PositionalAudioHelper extends Line {	constructor( audio, range = 1, divisionsInnerAngle = 16, divisionsOuterAngle = 2 ) {		const geometry = new BufferGeometry();		const divisions = divisionsInnerAngle + divisionsOuterAngle * 2;		const positions = new Float32Array( ( divisions * 3 + 3 ) * 3 );		geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );		const materialInnerAngle = new LineBasicMaterial( { color: 0x00ff00 } );		const materialOuterAngle = new LineBasicMaterial( { color: 0xffff00 } );		super( geometry, [ materialOuterAngle, materialInnerAngle ] );		this.audio = audio;		this.range = range;		this.divisionsInnerAngle = divisionsInnerAngle;		this.divisionsOuterAngle = divisionsOuterAngle;		this.type = 'PositionalAudioHelper';		this.update();	}	update() {		const audio = this.audio;		const range = this.range;		const divisionsInnerAngle = this.divisionsInnerAngle;		const divisionsOuterAngle = this.divisionsOuterAngle;		const coneInnerAngle = MathUtils.degToRad( audio.panner.coneInnerAngle );		const coneOuterAngle = MathUtils.degToRad( audio.panner.coneOuterAngle );		const halfConeInnerAngle = coneInnerAngle / 2;		const halfConeOuterAngle = coneOuterAngle / 2;		let start = 0;		let count = 0;		let i;		let stride;		const geometry = this.geometry;		const positionAttribute = geometry.attributes.position;		geometry.clearGroups();		//		function generateSegment( from, to, divisions, materialIndex ) {			const step = ( to - from ) / divisions;			positionAttribute.setXYZ( start, 0, 0, 0 );			count ++;			for ( i = from; i < to; i += step ) {				stride = start + count;				positionAttribute.setXYZ( stride, Math.sin( i ) * range, 0, Math.cos( i ) * range );				positionAttribute.setXYZ( stride + 1, Math.sin( Math.min( i + step, to ) ) * range, 0, Math.cos( Math.min( i + step, to ) ) * range );				positionAttribute.setXYZ( stride + 2, 0, 0, 0 );				count += 3;			}			geometry.addGroup( start, count, materialIndex );			start += count;			count = 0;		}		//		generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 );		generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 );		generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 );		//		positionAttribute.needsUpdate = true;		if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false;	}	dispose() {		this.geometry.dispose();		this.material[ 0 ].dispose();		this.material[ 1 ].dispose();	}}export { PositionalAudioHelper };
 |