RingBufferGeometry.js 2.6 KB

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