1 /**
2 * @author WestLangley / https://github.com/WestLangley
3 * @author zz85 / https://github.com/zz85
4 * @author miningold / https://github.com/miningold
5 *
6 * Modified from the TorusKnotGeometry by @oosmoxiecode
7 *
8 * Creates a tube which extrudes along a 3d spline
9 *
10 * Uses parallel transport frames as described in
11 * http://www.cs.indiana.edu/pub/techreports/TR425.pdf
12 */
13
14 /**@constructor*/
15 THREE.TubeGeometry = function( path, segments, radius, radiusSegments, closed, debug ) {
16
17 THREE.Geometry.call( this );
18
19 this.path = path;
20 this.segments = segments || 64;
21 this.radius = radius || 1;
22 this.radiusSegments = radiusSegments || 8;
23 this.closed = closed || false;
24
25 if ( debug ) this.debug = new THREE.Object3D();
26
27 this.grid = [];
28
29 var scope = this,
30
31 tangent,
32 normal,
33 binormal,
34
35 numpoints = this.segments + 1,
36
37 x, y, z,
38 tx, ty, tz,
39 u, v,
40
41 cx, cy,
42 pos, pos2 = new THREE.Vector3(),
43 i, j,
44 ip, jp,
45 a, b, c, d,
46 uva, uvb, uvc, uvd;
47
48 var frames = new THREE.TubeGeometry.FrenetFrames(path, segments, closed),
49 tangents = frames.tangents,
50 normals = frames.normals,
51 binormals = frames.binormals;
52
53 // proxy internals
54 this.tangents = tangents;
55 this.normals = normals;
56 this.binormals = binormals;
57
58 function vert( x, y, z ) {
59
60 return scope.vertices.push( new THREE.Vector3( x, y, z ) ) - 1;
61
62 }
63
64
65 // consruct the grid
66
67 for ( i = 0; i < numpoints; i++ ) {
68
69 this.grid[ i ] = [];
70
71 u = i / ( numpoints - 1 );
72
73 pos = path.getPointAt( u );
74
75 tangent = tangents[ i ];
76 normal = normals[ i ];
77 binormal = binormals[ i ];
78
79 if ( this.debug ) {
80
81 this.debug.add( new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff ) );
82 this.debug.add( new THREE.ArrowHelper(normal, pos, radius, 0xff0000 ) );
83 this.debug.add( new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00 ) );
84
85 }
86
87 for ( j = 0; j < this.radiusSegments; j++ ) {
88
89 v = j / this.radiusSegments * 2 * Math.PI;
90
91 cx = -this.radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
92 cy = this.radius * Math.sin( v );
93
94 pos2.copy( pos );
95 pos2.x += cx * normal.x + cy * binormal.x;
96 pos2.y += cx * normal.y + cy * binormal.y;
97 pos2.z += cx * normal.z + cy * binormal.z;
98
99 this.grid[ i ][ j ] = vert( pos2.x, pos2.y, pos2.z );
100
101 }
102 }
103
104
105 // construct the mesh
106
107 for ( i = 0; i < this.segments; i++ ) {
108
109 for ( j = 0; j < this.radiusSegments; j++ ) {
110
111 ip = ( closed ) ? (i + 1) % this.segments : i + 1;
112 jp = (j + 1) % this.radiusSegments;
113
114 a = this.grid[ i ][ j ]; // *** NOT NECESSARILY PLANAR ! ***
115 b = this.grid[ ip ][ j ];
116 c = this.grid[ ip ][ jp ];
117 d = this.grid[ i ][ jp ];
118
119 uva = new THREE.UV( i / this.segments, j / this.radiusSegments );
120 uvb = new THREE.UV( ( i + 1 ) / this.segments, j / this.radiusSegments );
121 uvc = new THREE.UV( ( i + 1 ) / this.segments, ( j + 1 ) / this.radiusSegments );
122 uvd = new THREE.UV( i / this.segments, ( j + 1 ) / this.radiusSegments );
123
124 this.faces.push( new THREE.Face4( a, b, c, d ) );
125 this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvc, uvd ] );
126
127 }
128 }
129
130 this.computeCentroids();
131 this.computeFaceNormals();
132 this.computeVertexNormals();
133
134 };
135
136 THREE.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
137
138
139 // For computing of Frenet frames, exposing the tangents, normals and binormals the spline
140 THREE.TubeGeometry.FrenetFrames = function(path, segments, closed) {
141
142 var
143 tangent = new THREE.Vector3(),
144 normal = new THREE.Vector3(),
145 binormal = new THREE.Vector3(),
146
147 tangents = [],
148 normals = [],
149 binormals = [],
150
151 vec = new THREE.Vector3(),
152 mat = new THREE.Matrix4(),
153
154 numpoints = segments + 1,
155 theta,
156 epsilon = 0.0001,
157 smallest,
158
159 tx, ty, tz,
160 i, u, v;
161
162
163 // expose internals
164 this.tangents = tangents;
165 this.normals = normals;
166 this.binormals = binormals;
167
168 // compute the tangent vectors for each segment on the path
169
170 for ( i = 0; i < numpoints; i++ ) {
171
172 u = i / ( numpoints - 1 );
173
174 tangents[ i ] = path.getTangentAt( u );
175 tangents[ i ].normalize();
176
177 }
178
179 initialNormal3();
180
181 function initialNormal1(lastBinormal) {
182 // fixed start binormal. Has dangers of 0 vectors
183 normals[ 0 ] = new THREE.Vector3();
184 binormals[ 0 ] = new THREE.Vector3();
185 if (lastBinormal===undefined) lastBinormal = new THREE.Vector3( 0, 0, 1 );
186 normals[ 0 ].cross( lastBinormal, tangents[ 0 ] ).normalize();
187 binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] ).normalize();
188 }
189
190 function initialNormal2() {
191
192 // This uses the Frenet-Serret formula for deriving binormal
193 var t2 = path.getTangentAt( epsilon );
194
195 normals[ 0 ] = new THREE.Vector3().sub( t2, tangents[ 0 ] ).normalize();
196 binormals[ 0 ] = new THREE.Vector3().cross( tangents[ 0 ], normals[ 0 ] );
197
198 normals[ 0 ].cross( binormals[ 0 ], tangents[ 0 ] ).normalize(); // last binormal x tangent
199 binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] ).normalize();
200
201 }
202
203 function initialNormal3() {
204 // select an initial normal vector perpenicular to the first tangent vector,
205 // and in the direction of the smallest tangent xyz component
206
207 normals[ 0 ] = new THREE.Vector3();
208 binormals[ 0 ] = new THREE.Vector3();
209 smallest = Number.MAX_VALUE;
210 tx = Math.abs( tangents[ 0 ].x );
211 ty = Math.abs( tangents[ 0 ].y );
212 tz = Math.abs( tangents[ 0 ].z );
213
214 if ( tx <= smallest ) {
215 smallest = tx;
216 normal.set( 1, 0, 0 );
217 }
218
219 if ( ty <= smallest ) {
220 smallest = ty;
221 normal.set( 0, 1, 0 );
222 }
223
224 if ( tz <= smallest ) {
225 normal.set( 0, 0, 1 );
226 }
227
228 vec.cross( tangents[ 0 ], normal ).normalize();
229
230 normals[ 0 ].cross( tangents[ 0 ], vec );
231 binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] );
232 }
233
234
235 // compute the slowly-varying normal and binormal vectors for each segment on the path
236
237 for ( i = 1; i < numpoints; i++ ) {
238
239 normals[ i ] = normals[ i-1 ].clone();
240
241 binormals[ i ] = binormals[ i-1 ].clone();
242
243 vec.cross( tangents[ i-1 ], tangents[ i ] );
244
245 if ( vec.length() > epsilon ) {
246
247 vec.normalize();
248
249 theta = Math.acos( tangents[ i-1 ].dot( tangents[ i ] ) );
250
251 mat.makeRotationAxis( vec, theta ).multiplyVector3( normals[ i ] );
252
253 }
254
255 binormals[ i ].cross( tangents[ i ], normals[ i ] );
256
257 }
258
259
260 // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
261
262 if ( closed ) {
263
264 theta = Math.acos( normals[ 0 ].dot( normals[ numpoints-1 ] ) );
265 theta /= ( numpoints - 1 );
266
267 if ( tangents[ 0 ].dot( vec.cross( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) {
268
269 theta = -theta;
270
271 }
272
273 for ( i = 1; i < numpoints; i++ ) {
274
275 // twist a little...
276 mat.makeRotationAxis( tangents[ i ], theta * i ).multiplyVector3( normals[ i ] );
277 binormals[ i ].cross( tangents[ i ], normals[ i ] );
278
279 }
280
281 }
282 };
283
nike free rn
new balance hombre baratas
cinturones gucci
ugg rebajas
cinturon gucci
ray ban baratas
nike cortez
peuterey mujer
christian louboutin madrid
mbt zapatos
gafas ray ban baratas
mbt ofertas
air max blancas
mbt barcelona
nike air max 90
woolrich barcelona
nike mujer
botas ugg
gafas de sol carrera aratas
air max 2016 baratas
oakley baratas
nike air max 2016