-
-
Notifications
You must be signed in to change notification settings - Fork 35.2k
/
SphereBufferGeometry.js
109 lines (70 loc) · 3.07 KB
/
SphereBufferGeometry.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { BufferGeometry } from '../../core/BufferGeometry';
import { Vector3 } from '../../math/Vector3';
import { Sphere } from '../../math/Sphere';
import { Uint16Attribute, Uint32Attribute, BufferAttribute } from '../../core/BufferAttribute';
/**
* @author benaadams / https://twitter.com/ben_a_adams
* based on THREE.SphereGeometry
*/
function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
BufferGeometry.call( this );
this.type = 'SphereBufferGeometry';
this.parameters = {
radius: radius,
widthSegments: widthSegments,
heightSegments: heightSegments,
phiStart: phiStart,
phiLength: phiLength,
thetaStart: thetaStart,
thetaLength: thetaLength
};
radius = radius || 50;
widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
phiStart = phiStart !== undefined ? phiStart : 0;
phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
thetaStart = thetaStart !== undefined ? thetaStart : 0;
thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
var thetaEnd = thetaStart + thetaLength;
var vertexCount = ( ( widthSegments + 1 ) * ( heightSegments + 1 ) );
var positions = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );
var normals = new BufferAttribute( new Float32Array( vertexCount * 3 ), 3 );
var uvs = new BufferAttribute( new Float32Array( vertexCount * 2 ), 2 );
var index = 0, vertices = [], normal = new Vector3();
for ( var y = 0; y <= heightSegments; y ++ ) {
var verticesRow = [];
var v = y / heightSegments;
for ( var x = 0; x <= widthSegments; x ++ ) {
var u = x / widthSegments;
var px = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
var py = radius * Math.cos( thetaStart + v * thetaLength );
var pz = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
normal.set( px, py, pz ).normalize();
positions.setXYZ( index, px, py, pz );
normals.setXYZ( index, normal.x, normal.y, normal.z );
uvs.setXY( index, u, 1 - v );
verticesRow.push( index );
index ++;
}
vertices.push( verticesRow );
}
var indices = [];
for ( var y = 0; y < heightSegments; y ++ ) {
for ( var x = 0; x < widthSegments; x ++ ) {
var v1 = vertices[ y ][ x + 1 ];
var v2 = vertices[ y ][ x ];
var v3 = vertices[ y + 1 ][ x ];
var v4 = vertices[ y + 1 ][ x + 1 ];
if ( y !== 0 || thetaStart > 0 ) indices.push( v1, v2, v4 );
if ( y !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( v2, v3, v4 );
}
}
this.setIndex( new ( positions.count > 65535 ? Uint32Attribute : Uint16Attribute )( indices, 1 ) );
this.addAttribute( 'position', positions );
this.addAttribute( 'normal', normals );
this.addAttribute( 'uv', uvs );
this.boundingSphere = new Sphere( new Vector3(), radius );
}
SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
SphereBufferGeometry.prototype.constructor = SphereBufferGeometry;
export { SphereBufferGeometry };