InstancedPointsGeometry.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import {
  2. Box3,
  3. Float32BufferAttribute,
  4. InstancedBufferGeometry,
  5. InstancedBufferAttribute,
  6. Sphere,
  7. Vector3
  8. } from 'three';
  9. const _vector = new Vector3();
  10. class InstancedPointsGeometry extends InstancedBufferGeometry {
  11. constructor() {
  12. super();
  13. this.isInstancedPointsGeometry = true;
  14. this.type = 'InstancedPointsGeometry';
  15. const positions = [ - 1, 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
  16. const uvs = [ 0, 1, 1, 1, 0, 0, 1, 0 ];
  17. const index = [ 0, 2, 1, 2, 3, 1 ];
  18. this.setIndex( index );
  19. this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
  20. this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  21. }
  22. applyMatrix4( matrix ) {
  23. const pos = this.attributes.instancePosition;
  24. if ( pos !== undefined ) {
  25. pos.applyMatrix4( matrix );
  26. pos.needsUpdate = true;
  27. }
  28. if ( this.boundingBox !== null ) {
  29. this.computeBoundingBox();
  30. }
  31. if ( this.boundingSphere !== null ) {
  32. this.computeBoundingSphere();
  33. }
  34. return this;
  35. }
  36. setPositions( array ) {
  37. let points;
  38. if ( array instanceof Float32Array ) {
  39. points = array;
  40. } else if ( Array.isArray( array ) ) {
  41. points = new Float32Array( array );
  42. }
  43. this.setAttribute( 'instancePosition', new InstancedBufferAttribute( points, 3 ) ); // xyz
  44. //
  45. this.computeBoundingBox();
  46. this.computeBoundingSphere();
  47. return this;
  48. }
  49. setColors( array ) {
  50. let colors;
  51. if ( array instanceof Float32Array ) {
  52. colors = array;
  53. } else if ( Array.isArray( array ) ) {
  54. colors = new Float32Array( array );
  55. }
  56. this.setAttribute( 'instanceColor', new InstancedBufferAttribute( colors, 3 ) ); // rgb
  57. return this;
  58. }
  59. computeBoundingBox() {
  60. if ( this.boundingBox === null ) {
  61. this.boundingBox = new Box3();
  62. }
  63. const pos = this.attributes.instancePosition;
  64. if ( pos !== undefined ) {
  65. this.boundingBox.setFromBufferAttribute( pos );
  66. }
  67. }
  68. computeBoundingSphere() {
  69. if ( this.boundingSphere === null ) {
  70. this.boundingSphere = new Sphere();
  71. }
  72. if ( this.boundingBox === null ) {
  73. this.computeBoundingBox();
  74. }
  75. const pos = this.attributes.instancePosition;
  76. if ( pos !== undefined ) {
  77. const center = this.boundingSphere.center;
  78. this.boundingBox.getCenter( center );
  79. let maxRadiusSq = 0;
  80. for ( let i = 0, il = pos.count; i < il; i ++ ) {
  81. _vector.fromBufferAttribute( pos, i );
  82. maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
  83. }
  84. this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
  85. if ( isNaN( this.boundingSphere.radius ) ) {
  86. console.error( 'THREE.InstancedPointsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
  87. }
  88. }
  89. }
  90. toJSON() {
  91. // todo
  92. }
  93. }
  94. export default InstancedPointsGeometry;