SphereBufferGeometry.js 2.9 KB

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