| 
					
				 | 
			
			
				@@ -0,0 +1,787 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @author mrdoob / http://mrdoob.com/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+THREE.BufferGeometryUtils = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	computeTangents: function ( geometry ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var index = geometry.index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var attributes = geometry.attributes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// based on http://www.terathon.com/code/tangent.html 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// (per vertex tangents) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if ( index === null || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			 attributes.position === undefined || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			 attributes.normal === undefined || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			 attributes.uv === undefined ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			console.error( 'THREE.BufferGeometryUtils: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var indices = index.array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var positions = attributes.position.array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var normals = attributes.normal.array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var uvs = attributes.uv.array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var nVertices = positions.length / 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if ( attributes.tangent === undefined ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			geometry.setAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var tangents = attributes.tangent.array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var tan1 = [], tan2 = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0; i < nVertices; i ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan1[ i ] = new THREE.Vector3(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan2[ i ] = new THREE.Vector3(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var vA = new THREE.Vector3(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			vB = new THREE.Vector3(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			vC = new THREE.Vector3(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvA = new THREE.Vector2(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvB = new THREE.Vector2(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvC = new THREE.Vector2(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			sdir = new THREE.Vector3(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tdir = new THREE.Vector3(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		function handleTriangle( a, b, c ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			vA.fromArray( positions, a * 3 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			vB.fromArray( positions, b * 3 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			vC.fromArray( positions, c * 3 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvA.fromArray( uvs, a * 2 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvB.fromArray( uvs, b * 2 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvC.fromArray( uvs, c * 2 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			vB.sub( vA ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			vC.sub( vA ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvB.sub( uvA ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			uvC.sub( uvA ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// silently ignore degenerate uv triangles having coincident or colinear vertices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( ! isFinite( r ) ) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan1[ a ].add( sdir ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan1[ b ].add( sdir ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan1[ c ].add( sdir ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan2[ a ].add( tdir ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan2[ b ].add( tdir ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tan2[ c ].add( tdir ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var groups = geometry.groups; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if ( groups.length === 0 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			groups = [ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				start: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				count: indices.length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0, il = groups.length; i < il; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var group = groups[ i ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var start = group.start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var count = group.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var j = start, jl = start + count; j < jl; j += 3 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				handleTriangle( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					indices[ j + 0 ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					indices[ j + 1 ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					indices[ j + 2 ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var n = new THREE.Vector3(), n2 = new THREE.Vector3(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var w, t, test; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		function handleVertex( v ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			n.fromArray( normals, v * 3 ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			n2.copy( n ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			t = tan1[ v ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Gram-Schmidt orthogonalize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tmp.copy( t ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Calculate handedness 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tmp2.crossVectors( n2, t ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			test = tmp2.dot( tan2[ v ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			w = ( test < 0.0 ) ? - 1.0 : 1.0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tangents[ v * 4 ] = tmp.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tangents[ v * 4 + 1 ] = tmp.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tangents[ v * 4 + 2 ] = tmp.z; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			tangents[ v * 4 + 3 ] = w; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0, il = groups.length; i < il; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var group = groups[ i ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var start = group.start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var count = group.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var j = start, jl = start + count; j < jl; j += 3 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				handleVertex( indices[ j + 0 ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				handleVertex( indices[ j + 1 ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				handleVertex( indices[ j + 2 ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param  {Array<THREE.BufferGeometry>} geometries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param  {Boolean} useGroups 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @return {THREE.BufferGeometry} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	mergeBufferGeometries: function ( geometries, useGroups ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var isIndexed = geometries[ 0 ].index !== null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var morphAttributesUsed = new Set( Object.keys( geometries[ 0 ].morphAttributes ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var attributes = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var morphAttributes = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var morphTargetsRelative = geometries[ 0 ].morphTargetsRelative; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var mergedGeometry = new THREE.BufferGeometry(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var offset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0; i < geometries.length; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var geometry = geometries[ i ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var attributesCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// ensure that all geometries are indexed, or none 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( isIndexed !== ( geometry.index !== null ) ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// gather attributes, exit early if they're different 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var name in geometry.attributes ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if ( ! attributesUsed.has( name ) ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure "' + name + '" attribute exists among all geometries, or in none of them.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if ( attributes[ name ] === undefined ) attributes[ name ] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				attributes[ name ].push( geometry.attributes[ name ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				attributesCount ++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// ensure geometries have the same number of attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( attributesCount !== attributesUsed.size ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// gather morph attributes, exit early if they're different 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( morphTargetsRelative !== geometry.morphTargetsRelative ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. .morphTargetsRelative must be consistent throughout all geometries.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var name in geometry.morphAttributes ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if ( ! morphAttributesUsed.has( name ) ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '.  .morphAttributes must be consistent throughout all geometries.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				morphAttributes[ name ].push( geometry.morphAttributes[ name ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// gather .userData 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			mergedGeometry.userData.mergedUserData.push( geometry.userData ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( useGroups ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if ( isIndexed ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					count = geometry.index.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} else if ( geometry.attributes.position !== undefined ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					count = geometry.attributes.position.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. The geometry must have either an index or a position attribute' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				mergedGeometry.addGroup( offset, count, i ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				offset += count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// merge indices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if ( isIndexed ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var indexOffset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var mergedIndex = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var i = 0; i < geometries.length; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var index = geometries[ i ].index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var j = 0; j < index.count; ++ j ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					mergedIndex.push( index.getX( j ) + indexOffset ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				indexOffset += geometries[ i ].attributes.position.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			mergedGeometry.setIndex( mergedIndex ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// merge attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var name in attributes ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var mergedAttribute = this.mergeBufferAttributes( attributes[ name ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( ! mergedAttribute ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' + name + ' attribute.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			mergedGeometry.setAttribute( name, mergedAttribute ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// merge morph attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var name in morphAttributes ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var numMorphTargets = morphAttributes[ name ][ 0 ].length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( numMorphTargets === 0 ) break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			mergedGeometry.morphAttributes[ name ] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var i = 0; i < numMorphTargets; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var morphAttributesToMerge = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var j = 0; j < morphAttributes[ name ].length; ++ j ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					morphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var mergedMorphAttribute = this.mergeBufferAttributes( morphAttributesToMerge ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if ( ! mergedMorphAttribute ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					console.error( 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' + name + ' morphAttribute.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				mergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return mergedGeometry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param {Array<THREE.BufferAttribute>} attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @return {THREE.BufferAttribute} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	mergeBufferAttributes: function ( attributes ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var TypedArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var itemSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var normalized; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var arrayLength = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0; i < attributes.length; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var attribute = attributes[ i ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( attribute.isInterleavedBufferAttribute ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. InterleavedBufferAttributes are not supported.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( TypedArray === undefined ) TypedArray = attribute.array.constructor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( TypedArray !== attribute.array.constructor ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( itemSize === undefined ) itemSize = attribute.itemSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( itemSize !== attribute.itemSize ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( normalized === undefined ) normalized = attribute.normalized; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( normalized !== attribute.normalized ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			arrayLength += attribute.array.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var array = new TypedArray( arrayLength ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var offset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0; i < attributes.length; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			array.set( attributes[ i ].array, offset ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			offset += attributes[ i ].array.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return new THREE.BufferAttribute( array, itemSize, normalized ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param {Array<THREE.BufferAttribute>} attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @return {Array<THREE.InterleavedBufferAttribute>} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	interleaveAttributes: function ( attributes ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// Interleaves the provided attributes into an InterleavedBuffer and returns 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// a set of InterleavedBufferAttributes for each attribute 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var TypedArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var arrayLength = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var stride = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// calculate the the length and type of the interleavedBuffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0, l = attributes.length; i < l; ++ i ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var attribute = attributes[ i ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( TypedArray === undefined ) TypedArray = attribute.array.constructor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( TypedArray !== attribute.array.constructor ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'AttributeBuffers of different types cannot be interleaved' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			arrayLength += attribute.array.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			stride += attribute.itemSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// Create the set of buffer attributes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var interleavedBuffer = new THREE.InterleavedBuffer( new TypedArray( arrayLength ), stride ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var offset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var res = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var getters = [ 'getX', 'getY', 'getZ', 'getW' ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var setters = [ 'setX', 'setY', 'setZ', 'setW' ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var j = 0, l = attributes.length; j < l; j ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var attribute = attributes[ j ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var itemSize = attribute.itemSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var count = attribute.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var iba = new THREE.InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, attribute.normalized ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			res.push( iba ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			offset += itemSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Move the data for each attribute into the new interleavedBuffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// at the appropriate offset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var c = 0; c < count; c ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var k = 0; k < itemSize; k ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					iba[ setters[ k ] ]( c, attribute[ getters[ k ] ]( c ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return res; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param {Array<THREE.BufferGeometry>} geometry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @return {number} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	estimateBytesUsed: function ( geometry ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// Return the estimated memory used by this geometry in bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// Calculate using itemSize, count, and BYTES_PER_ELEMENT to account 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// for InterleavedBufferAttributes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var mem = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var name in geometry.attributes ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var attr = geometry.getAttribute( name ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			mem += attr.count * attr.itemSize * attr.array.BYTES_PER_ELEMENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var indices = geometry.getIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		mem += indices ? indices.count * indices.itemSize * indices.array.BYTES_PER_ELEMENT : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return mem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param {THREE.BufferGeometry} geometry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param {number} tolerance 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @return {THREE.BufferGeometry>} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	mergeVertices: function ( geometry, tolerance = 1e-4 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		tolerance = Math.max( tolerance, Number.EPSILON ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// Generate an index buffer if the geometry doesn't have one, or optimize it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// if it's already available. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var hashToIndex = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var indices = geometry.getIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var positions = geometry.getAttribute( 'position' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var vertexCount = indices ? indices.count : positions.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// next value for triangle indices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var nextIndex = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// attributes and new attribute arrays 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var attributeNames = Object.keys( geometry.attributes ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var attrArrays = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var morphAttrsArrays = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var newIndices = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var getters = [ 'getX', 'getY', 'getZ', 'getW' ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// initialize the arrays 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0, l = attributeNames.length; i < l; i ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var name = attributeNames[ i ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			attrArrays[ name ] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var morphAttr = geometry.morphAttributes[ name ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( morphAttr ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				morphAttrsArrays[ name ] = new Array( morphAttr.length ).fill().map( () => [] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// convert the error tolerance to an amount of decimal places to truncate to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var decimalShift = Math.log10( 1 / tolerance ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var shiftMultiplier = Math.pow( 10, decimalShift ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0; i < vertexCount; i ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var index = indices ? indices.getX( i ) : i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Generate a hash for the vertex attributes at the current index 'i' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var hash = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for ( var j = 0, l = attributeNames.length; j < l; j ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var name = attributeNames[ j ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var attribute = geometry.getAttribute( name ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var itemSize = attribute.itemSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var k = 0; k < itemSize; k ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					// double tilde truncates the decimal value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * shiftMultiplier ) },`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Add another reference to the vertex if it's already 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// used by another index 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( hash in hashToIndex ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				newIndices.push( hashToIndex[ hash ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// copy data to the new index in the attribute arrays 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var j = 0, l = attributeNames.length; j < l; j ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var name = attributeNames[ j ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var attribute = geometry.getAttribute( name ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var morphAttr = geometry.morphAttributes[ name ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var itemSize = attribute.itemSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var newarray = attrArrays[ name ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var newMorphArrays = morphAttrsArrays[ name ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					for ( var k = 0; k < itemSize; k ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						var getterFunc = getters[ k ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						newarray.push( attribute[ getterFunc ]( index ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						if ( morphAttr ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							for ( var m = 0, ml = morphAttr.length; m < ml; m ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+								newMorphArrays[ m ].push( morphAttr[ m ][ getterFunc ]( index ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				hashToIndex[ hash ] = nextIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				newIndices.push( nextIndex ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				nextIndex ++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// Generate typed arrays from new attribute arrays and update 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// the attributeBuffers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		const result = geometry.clone(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		for ( var i = 0, l = attributeNames.length; i < l; i ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var name = attributeNames[ i ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var oldAttribute = geometry.getAttribute( name ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var buffer = new oldAttribute.array.constructor( attrArrays[ name ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.normalized ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			result.setAttribute( name, attribute ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Update the attribute arrays 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( name in morphAttrsArrays ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var j = 0; j < morphAttrsArrays[ name ].length; j ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var oldMorphAttribute = geometry.morphAttributes[ name ][ j ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var buffer = new oldMorphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					var morphAttribute = new THREE.BufferAttribute( buffer, oldMorphAttribute.itemSize, oldMorphAttribute.normalized ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					result.morphAttributes[ name ][ j ] = morphAttribute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// indices 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		result.setIndex( newIndices ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param {THREE.BufferGeometry} geometry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @param {number} drawMode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 * @return {THREE.BufferGeometry>} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	toTrianglesDrawMode: function ( geometry, drawMode ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if ( drawMode === THREE.TrianglesDrawMode ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			console.warn( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return geometry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if ( drawMode === THREE.TriangleFanDrawMode || drawMode === THREE.TriangleStripDrawMode ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var index = geometry.getIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// generate index if not present 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( index === null ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var indices = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				var position = geometry.getAttribute( 'position' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if ( position !== undefined ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					for ( var i = 0; i < position.count; i ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						indices.push( i ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					geometry.setIndex( indices ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					index = geometry.getIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					console.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return geometry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var numberOfTriangles = index.count - 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var newIndices = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( drawMode === THREE.TriangleFanDrawMode ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// gl.TRIANGLE_FAN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var i = 1; i <= numberOfTriangles; i ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					newIndices.push( index.getX( 0 ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					newIndices.push( index.getX( i ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					newIndices.push( index.getX( i + 1 ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// gl.TRIANGLE_STRIP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				for ( var i = 0; i < numberOfTriangles; i ++ ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if ( i % 2 === 0 ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						newIndices.push( index.getX( i ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						newIndices.push( index.getX( i + 1 ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						newIndices.push( index.getX( i + 2 ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						newIndices.push( index.getX( i + 2 ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						newIndices.push( index.getX( i + 1 ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						newIndices.push( index.getX( i ) ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if ( ( newIndices.length / 3 ) !== numberOfTriangles ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				console.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// build final geometry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			var newGeometry = geometry.clone(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			newGeometry.setIndex( newIndices ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			newGeometry.clearGroups(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return newGeometry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			console.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:', drawMode ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return geometry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 |