UNPKG

4.03 kBJavaScriptView Raw
1/**
2 * @author astrodud / http://astrodud.isgreat.org/
3 * @author zz85 / https://github.com/zz85
4 * @author bhouston / http://clara.io
5 * @author Mugen87 / https://github.com/Mugen87
6 */
7
8import { Geometry } from '../core/Geometry.js';
9import { Float32BufferAttribute } from '../core/BufferAttribute.js';
10import { BufferGeometry } from '../core/BufferGeometry.js';
11import { Vector3 } from '../math/Vector3.js';
12import { Vector2 } from '../math/Vector2.js';
13import { _Math } from '../math/Math.js';
14
15// LatheGeometry
16
17function LatheGeometry( points, segments, phiStart, phiLength ) {
18
19 Geometry.call( this );
20
21 this.type = 'LatheGeometry';
22
23 this.parameters = {
24 points: points,
25 segments: segments,
26 phiStart: phiStart,
27 phiLength: phiLength
28 };
29
30 this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );
31 this.mergeVertices();
32
33}
34
35LatheGeometry.prototype = Object.create( Geometry.prototype );
36LatheGeometry.prototype.constructor = LatheGeometry;
37
38// LatheBufferGeometry
39
40function LatheBufferGeometry( points, segments, phiStart, phiLength ) {
41
42 BufferGeometry.call( this );
43
44 this.type = 'LatheBufferGeometry';
45
46 this.parameters = {
47 points: points,
48 segments: segments,
49 phiStart: phiStart,
50 phiLength: phiLength
51 };
52
53 segments = Math.floor( segments ) || 12;
54 phiStart = phiStart || 0;
55 phiLength = phiLength || Math.PI * 2;
56
57 // clamp phiLength so it's in range of [ 0, 2PI ]
58
59 phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );
60
61
62 // buffers
63
64 var indices = [];
65 var vertices = [];
66 var uvs = [];
67
68 // helper variables
69
70 var base;
71 var inverseSegments = 1.0 / segments;
72 var vertex = new Vector3();
73 var uv = new Vector2();
74 var i, j;
75
76 // generate vertices and uvs
77
78 for ( i = 0; i <= segments; i ++ ) {
79
80 var phi = phiStart + i * inverseSegments * phiLength;
81
82 var sin = Math.sin( phi );
83 var cos = Math.cos( phi );
84
85 for ( j = 0; j <= ( points.length - 1 ); j ++ ) {
86
87 // vertex
88
89 vertex.x = points[ j ].x * sin;
90 vertex.y = points[ j ].y;
91 vertex.z = points[ j ].x * cos;
92
93 vertices.push( vertex.x, vertex.y, vertex.z );
94
95 // uv
96
97 uv.x = i / segments;
98 uv.y = j / ( points.length - 1 );
99
100 uvs.push( uv.x, uv.y );
101
102
103 }
104
105 }
106
107 // indices
108
109 for ( i = 0; i < segments; i ++ ) {
110
111 for ( j = 0; j < ( points.length - 1 ); j ++ ) {
112
113 base = j + i * points.length;
114
115 var a = base;
116 var b = base + points.length;
117 var c = base + points.length + 1;
118 var d = base + 1;
119
120 // faces
121
122 indices.push( a, b, d );
123 indices.push( b, c, d );
124
125 }
126
127 }
128
129 // build geometry
130
131 this.setIndex( indices );
132 this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
133 this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
134
135 // generate normals
136
137 this.computeVertexNormals();
138
139 // if the geometry is closed, we need to average the normals along the seam.
140 // because the corresponding vertices are identical (but still have different UVs).
141
142 if ( phiLength === Math.PI * 2 ) {
143
144 var normals = this.attributes.normal.array;
145 var n1 = new Vector3();
146 var n2 = new Vector3();
147 var n = new Vector3();
148
149 // this is the buffer offset for the last line of vertices
150
151 base = segments * points.length * 3;
152
153 for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {
154
155 // select the normal of the vertex in the first line
156
157 n1.x = normals[ j + 0 ];
158 n1.y = normals[ j + 1 ];
159 n1.z = normals[ j + 2 ];
160
161 // select the normal of the vertex in the last line
162
163 n2.x = normals[ base + j + 0 ];
164 n2.y = normals[ base + j + 1 ];
165 n2.z = normals[ base + j + 2 ];
166
167 // average normals
168
169 n.addVectors( n1, n2 ).normalize();
170
171 // assign the new values to both normals
172
173 normals[ j + 0 ] = normals[ base + j + 0 ] = n.x;
174 normals[ j + 1 ] = normals[ base + j + 1 ] = n.y;
175 normals[ j + 2 ] = normals[ base + j + 2 ] = n.z;
176
177 }
178
179 }
180
181}
182
183LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
184LatheBufferGeometry.prototype.constructor = LatheBufferGeometry;
185
186
187export { LatheGeometry, LatheBufferGeometry };