175 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			175 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import { | ||
|  | 	Box3, | ||
|  | 	Float32BufferAttribute, | ||
|  | 	InstancedBufferGeometry, | ||
|  | 	InstancedBufferAttribute, | ||
|  | 	Sphere, | ||
|  | 	Vector3 | ||
|  | } from 'three'; | ||
|  | 
 | ||
|  | const _vector = new Vector3(); | ||
|  | 
 | ||
|  | class InstancedPointsGeometry extends InstancedBufferGeometry { | ||
|  | 
 | ||
|  | 	constructor() { | ||
|  | 
 | ||
|  | 		super(); | ||
|  | 
 | ||
|  | 		this.isInstancedPointsGeometry = true; | ||
|  | 
 | ||
|  | 		this.type = 'InstancedPointsGeometry'; | ||
|  | 
 | ||
|  | 		const positions = [ - 1, 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ]; | ||
|  | 		const uvs = [ - 1, 1, 1, 1, - 1, - 1, 1, - 1 ]; | ||
|  | 		const index = [ 0, 2, 1, 2, 3, 1 ]; | ||
|  | 
 | ||
|  | 		this.setIndex( index ); | ||
|  | 		this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); | ||
|  | 		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	applyMatrix4( matrix ) { | ||
|  | 
 | ||
|  | 		const pos = this.attributes.instancePosition; | ||
|  | 
 | ||
|  | 		if ( pos !== undefined ) { | ||
|  | 
 | ||
|  | 			pos.applyMatrix4( matrix ); | ||
|  | 
 | ||
|  | 			pos.needsUpdate = true; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( this.boundingBox !== null ) { | ||
|  | 
 | ||
|  | 			this.computeBoundingBox(); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( this.boundingSphere !== null ) { | ||
|  | 
 | ||
|  | 			this.computeBoundingSphere(); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return this; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	setPositions( array ) { | ||
|  | 
 | ||
|  | 		let points; | ||
|  | 
 | ||
|  | 		if ( array instanceof Float32Array ) { | ||
|  | 
 | ||
|  | 			points = array; | ||
|  | 
 | ||
|  | 		} else if ( Array.isArray( array ) ) { | ||
|  | 
 | ||
|  | 			points = new Float32Array( array ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		this.setAttribute( 'instancePosition', new InstancedBufferAttribute( points, 3 ) ); // xyz
 | ||
|  | 
 | ||
|  | 		//
 | ||
|  | 
 | ||
|  | 		this.computeBoundingBox(); | ||
|  | 		this.computeBoundingSphere(); | ||
|  | 
 | ||
|  | 		return this; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	setColors( array ) { | ||
|  | 
 | ||
|  | 		let colors; | ||
|  | 
 | ||
|  | 		if ( array instanceof Float32Array ) { | ||
|  | 
 | ||
|  | 			colors = array; | ||
|  | 
 | ||
|  | 		} else if ( Array.isArray( array ) ) { | ||
|  | 
 | ||
|  | 			colors = new Float32Array( array ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		this.setAttribute( 'instanceColor', new InstancedBufferAttribute( colors, 3 ) ); // rgb
 | ||
|  | 
 | ||
|  | 		return this; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	computeBoundingBox() { | ||
|  | 
 | ||
|  | 		if ( this.boundingBox === null ) { | ||
|  | 
 | ||
|  | 			this.boundingBox = new Box3(); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		const pos = this.attributes.instancePosition; | ||
|  | 
 | ||
|  | 		if ( pos !== undefined ) { | ||
|  | 
 | ||
|  | 			this.boundingBox.setFromBufferAttribute( pos ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	computeBoundingSphere() { | ||
|  | 
 | ||
|  | 		if ( this.boundingSphere === null ) { | ||
|  | 
 | ||
|  | 			this.boundingSphere = new Sphere(); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( this.boundingBox === null ) { | ||
|  | 
 | ||
|  | 			this.computeBoundingBox(); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		const pos = this.attributes.instancePosition; | ||
|  | 
 | ||
|  | 		if ( pos !== undefined ) { | ||
|  | 
 | ||
|  | 			const center = this.boundingSphere.center; | ||
|  | 
 | ||
|  | 			this.boundingBox.getCenter( center ); | ||
|  | 
 | ||
|  | 			let maxRadiusSq = 0; | ||
|  | 
 | ||
|  | 			for ( let i = 0, il = pos.count; i < il; i ++ ) { | ||
|  | 
 | ||
|  | 				_vector.fromBufferAttribute( pos, i ); | ||
|  | 				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) ); | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 			this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); | ||
|  | 
 | ||
|  | 			if ( isNaN( this.boundingSphere.radius ) ) { | ||
|  | 
 | ||
|  | 				console.error( 'THREE.InstancedPointsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this ); | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	toJSON() { | ||
|  | 
 | ||
|  | 		// todo
 | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | export default InstancedPointsGeometry; |