433 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			433 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | var THREE = require("./three.min"); | ||
|  | 
 | ||
|  | // BufferGeometryUtils.js
 | ||
|  | /** | ||
|  |  * @author spite / http://www.clicktorelease.com/
 | ||
|  |  * @author mrdoob / http://mrdoob.com/
 | ||
|  |  */ | ||
|  | 
 | ||
|  | THREE.BufferGeometryUtils = { | ||
|  | 
 | ||
|  | 	fromGeometry: function geometryToBufferGeometry( geometry, settings ) { | ||
|  | 
 | ||
|  | 		if ( geometry instanceof THREE.BufferGeometry ) { | ||
|  | 
 | ||
|  | 			return geometry; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		settings = settings || { 'vertexColors': THREE.NoColors }; | ||
|  | 
 | ||
|  | 		var vertices = geometry.vertices; | ||
|  | 		var faces = geometry.faces; | ||
|  | 		var faceVertexUvs = geometry.faceVertexUvs; | ||
|  | 		var vertexColors = settings.vertexColors; | ||
|  | 		var hasFaceVertexUv = faceVertexUvs[ 0 ].length > 0; | ||
|  | 		var hasFaceVertexNormals = faces[ 0 ].vertexNormals.length == 3; | ||
|  | 
 | ||
|  | 		var bufferGeometry = new THREE.BufferGeometry(); | ||
|  | 
 | ||
|  | 		bufferGeometry.attributes = { | ||
|  | 
 | ||
|  | 			position: { | ||
|  | 				itemSize: 3, | ||
|  | 				array: new Float32Array( faces.length * 3 * 3 ) | ||
|  | 			}, | ||
|  | 			normal: { | ||
|  | 				itemSize: 3, | ||
|  | 				array: new Float32Array( faces.length * 3 * 3 ) | ||
|  | 			} | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		var positions = bufferGeometry.attributes.position.array; | ||
|  | 		var normals = bufferGeometry.attributes.normal.array; | ||
|  | 
 | ||
|  | 		if ( vertexColors !== THREE.NoColors ) { | ||
|  | 
 | ||
|  | 			bufferGeometry.attributes.color = { | ||
|  | 				itemSize: 3, | ||
|  | 				array: new Float32Array( faces.length * 3 * 3 ) | ||
|  | 			}; | ||
|  | 
 | ||
|  | 			var colors = bufferGeometry.attributes.color.array; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( hasFaceVertexUv === true ) { | ||
|  | 
 | ||
|  | 			bufferGeometry.attributes.uv = { | ||
|  | 				itemSize: 2, | ||
|  | 				array: new Float32Array( faces.length * 3 * 2 ) | ||
|  | 			}; | ||
|  | 
 | ||
|  | 			var uvs = bufferGeometry.attributes.uv.array; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		for ( var i = 0, i2 = 0, i3 = 0; i < faces.length; i ++, i2 += 6, i3 += 9 ) { | ||
|  | 
 | ||
|  | 			var face = faces[ i ]; | ||
|  | 
 | ||
|  | 			var a = vertices[ face.a ]; | ||
|  | 			var b = vertices[ face.b ]; | ||
|  | 			var c = vertices[ face.c ]; | ||
|  | 
 | ||
|  | 			positions[ i3     ] = a.x; | ||
|  | 			positions[ i3 + 1 ] = a.y; | ||
|  | 			positions[ i3 + 2 ] = a.z; | ||
|  | 			 | ||
|  | 			positions[ i3 + 3 ] = b.x; | ||
|  | 			positions[ i3 + 4 ] = b.y; | ||
|  | 			positions[ i3 + 5 ] = b.z; | ||
|  | 			 | ||
|  | 			positions[ i3 + 6 ] = c.x; | ||
|  | 			positions[ i3 + 7 ] = c.y; | ||
|  | 			positions[ i3 + 8 ] = c.z; | ||
|  | 
 | ||
|  | 			if ( hasFaceVertexNormals === true ) { | ||
|  | 
 | ||
|  | 				var na = face.vertexNormals[ 0 ]; | ||
|  | 				var nb = face.vertexNormals[ 1 ]; | ||
|  | 				var nc = face.vertexNormals[ 2 ]; | ||
|  | 
 | ||
|  | 				normals[ i3     ] = na.x; | ||
|  | 				normals[ i3 + 1 ] = na.y; | ||
|  | 				normals[ i3 + 2 ] = na.z; | ||
|  | 
 | ||
|  | 				normals[ i3 + 3 ] = nb.x; | ||
|  | 				normals[ i3 + 4 ] = nb.y; | ||
|  | 				normals[ i3 + 5 ] = nb.z; | ||
|  | 
 | ||
|  | 				normals[ i3 + 6 ] = nc.x; | ||
|  | 				normals[ i3 + 7 ] = nc.y; | ||
|  | 				normals[ i3 + 8 ] = nc.z; | ||
|  | 
 | ||
|  | 			} else { | ||
|  | 
 | ||
|  | 				var n = face.normal; | ||
|  | 
 | ||
|  | 				normals[ i3     ] = n.x; | ||
|  | 				normals[ i3 + 1 ] = n.y; | ||
|  | 				normals[ i3 + 2 ] = n.z; | ||
|  | 
 | ||
|  | 				normals[ i3 + 3 ] = n.x; | ||
|  | 				normals[ i3 + 4 ] = n.y; | ||
|  | 				normals[ i3 + 5 ] = n.z; | ||
|  | 
 | ||
|  | 				normals[ i3 + 6 ] = n.x; | ||
|  | 				normals[ i3 + 7 ] = n.y; | ||
|  | 				normals[ i3 + 8 ] = n.z; | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if ( vertexColors === THREE.FaceColors ) { | ||
|  | 
 | ||
|  | 				var fc = face.color; | ||
|  | 
 | ||
|  | 				colors[ i3     ] = fc.r; | ||
|  | 				colors[ i3 + 1 ] = fc.g; | ||
|  | 				colors[ i3 + 2 ] = fc.b; | ||
|  | 
 | ||
|  | 				colors[ i3 + 3 ] = fc.r; | ||
|  | 				colors[ i3 + 4 ] = fc.g; | ||
|  | 				colors[ i3 + 5 ] = fc.b; | ||
|  | 
 | ||
|  | 				colors[ i3 + 6 ] = fc.r; | ||
|  | 				colors[ i3 + 7 ] = fc.g; | ||
|  | 				colors[ i3 + 8 ] = fc.b; | ||
|  | 
 | ||
|  | 			} else if ( vertexColors === THREE.VertexColors ) { | ||
|  | 
 | ||
|  | 				var vca = face.vertexColors[ 0 ]; | ||
|  | 				var vcb = face.vertexColors[ 1 ]; | ||
|  | 				var vcc = face.vertexColors[ 2 ]; | ||
|  | 
 | ||
|  | 				colors[ i3     ] = vca.r; | ||
|  | 				colors[ i3 + 1 ] = vca.g; | ||
|  | 				colors[ i3 + 2 ] = vca.b; | ||
|  | 
 | ||
|  | 				colors[ i3 + 3 ] = vcb.r; | ||
|  | 				colors[ i3 + 4 ] = vcb.g; | ||
|  | 				colors[ i3 + 5 ] = vcb.b; | ||
|  | 
 | ||
|  | 				colors[ i3 + 6 ] = vcc.r; | ||
|  | 				colors[ i3 + 7 ] = vcc.g; | ||
|  | 				colors[ i3 + 8 ] = vcc.b; | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if ( hasFaceVertexUv === true ) { | ||
|  | 
 | ||
|  | 				var uva = faceVertexUvs[ 0 ][ i ][ 0 ]; | ||
|  | 				var uvb = faceVertexUvs[ 0 ][ i ][ 1 ]; | ||
|  | 				var uvc = faceVertexUvs[ 0 ][ i ][ 2 ]; | ||
|  | 
 | ||
|  | 				uvs[ i2     ] = uva.x; | ||
|  | 				uvs[ i2 + 1 ] = uva.y; | ||
|  | 			 | ||
|  | 				uvs[ i2 + 2 ] = uvb.x; | ||
|  | 				uvs[ i2 + 3 ] = uvb.y; | ||
|  | 			 | ||
|  | 				uvs[ i2 + 4 ] = uvc.x; | ||
|  | 				uvs[ i2 + 5 ] = uvc.y; | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		bufferGeometry.computeBoundingSphere(); | ||
|  | 
 | ||
|  | 		return bufferGeometry; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | // ConvexGeometry.js
 | ||
|  | // @author qiao / https://github.com/qiao
 | ||
|  | 
 | ||
|  | THREE.ConvexGeometry = function( vertices ) { | ||
|  | 
 | ||
|  | 	THREE.Geometry.call( this ); | ||
|  | 
 | ||
|  | 	var faces = [ [ 0, 1, 2 ], [ 0, 2, 1 ] ];  | ||
|  | 
 | ||
|  | 	for ( var i = 3; i < vertices.length; i++ ) { | ||
|  | 
 | ||
|  | 		addPoint( i ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	function addPoint( vertexId ) { | ||
|  | 
 | ||
|  | 		var vertex = vertices[ vertexId ].clone(); | ||
|  | 
 | ||
|  | 		var mag = vertex.length(); | ||
|  | 		vertex.x += mag * randomOffset(); | ||
|  | 		vertex.y += mag * randomOffset(); | ||
|  | 		vertex.z += mag * randomOffset(); | ||
|  | 
 | ||
|  | 		var hole = []; | ||
|  | 
 | ||
|  | 		for ( var f = 0; f < faces.length; ) { | ||
|  | 
 | ||
|  | 			var face = faces[ f ]; | ||
|  | 
 | ||
|  | 			// for each face, if the vertex can see it,
 | ||
|  | 			// then we try to add the face's edges into the hole.
 | ||
|  | 			if ( visible( face, vertex ) ) { | ||
|  | 
 | ||
|  | 				for ( var e = 0; e < 3; e++ ) { | ||
|  | 
 | ||
|  | 					var edge = [ face[ e ], face[ ( e + 1 ) % 3 ] ]; | ||
|  | 					var boundary = true; | ||
|  | 
 | ||
|  | 					// remove duplicated edges.
 | ||
|  | 					for ( var h = 0; h < hole.length; h++ ) { | ||
|  | 
 | ||
|  | 						if ( equalEdge( hole[ h ], edge ) ) { | ||
|  | 
 | ||
|  | 							hole[ h ] = hole[ hole.length - 1 ]; | ||
|  | 							hole.pop(); | ||
|  | 							boundary = false; | ||
|  | 							break; | ||
|  | 
 | ||
|  | 						} | ||
|  | 
 | ||
|  | 					} | ||
|  | 
 | ||
|  | 					if ( boundary ) { | ||
|  | 
 | ||
|  | 						hole.push( edge ); | ||
|  | 
 | ||
|  | 					} | ||
|  | 
 | ||
|  | 				} | ||
|  | 
 | ||
|  | 				// remove faces[ f ]
 | ||
|  | 				faces[ f ] = faces[ faces.length - 1 ]; | ||
|  | 				faces.pop(); | ||
|  | 
 | ||
|  | 			} else { // not visible
 | ||
|  | 
 | ||
|  | 				f++; | ||
|  | 
 | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// construct the new faces formed by the edges of the hole and the vertex
 | ||
|  | 		for ( var h = 0; h < hole.length; h++ ) { | ||
|  | 
 | ||
|  | 			faces.push( [  | ||
|  | 				hole[ h ][ 0 ], | ||
|  | 				hole[ h ][ 1 ], | ||
|  | 				vertexId | ||
|  | 			] ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Whether the face is visible from the vertex | ||
|  | 	 */ | ||
|  | 	function visible( face, vertex ) { | ||
|  | 
 | ||
|  | 		var va = vertices[ face[ 0 ] ]; | ||
|  | 		var vb = vertices[ face[ 1 ] ]; | ||
|  | 		var vc = vertices[ face[ 2 ] ]; | ||
|  | 
 | ||
|  | 		var n = normal( va, vb, vc ); | ||
|  | 
 | ||
|  | 		// distance from face to origin
 | ||
|  | 		var dist = n.dot( va ); | ||
|  | 
 | ||
|  | 		return n.dot( vertex ) >= dist;  | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Face normal | ||
|  | 	 */ | ||
|  | 	function normal( va, vb, vc ) { | ||
|  | 
 | ||
|  | 		var cb = new THREE.Vector3(); | ||
|  | 		var ab = new THREE.Vector3(); | ||
|  | 
 | ||
|  | 		cb.subVectors( vc, vb ); | ||
|  | 		ab.subVectors( va, vb ); | ||
|  | 		cb.cross( ab ); | ||
|  | 
 | ||
|  | 		cb.normalize(); | ||
|  | 
 | ||
|  | 		return cb; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Detect whether two edges are equal. | ||
|  | 	 * Note that when constructing the convex hull, two same edges can only | ||
|  | 	 * be of the negative direction. | ||
|  | 	 */ | ||
|  | 	function equalEdge( ea, eb ) { | ||
|  | 
 | ||
|  | 		return ea[ 0 ] === eb[ 1 ] && ea[ 1 ] === eb[ 0 ];  | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Create a random offset between -1e-6 and 1e-6. | ||
|  | 	 */ | ||
|  | 	function randomOffset() { | ||
|  | 
 | ||
|  | 		return ( Math.random() - 0.5 ) * 2 * 1e-6; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * XXX: Not sure if this is the correct approach. Need someone to review. | ||
|  | 	 */ | ||
|  | 	function vertexUv( vertex ) { | ||
|  | 
 | ||
|  | 		var mag = vertex.length(); | ||
|  | 		return new THREE.Vector2( vertex.x / mag, vertex.y / mag ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Push vertices into `this.vertices`, skipping those inside the hull
 | ||
|  | 	var id = 0; | ||
|  | 	var newId = new Array( vertices.length ); // map from old vertex id to new id
 | ||
|  | 
 | ||
|  | 	for ( var i = 0; i < faces.length; i++ ) { | ||
|  | 
 | ||
|  | 		 var face = faces[ i ]; | ||
|  | 
 | ||
|  | 		 for ( var j = 0; j < 3; j++ ) { | ||
|  | 
 | ||
|  | 				if ( newId[ face[ j ] ] === undefined ) { | ||
|  | 
 | ||
|  | 						newId[ face[ j ] ] = id++; | ||
|  | 						this.vertices.push( vertices[ face[ j ] ] ); | ||
|  | 
 | ||
|  | 				} | ||
|  | 
 | ||
|  | 				face[ j ] = newId[ face[ j ] ]; | ||
|  | 
 | ||
|  | 		 } | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Convert faces into instances of THREE.Face3
 | ||
|  | 	for ( var i = 0; i < faces.length; i++ ) { | ||
|  | 
 | ||
|  | 		this.faces.push( new THREE.Face3(  | ||
|  | 				faces[ i ][ 0 ], | ||
|  | 				faces[ i ][ 1 ], | ||
|  | 				faces[ i ][ 2 ] | ||
|  | 		) ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Compute UVs
 | ||
|  | 	for ( var i = 0; i < this.faces.length; i++ ) { | ||
|  | 
 | ||
|  | 		var face = this.faces[ i ]; | ||
|  | 
 | ||
|  | 		this.faceVertexUvs[ 0 ].push( [ | ||
|  | 			vertexUv( this.vertices[ face.a ] ), | ||
|  | 			vertexUv( this.vertices[ face.b ] ), | ||
|  | 			vertexUv( this.vertices[ face.c ]) | ||
|  | 		] ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	this.computeFaceNormals(); | ||
|  | 	this.computeVertexNormals(); | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | THREE.ConvexGeometry.prototype = Object.create( THREE.Geometry.prototype ); | ||
|  | 
 | ||
|  | // SceneUtils.js
 | ||
|  | /** | ||
|  |  * @author alteredq / http://alteredqualia.com/
 | ||
|  |  */ | ||
|  | 
 | ||
|  | THREE.SceneUtils = { | ||
|  | 
 | ||
|  | 	createMultiMaterialObject: function ( geometry, materials ) { | ||
|  | 
 | ||
|  | 		var group = new THREE.Group(); | ||
|  | 
 | ||
|  | 		for ( var i = 0, l = materials.length; i < l; i ++ ) { | ||
|  | 
 | ||
|  | 			group.add( new THREE.Mesh( geometry, materials[ i ] ) ); | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return group; | ||
|  | 
 | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	detach: function ( child, parent, scene ) { | ||
|  | 
 | ||
|  | 		console.warn( 'THREE.SceneUtils: detach() has been deprecated. Use scene.attach( child ) instead.' ); | ||
|  | 
 | ||
|  | 		scene.attach( child ); | ||
|  | 
 | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	attach: function ( child, scene, parent ) { | ||
|  | 
 | ||
|  | 		console.warn( 'THREE.SceneUtils: attach() has been deprecated. Use parent.attach( child ) instead.' ); | ||
|  | 
 | ||
|  | 		parent.attach( child ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | module.exports = THREE |