RingGeometry.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import { Geometry } from '../core/Geometry.js';
  2. import { BufferGeometry } from '../core/BufferGeometry.js';
  3. import { Float32BufferAttribute } from '../core/BufferAttribute.js';
  4. import { Vector2 } from '../math/Vector2.js';
  5. import { Vector3 } from '../math/Vector3.js';
  6. // RingGeometry
  7. function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
  8. Geometry.call( this );
  9. this.type = 'RingGeometry';
  10. this.parameters = {
  11. innerRadius: innerRadius,
  12. outerRadius: outerRadius,
  13. thetaSegments: thetaSegments,
  14. phiSegments: phiSegments,
  15. thetaStart: thetaStart,
  16. thetaLength: thetaLength
  17. };
  18. this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
  19. this.mergeVertices();
  20. }
  21. RingGeometry.prototype = Object.create( Geometry.prototype );
  22. RingGeometry.prototype.constructor = RingGeometry;
  23. // RingBufferGeometry
  24. function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
  25. BufferGeometry.call( this );
  26. this.type = 'RingBufferGeometry';
  27. this.parameters = {
  28. innerRadius: innerRadius,
  29. outerRadius: outerRadius,
  30. thetaSegments: thetaSegments,
  31. phiSegments: phiSegments,
  32. thetaStart: thetaStart,
  33. thetaLength: thetaLength
  34. };
  35. innerRadius = innerRadius || 0.5;
  36. outerRadius = outerRadius || 1;
  37. thetaStart = thetaStart !== undefined ? thetaStart : 0;
  38. thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
  39. thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
  40. phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;
  41. // buffers
  42. const indices = [];
  43. const vertices = [];
  44. const normals = [];
  45. const uvs = [];
  46. // some helper variables
  47. let radius = innerRadius;
  48. const radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
  49. const vertex = new Vector3();
  50. const uv = new Vector2();
  51. // generate vertices, normals and uvs
  52. for ( let j = 0; j <= phiSegments; j ++ ) {
  53. for ( let i = 0; i <= thetaSegments; i ++ ) {
  54. // values are generate from the inside of the ring to the outside
  55. const segment = thetaStart + i / thetaSegments * thetaLength;
  56. // vertex
  57. vertex.x = radius * Math.cos( segment );
  58. vertex.y = radius * Math.sin( segment );
  59. vertices.push( vertex.x, vertex.y, vertex.z );
  60. // normal
  61. normals.push( 0, 0, 1 );
  62. // uv
  63. uv.x = ( vertex.x / outerRadius + 1 ) / 2;
  64. uv.y = ( vertex.y / outerRadius + 1 ) / 2;
  65. uvs.push( uv.x, uv.y );
  66. }
  67. // increase the radius for next row of vertices
  68. radius += radiusStep;
  69. }
  70. // indices
  71. for ( let j = 0; j < phiSegments; j ++ ) {
  72. const thetaSegmentLevel = j * ( thetaSegments + 1 );
  73. for ( let i = 0; i < thetaSegments; i ++ ) {
  74. const segment = i + thetaSegmentLevel;
  75. const a = segment;
  76. const b = segment + thetaSegments + 1;
  77. const c = segment + thetaSegments + 2;
  78. const d = segment + 1;
  79. // faces
  80. indices.push( a, b, d );
  81. indices.push( b, c, d );
  82. }
  83. }
  84. // build geometry
  85. this.setIndex( indices );
  86. this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  87. this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  88. this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  89. }
  90. RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  91. RingBufferGeometry.prototype.constructor = RingBufferGeometry;
  92. export { RingGeometry, RingBufferGeometry };