SphereBufferGeometry.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { BufferGeometry } from '../core/BufferGeometry';
  2. import { Vector3 } from '../math/Vector3';
  3. import { Sphere } from '../math/Sphere';
  4. import { Uint16Attribute, Uint32Attribute, BufferAttribute } from '../core/BufferAttribute';
  5. /**
  6. * @author benaadams / https://twitter.com/ben_a_adams
  7. * based on THREE.SphereGeometry
  8. */
  9. function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
  10. BufferGeometry.call( this );
  11. this.type = 'SphereBufferGeometry';
  12. this.parameters = {
  13. radius: radius,
  14. widthSegments: widthSegments,
  15. heightSegments: heightSegments,
  16. phiStart: phiStart,
  17. phiLength: phiLength,
  18. thetaStart: thetaStart,
  19. thetaLength: thetaLength
  20. };
  21. radius = radius || 50;
  22. widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
  23. heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
  24. phiStart = phiStart !== undefined ? phiStart : 0;
  25. phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
  26. thetaStart = thetaStart !== undefined ? thetaStart : 0;
  27. thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
  28. var thetaEnd = thetaStart + thetaLength;
  29. var vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );
  30. var positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );
  31. var normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );
  32. var uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );
  33. var index = 0, vertices = [], normal = new Vector3();
  34. for ( var y = 0; y <= heightSegments; y ++ ) {
  35. var verticesRow = [];
  36. var v = y / heightSegments;
  37. for ( var x = 0; x <= widthSegments; x ++ ) {
  38. var u = x / widthSegments;
  39. var px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
  40. var py = radius * Math.cos( thetaStart + v * thetaLength );
  41. var pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
  42. normal.set( px, py, pz ).normalize();
  43. positions.setXYZ( index, px, py, pz );
  44. normals.setXYZ( index, normal.x, normal.y, normal.z );
  45. uvs.setXY( index, u, 1 - v );
  46. verticesRow.push( index );
  47. index ++;
  48. }
  49. vertices.push( verticesRow );
  50. }
  51. var indices = [];
  52. for ( var y = 0; y < heightSegments; y ++ ) {
  53. for ( var x = 0; x < widthSegments; x ++ ) {
  54. var v1 = vertices[ y ][ x + 1 ];
  55. var v2 = vertices[ y ][ x ];
  56. var v3 = vertices[ y + 1 ][ x ];
  57. var v4 = vertices[ y + 1 ][ x + 1 ];
  58. if ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );
  59. if ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );
  60. }
  61. }
  62. this.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );
  63. this.addAttribute( 'position', positions );
  64. this.addAttribute( 'normal', normals );
  65. this.addAttribute( 'uv', uvs );
  66. this.boundingSphere = new Sphere( new Vector3(), radius );
  67. }
  68. SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  69. SphereBufferGeometry.prototype.constructor = SphereBufferGeometry;
  70. export { SphereBufferGeometry };
粤ICP备19079148号