1 /**
  2  * @author mrdoob / http://mrdoob.com/
  3  * @author kile / http://kile.stravaganza.org/
  4  * @author alteredq / http://alteredqualia.com/
  5  * @author mikael emtinger / http://gomo.se/
  6  * @author zz85 / http://www.lab4games.net/zz85/blog
  7  */
  8 
  9 /**@constructor*/
 10 THREE.Geometry = function () {
 11 
 12 	THREE.GeometryLibrary.push( this );
 13 
 14 	this.id = THREE.GeometryIdCount ++;
 15 
 16 	this.name = '';
 17 
 18 	this.vertices = [];
 19 	this.colors = [];  // one-to-one vertex colors, used in ParticleSystem, Line and Ribbon
 20 	this.normals = []; // one-to-one vertex normals, used in Ribbon
 21 
 22 	this.faces = [];
 23 
 24 	this.faceUvs = [[]];
 25 	this.faceVertexUvs = [[]];
 26 
 27 	this.morphTargets = [];
 28 	this.morphColors = [];
 29 	this.morphNormals = [];
 30 
 31 	this.skinWeights = [];
 32 	this.skinIndices = [];
 33 
 34 	this.lineDistances = [];
 35 
 36 	this.boundingBox = null;
 37 	this.boundingSphere = null;
 38 
 39 	this.hasTangents = false;
 40 
 41 	this.dynamic = true; // the intermediate typed arrays will be deleted when set to false
 42 
 43 	// update flags
 44 
 45 	this.verticesNeedUpdate = false;
 46 	this.elementsNeedUpdate = false;
 47 	this.uvsNeedUpdate = false;
 48 	this.normalsNeedUpdate = false;
 49 	this.tangentsNeedUpdate = false;
 50 	this.colorsNeedUpdate = false;
 51 	this.lineDistancesNeedUpdate = false;
 52 
 53 	this.buffersNeedUpdate = false;
 54 
 55 };
 56 
 57 THREE.Geometry.prototype = {
 58 
 59 	constructor : THREE.Geometry,
 60 
 61 	applyMatrix: function ( matrix ) {
 62 
 63 		var normalMatrix = new THREE.Matrix3();
 64 
 65 		normalMatrix.getInverse( matrix ).transpose();
 66 
 67 		for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
 68 
 69 			var vertex = this.vertices[ i ];
 70 
 71 			matrix.multiplyVector3( vertex );
 72 
 73 		}
 74 
 75 		for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
 76 
 77 			var face = this.faces[ i ];
 78 
 79 			normalMatrix.multiplyVector3( face.normal ).normalize();
 80 
 81 			for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
 82 
 83 				normalMatrix.multiplyVector3( face.vertexNormals[ j ] ).normalize();
 84 
 85 			}
 86 
 87 			matrix.multiplyVector3( face.centroid );
 88 
 89 		}
 90 
 91 	},
 92 
 93 	computeCentroids: function () {
 94 
 95 		var f, fl, face;
 96 
 97 		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
 98 
 99 			face = this.faces[ f ];
100 			face.centroid.set( 0, 0, 0 );
101 
102 			if ( face instanceof THREE.Face3 ) {
103 
104 				face.centroid.addSelf( this.vertices[ face.a ] );
105 				face.centroid.addSelf( this.vertices[ face.b ] );
106 				face.centroid.addSelf( this.vertices[ face.c ] );
107 				face.centroid.divideScalar( 3 );
108 
109 			} else if ( face instanceof THREE.Face4 ) {
110 
111 				face.centroid.addSelf( this.vertices[ face.a ] );
112 				face.centroid.addSelf( this.vertices[ face.b ] );
113 				face.centroid.addSelf( this.vertices[ face.c ] );
114 				face.centroid.addSelf( this.vertices[ face.d ] );
115 				face.centroid.divideScalar( 4 );
116 
117 			}
118 
119 		}
120 
121 	},
122 
123 	computeFaceNormals: function () {
124 
125 		var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
126 		cb = new THREE.Vector3(), ab = new THREE.Vector3();
127 
128 		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
129 
130 			face = this.faces[ f ];
131 
132 			vA = this.vertices[ face.a ];
133 			vB = this.vertices[ face.b ];
134 			vC = this.vertices[ face.c ];
135 
136 			cb.sub( vC, vB );
137 			ab.sub( vA, vB );
138 			cb.crossSelf( ab );
139 
140 			cb.normalize();
141 
142 			face.normal.copy( cb );
143 
144 		}
145 
146 	},
147 
148 	computeVertexNormals: function ( areaWeighted ) {
149 
150 		var v, vl, f, fl, face, vertices;
151 
152 		// create internal buffers for reuse when calling this method repeatedly
153 		// (otherwise memory allocation / deallocation every frame is big resource hog)
154 
155 		if ( this.__tmpVertices === undefined ) {
156 
157 			this.__tmpVertices = new Array( this.vertices.length );
158 			vertices = this.__tmpVertices;
159 
160 			for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
161 
162 				vertices[ v ] = new THREE.Vector3();
163 
164 			}
165 
166 			for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
167 
168 				face = this.faces[ f ];
169 
170 				if ( face instanceof THREE.Face3 ) {
171 
172 					face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
173 
174 				} else if ( face instanceof THREE.Face4 ) {
175 
176 					face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
177 
178 				}
179 
180 			}
181 
182 		} else {
183 
184 			vertices = this.__tmpVertices;
185 
186 			for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
187 
188 				vertices[ v ].set( 0, 0, 0 );
189 
190 			}
191 
192 		}
193 
194 		if ( areaWeighted ) {
195 
196 			// vertex normals weighted by triangle areas
197 			// http://www.iquilezles.org/www/articles/normals/normals.htm
198 
199 			var vA, vB, vC, vD;
200 			var cb = new THREE.Vector3(), ab = new THREE.Vector3(),
201 				db = new THREE.Vector3(), dc = new THREE.Vector3(), bc = new THREE.Vector3();
202 
203 			for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
204 
205 				face = this.faces[ f ];
206 
207 				if ( face instanceof THREE.Face3 ) {
208 
209 					vA = this.vertices[ face.a ];
210 					vB = this.vertices[ face.b ];
211 					vC = this.vertices[ face.c ];
212 
213 					cb.sub( vC, vB );
214 					ab.sub( vA, vB );
215 					cb.crossSelf( ab );
216 
217 					vertices[ face.a ].addSelf( cb );
218 					vertices[ face.b ].addSelf( cb );
219 					vertices[ face.c ].addSelf( cb );
220 
221 				} else if ( face instanceof THREE.Face4 ) {
222 
223 					vA = this.vertices[ face.a ];
224 					vB = this.vertices[ face.b ];
225 					vC = this.vertices[ face.c ];
226 					vD = this.vertices[ face.d ];
227 
228 					// abd
229 
230 					db.sub( vD, vB );
231 					ab.sub( vA, vB );
232 					db.crossSelf( ab );
233 
234 					vertices[ face.a ].addSelf( db );
235 					vertices[ face.b ].addSelf( db );
236 					vertices[ face.d ].addSelf( db );
237 
238 					// bcd
239 
240 					dc.sub( vD, vC );
241 					bc.sub( vB, vC );
242 					dc.crossSelf( bc );
243 
244 					vertices[ face.b ].addSelf( dc );
245 					vertices[ face.c ].addSelf( dc );
246 					vertices[ face.d ].addSelf( dc );
247 
248 				}
249 
250 			}
251 
252 		} else {
253 
254 			for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
255 
256 				face = this.faces[ f ];
257 
258 				if ( face instanceof THREE.Face3 ) {
259 
260 					vertices[ face.a ].addSelf( face.normal );
261 					vertices[ face.b ].addSelf( face.normal );
262 					vertices[ face.c ].addSelf( face.normal );
263 
264 				} else if ( face instanceof THREE.Face4 ) {
265 
266 					vertices[ face.a ].addSelf( face.normal );
267 					vertices[ face.b ].addSelf( face.normal );
268 					vertices[ face.c ].addSelf( face.normal );
269 					vertices[ face.d ].addSelf( face.normal );
270 
271 				}
272 
273 			}
274 
275 		}
276 
277 		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
278 
279 			vertices[ v ].normalize();
280 
281 		}
282 
283 		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
284 
285 			face = this.faces[ f ];
286 
287 			if ( face instanceof THREE.Face3 ) {
288 
289 				face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
290 				face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
291 				face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
292 
293 			} else if ( face instanceof THREE.Face4 ) {
294 
295 				face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
296 				face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
297 				face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
298 				face.vertexNormals[ 3 ].copy( vertices[ face.d ] );
299 
300 			}
301 
302 		}
303 
304 	},
305 
306 	computeMorphNormals: function () {
307 
308 		var i, il, f, fl, face;
309 
310 		// save original normals
311 		// - create temp variables on first access
312 		//   otherwise just copy (for faster repeated calls)
313 
314 		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
315 
316 			face = this.faces[ f ];
317 
318 			if ( ! face.__originalFaceNormal ) {
319 
320 				face.__originalFaceNormal = face.normal.clone();
321 
322 			} else {
323 
324 				face.__originalFaceNormal.copy( face.normal );
325 
326 			}
327 
328 			if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
329 
330 			for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
331 
332 				if ( ! face.__originalVertexNormals[ i ] ) {
333 
334 					face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
335 
336 				} else {
337 
338 					face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
339 
340 				}
341 
342 			}
343 
344 		}
345 
346 		// use temp geometry to compute face and vertex normals for each morph
347 
348 		var tmpGeo = new THREE.Geometry();
349 		tmpGeo.faces = this.faces;
350 
351 		for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
352 
353 			// create on first access
354 
355 			if ( ! this.morphNormals[ i ] ) {
356 
357 				this.morphNormals[ i ] = {};
358 				this.morphNormals[ i ].faceNormals = [];
359 				this.morphNormals[ i ].vertexNormals = [];
360 
361 				var dstNormalsFace = this.morphNormals[ i ].faceNormals;
362 				var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
363 
364 				var faceNormal, vertexNormals;
365 
366 				for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
367 
368 					face = this.faces[ f ];
369 
370 					faceNormal = new THREE.Vector3();
371 
372 					if ( face instanceof THREE.Face3 ) {
373 
374 						vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
375 
376 					} else {
377 
378 						vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3(), d: new THREE.Vector3() };
379 
380 					}
381 
382 					dstNormalsFace.push( faceNormal );
383 					dstNormalsVertex.push( vertexNormals );
384 
385 				}
386 
387 			}
388 
389 			var morphNormals = this.morphNormals[ i ];
390 
391 			// set vertices to morph target
392 
393 			tmpGeo.vertices = this.morphTargets[ i ].vertices;
394 
395 			// compute morph normals
396 
397 			tmpGeo.computeFaceNormals();
398 			tmpGeo.computeVertexNormals();
399 
400 			// store morph normals
401 
402 			var faceNormal, vertexNormals;
403 
404 			for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
405 
406 				face = this.faces[ f ];
407 
408 				faceNormal = morphNormals.faceNormals[ f ];
409 				vertexNormals = morphNormals.vertexNormals[ f ];
410 
411 				faceNormal.copy( face.normal );
412 
413 				if ( face instanceof THREE.Face3 ) {
414 
415 					vertexNormals.a.copy( face.vertexNormals[ 0 ] );
416 					vertexNormals.b.copy( face.vertexNormals[ 1 ] );
417 					vertexNormals.c.copy( face.vertexNormals[ 2 ] );
418 
419 				} else {
420 
421 					vertexNormals.a.copy( face.vertexNormals[ 0 ] );
422 					vertexNormals.b.copy( face.vertexNormals[ 1 ] );
423 					vertexNormals.c.copy( face.vertexNormals[ 2 ] );
424 					vertexNormals.d.copy( face.vertexNormals[ 3 ] );
425 
426 				}
427 
428 			}
429 
430 		}
431 
432 		// restore original normals
433 
434 		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
435 
436 			face = this.faces[ f ];
437 
438 			face.normal = face.__originalFaceNormal;
439 			face.vertexNormals = face.__originalVertexNormals;
440 
441 		}
442 
443 	},
444 
445 	computeTangents: function () {
446 
447 		// based on http://www.terathon.com/code/tangent.html
448 		// tangents go to vertices
449 
450 		var f, fl, v, vl, i, il, vertexIndex,
451 			face, uv, vA, vB, vC, uvA, uvB, uvC,
452 			x1, x2, y1, y2, z1, z2,
453 			s1, s2, t1, t2, r, t, test,
454 			tan1 = [], tan2 = [],
455 			sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
456 			tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
457 			n = new THREE.Vector3(), w;
458 
459 		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
460 
461 			tan1[ v ] = new THREE.Vector3();
462 			tan2[ v ] = new THREE.Vector3();
463 
464 		}
465 
466 		function handleTriangle( context, a, b, c, ua, ub, uc ) {
467 
468 			vA = context.vertices[ a ];
469 			vB = context.vertices[ b ];
470 			vC = context.vertices[ c ];
471 
472 			uvA = uv[ ua ];
473 			uvB = uv[ ub ];
474 			uvC = uv[ uc ];
475 
476 			x1 = vB.x - vA.x;
477 			x2 = vC.x - vA.x;
478 			y1 = vB.y - vA.y;
479 			y2 = vC.y - vA.y;
480 			z1 = vB.z - vA.z;
481 			z2 = vC.z - vA.z;
482 
483 			s1 = uvB.u - uvA.u;
484 			s2 = uvC.u - uvA.u;
485 			t1 = uvB.v - uvA.v;
486 			t2 = uvC.v - uvA.v;
487 
488 			r = 1.0 / ( s1 * t2 - s2 * t1 );
489 			sdir.set( ( t2 * x1 - t1 * x2 ) * r,
490 					  ( t2 * y1 - t1 * y2 ) * r,
491 					  ( t2 * z1 - t1 * z2 ) * r );
492 			tdir.set( ( s1 * x2 - s2 * x1 ) * r,
493 					  ( s1 * y2 - s2 * y1 ) * r,
494 					  ( s1 * z2 - s2 * z1 ) * r );
495 
496 			tan1[ a ].addSelf( sdir );
497 			tan1[ b ].addSelf( sdir );
498 			tan1[ c ].addSelf( sdir );
499 
500 			tan2[ a ].addSelf( tdir );
501 			tan2[ b ].addSelf( tdir );
502 			tan2[ c ].addSelf( tdir );
503 
504 		}
505 
506 		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
507 
508 			face = this.faces[ f ];
509 			uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
510 
511 			if ( face instanceof THREE.Face3 ) {
512 
513 				handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
514 
515 			} else if ( face instanceof THREE.Face4 ) {
516 
517 				handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
518 				handleTriangle( this, face.b, face.c, face.d, 1, 2, 3 );
519 
520 			}
521 
522 		}
523 
524 		var faceIndex = [ 'a', 'b', 'c', 'd' ];
525 
526 		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
527 
528 			face = this.faces[ f ];
529 
530 			for ( i = 0; i < face.vertexNormals.length; i++ ) {
531 
532 				n.copy( face.vertexNormals[ i ] );
533 
534 				vertexIndex = face[ faceIndex[ i ] ];
535 
536 				t = tan1[ vertexIndex ];
537 
538 				// Gram-Schmidt orthogonalize
539 
540 				tmp.copy( t );
541 				tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
542 
543 				// Calculate handedness
544 
545 				tmp2.cross( face.vertexNormals[ i ], t );
546 				test = tmp2.dot( tan2[ vertexIndex ] );
547 				w = (test < 0.0) ? -1.0 : 1.0;
548 
549 				face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
550 
551 			}
552 
553 		}
554 
555 		this.hasTangents = true;
556 
557 	},
558 
559 	computeLineDistances: function ( ) {
560 
561 		var d = 0;
562 		var vertices = this.vertices;
563 
564 		for ( var i = 0, il = vertices.length; i < il; i ++ ) {
565 
566 			if ( i > 0 ) {
567 
568 				d += vertices[ i ].distanceTo( vertices[ i - 1 ] );
569 
570 			}
571 
572 			this.lineDistances[ i ] = d;
573 
574 		}
575 
576 	},
577 
578 	computeBoundingBox: function () {
579 
580 		if ( ! this.boundingBox ) {
581 
582 			this.boundingBox = { min: new THREE.Vector3(), max: new THREE.Vector3() };
583 
584 		}
585 
586 		if ( this.vertices.length > 0 ) {
587 
588 			var position, firstPosition = this.vertices[ 0 ];
589 
590 			this.boundingBox.min.copy( firstPosition );
591 			this.boundingBox.max.copy( firstPosition );
592 
593 			var min = this.boundingBox.min,
594 				max = this.boundingBox.max;
595 
596 			for ( var v = 1, vl = this.vertices.length; v < vl; v ++ ) {
597 
598 				position = this.vertices[ v ];
599 
600 				if ( position.x < min.x ) {
601 
602 					min.x = position.x;
603 
604 				} else if ( position.x > max.x ) {
605 
606 					max.x = position.x;
607 
608 				}
609 
610 				if ( position.y < min.y ) {
611 
612 					min.y = position.y;
613 
614 				} else if ( position.y > max.y ) {
615 
616 					max.y = position.y;
617 
618 				}
619 
620 				if ( position.z < min.z ) {
621 
622 					min.z = position.z;
623 
624 				} else if ( position.z > max.z ) {
625 
626 					max.z = position.z;
627 
628 				}
629 
630 			}
631 
632 		} else {
633 
634 			this.boundingBox.min.set( 0, 0, 0 );
635 			this.boundingBox.max.set( 0, 0, 0 );
636 
637 		}
638 
639 	},
640 
641 	computeBoundingSphere: function () {
642 
643 		var maxRadiusSq = 0;
644 
645 		if ( this.boundingSphere === null ) this.boundingSphere = { radius: 0 };
646 
647 		for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {
648 
649 			var radiusSq = this.vertices[ i ].lengthSq();
650 			if ( radiusSq > maxRadiusSq ) maxRadiusSq = radiusSq;
651 
652 		}
653 
654 		this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
655 
656 	},
657 
658 	/*
659 	 * Checks for duplicate vertices with hashmap.
660 	 * Duplicated vertices are removed
661 	 * and faces' vertices are updated.
662 	 */
663 
664 	mergeVertices: function () {
665 
666 		var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
667 		var unique = [], changes = [];
668 
669 		var v, key;
670 		var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
671 		var precision = Math.pow( 10, precisionPoints );
672 		var i,il, face;
673 		var abcd = 'abcd', o, k, j, jl, u;
674 
675 		for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
676 
677 			v = this.vertices[ i ];
678 			key = [ Math.round( v.x * precision ), Math.round( v.y * precision ), Math.round( v.z * precision ) ].join( '_' );
679 
680 			if ( verticesMap[ key ] === undefined ) {
681 
682 				verticesMap[ key ] = i;
683 				unique.push( this.vertices[ i ] );
684 				changes[ i ] = unique.length - 1;
685 
686 			} else {
687 
688 				//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
689 				changes[ i ] = changes[ verticesMap[ key ] ];
690 
691 			}
692 
693 		};
694 
695 
696 		// Start to patch face indices
697 
698 		for( i = 0, il = this.faces.length; i < il; i ++ ) {
699 
700 			face = this.faces[ i ];
701 
702 			if ( face instanceof THREE.Face3 ) {
703 
704 				face.a = changes[ face.a ];
705 				face.b = changes[ face.b ];
706 				face.c = changes[ face.c ];
707 
708 			} else if ( face instanceof THREE.Face4 ) {
709 
710 				face.a = changes[ face.a ];
711 				face.b = changes[ face.b ];
712 				face.c = changes[ face.c ];
713 				face.d = changes[ face.d ];
714 
715 				// check dups in (a, b, c, d) and convert to -> face3
716 
717 				o = [ face.a, face.b, face.c, face.d ];
718 
719 				for ( k = 3; k > 0; k -- ) {
720 
721 					if ( o.indexOf( face[ abcd[ k ] ] ) !== k ) {
722 
723 						// console.log('faces', face.a, face.b, face.c, face.d, 'dup at', k);
724 
725 						o.splice( k, 1 );
726 
727 						this.faces[ i ] = new THREE.Face3( o[0], o[1], o[2], face.normal, face.color, face.materialIndex );
728 
729 						for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
730 
731 							u = this.faceVertexUvs[ j ][ i ];
732 							if ( u ) u.splice( k, 1 );
733 
734 						}
735 
736 						this.faces[ i ].vertexColors = face.vertexColors;
737 
738 						break;
739 					}
740 
741 				}
742 
743 			}
744 
745 		}
746 
747 		// Use unique set of vertices
748 
749 		var diff = this.vertices.length - unique.length;
750 		this.vertices = unique;
751 		return diff;
752 
753 	},
754 
755 	clone: function () {
756 
757 		var geometry = new THREE.Geometry();
758 
759 		var vertices = this.vertices;
760 
761 		for ( var i = 0, il = vertices.length; i < il; i ++ ) {
762 
763 			geometry.vertices.push( vertices[ i ].clone() );
764 
765 		}
766 
767 		var faces = this.faces;
768 
769 		for ( var i = 0, il = faces.length; i < il; i ++ ) {
770 
771 			geometry.faces.push( faces[ i ].clone() );
772 
773 		}
774 
775 		var uvs = this.faceVertexUvs[ 0 ];
776 
777 		for ( var i = 0, il = uvs.length; i < il; i ++ ) {
778 
779 			var uv = uvs[ i ], uvCopy = [];
780 
781 			for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
782 
783 				uvCopy.push( new THREE.UV( uv[ j ].u, uv[ j ].v ) );
784 
785 			}
786 
787 			geometry.faceVertexUvs[ 0 ].push( uvCopy );
788 
789 		}
790 
791 		return geometry;
792 
793 	},
794 
795 	deallocate: function () {
796 
797 		var index = THREE.GeometryLibrary.indexOf( this );
798 		if ( index !== -1 ) THREE.GeometryLibrary.splice( index, 1 );
799 
800 	}
801 
802 };
803 
804 /**@fieldOf THREE
805 @field
806 @name GeometryIdCount*/
807 THREE.GeometryIdCount = 0;
808 /**@fieldOf THREE
809 @field
810 @name GeometryLibrary*/
811 THREE.GeometryLibrary = [];
812 

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

mbt skor nike sverige louboutin skor hollister sverige polo ralph lauren skjorta woolrich jacka dam canada goose jacka woolrich jacka ray ban rea canada goose rea michael kors rea new balance skor ralph lauren skjorta new balance rea uggs sverige lacoste rea christian louboutin skor moncler jacka nike shox barbour jacka uggs rea