forked from mrdoob/three.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTorusBufferGeometry.js
More file actions
133 lines (95 loc) · 3.43 KB
/
TorusBufferGeometry.js
File metadata and controls
133 lines (95 loc) · 3.43 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { BufferGeometry } from '../core/BufferGeometry';
import { BufferAttribute } from '../core/BufferAttribute';
import { Vector3 } from '../math/Vector3';
/**
* @author Mugen87 / https://github.com/Mugen87
*/
function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
BufferGeometry.call( this );
this.type = 'TorusBufferGeometry';
this.parameters = {
radius: radius,
tube: tube,
radialSegments: radialSegments,
tubularSegments: tubularSegments,
arc: arc
};
radius = radius || 100;
tube = tube || 40;
radialSegments = Math.floor( radialSegments ) || 8;
tubularSegments = Math.floor( tubularSegments ) || 6;
arc = arc || Math.PI * 2;
// used to calculate buffer length
var vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) );
var indexCount = radialSegments * tubularSegments * 2 * 3;
// buffers
var indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );
var vertices = new Float32Array( vertexCount * 3 );
var normals = new Float32Array( vertexCount * 3 );
var uvs = new Float32Array( vertexCount * 2 );
// offset variables
var vertexBufferOffset = 0;
var uvBufferOffset = 0;
var indexBufferOffset = 0;
// helper variables
var center = new Vector3();
var vertex = new Vector3();
var normal = new Vector3();
var j, i;
// generate vertices, normals and uvs
for ( j = 0; j <= radialSegments; j ++ ) {
for ( i = 0; i <= tubularSegments; i ++ ) {
var u = i / tubularSegments * arc;
var v = j / radialSegments * Math.PI * 2;
// vertex
vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
vertex.z = tube * Math.sin( v );
vertices[ vertexBufferOffset ] = vertex.x;
vertices[ vertexBufferOffset + 1 ] = vertex.y;
vertices[ vertexBufferOffset + 2 ] = vertex.z;
// this vector is used to calculate the normal
center.x = radius * Math.cos( u );
center.y = radius * Math.sin( u );
// normal
normal.subVectors( vertex, center ).normalize();
normals[ vertexBufferOffset ] = normal.x;
normals[ vertexBufferOffset + 1 ] = normal.y;
normals[ vertexBufferOffset + 2 ] = normal.z;
// uv
uvs[ uvBufferOffset ] = i / tubularSegments;
uvs[ uvBufferOffset + 1 ] = j / radialSegments;
// update offsets
vertexBufferOffset += 3;
uvBufferOffset += 2;
}
}
// generate indices
for ( j = 1; j <= radialSegments; j ++ ) {
for ( i = 1; i <= tubularSegments; i ++ ) {
// indices
var a = ( tubularSegments + 1 ) * j + i - 1;
var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
var c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
var d = ( tubularSegments + 1 ) * j + i;
// face one
indices[ indexBufferOffset ] = a;
indices[ indexBufferOffset + 1 ] = b;
indices[ indexBufferOffset + 2 ] = d;
// face two
indices[ indexBufferOffset + 3 ] = b;
indices[ indexBufferOffset + 4 ] = c;
indices[ indexBufferOffset + 5 ] = d;
// update offset
indexBufferOffset += 6;
}
}
// build geometry
this.setIndex( new BufferAttribute( indices, 1 ) );
this.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );
this.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );
this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );
}
TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
TorusBufferGeometry.prototype.constructor = TorusBufferGeometry;
export { TorusBufferGeometry };