RingGeometry.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { BufferGeometry } from '../core/BufferGeometry.js';
  2. import { Float32BufferAttribute } from '../core/BufferAttribute.js';
  3. import { Vector2 } from '../math/Vector2.js';
  4. import { Vector3 } from '../math/Vector3.js';
  5. class RingGeometry extends BufferGeometry {
  6. constructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) {
  7. super();
  8. this.type = 'RingGeometry';
  9. this.parameters = {
  10. innerRadius: innerRadius,
  11. outerRadius: outerRadius,
  12. thetaSegments: thetaSegments,
  13. phiSegments: phiSegments,
  14. thetaStart: thetaStart,
  15. thetaLength: thetaLength
  16. };
  17. thetaSegments = Math.max( 3, thetaSegments );
  18. phiSegments = Math.max( 1, phiSegments );
  19. // buffers
  20. const indices = [];
  21. const vertices = [];
  22. const normals = [];
  23. const uvs = [];
  24. // some helper variables
  25. let radius = innerRadius;
  26. const radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
  27. const vertex = new Vector3();
  28. const uv = new Vector2();
  29. // generate vertices, normals and uvs
  30. for ( let j = 0; j <= phiSegments; j ++ ) {
  31. for ( let i = 0; i <= thetaSegments; i ++ ) {
  32. // values are generate from the inside of the ring to the outside
  33. const segment = thetaStart + i / thetaSegments * thetaLength;
  34. // vertex
  35. vertex.x = radius * Math.cos( segment );
  36. vertex.y = radius * Math.sin( segment );
  37. vertices.push( vertex.x, vertex.y, vertex.z );
  38. // normal
  39. normals.push( 0, 0, 1 );
  40. // uv
  41. uv.x = ( vertex.x / outerRadius + 1 ) / 2;
  42. uv.y = ( vertex.y / outerRadius + 1 ) / 2;
  43. uvs.push( uv.x, uv.y );
  44. }
  45. // increase the radius for next row of vertices
  46. radius += radiusStep;
  47. }
  48. // indices
  49. for ( let j = 0; j < phiSegments; j ++ ) {
  50. const thetaSegmentLevel = j * ( thetaSegments + 1 );
  51. for ( let i = 0; i < thetaSegments; i ++ ) {
  52. const segment = i + thetaSegmentLevel;
  53. const a = segment;
  54. const b = segment + thetaSegments + 1;
  55. const c = segment + thetaSegments + 2;
  56. const d = segment + 1;
  57. // faces
  58. indices.push( a, b, d );
  59. indices.push( b, c, d );
  60. }
  61. }
  62. // build geometry
  63. this.setIndex( indices );
  64. this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  65. this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  66. this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  67. }
  68. copy( source ) {
  69. super.copy( source );
  70. this.parameters = Object.assign( {}, source.parameters );
  71. return this;
  72. }
  73. static fromJSON( data ) {
  74. return new RingGeometry( data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength );
  75. }
  76. }
  77. export { RingGeometry };
粤ICP备19079148号