You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
2.8 KiB

6 months ago
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;