Browse Source

Decals: Code clean up.

Mr.doob 11 years ago
parent
commit
9f69cbc3ac
2 changed files with 360 additions and 365 deletions
  1. 101 103
      examples/js/geometries/DecalGeometry.js
  2. 259 262
      examples/webgl_decals.html

+ 101 - 103
examples/js/THREE.DecalGeometry.js → examples/js/geometries/DecalGeometry.js

@@ -1,5 +1,3 @@
-//goog.provide( 'green.THREEAddOns' );
-
 THREE.DecalVertex = function( v, n ) {
 THREE.DecalVertex = function( v, n ) {
 
 
 	this.vertex = v;
 	this.vertex = v;
@@ -28,17 +26,17 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 	this.cube.scale.set( 1, 1, 1 );
 	this.cube.scale.set( 1, 1, 1 );
 	this.cube.updateMatrix();
 	this.cube.updateMatrix();
 
 
-    this.iCubeMatrix = ( new THREE.Matrix4() ).getInverse( this.cube.matrix );
-    
-    this.faceIndices = [ 'a', 'b', 'c', 'd' ];
+	this.iCubeMatrix = ( new THREE.Matrix4() ).getInverse( this.cube.matrix );
+	
+	this.faceIndices = [ 'a', 'b', 'c', 'd' ];
 
 
-    this.clipFace = function( inVertices, plane ) {
+	this.clipFace = function( inVertices, plane ) {
 
 
-    	var size = .5 * Math.abs( ( dimensions.clone() ).dot( plane ) );
+		var size = .5 * Math.abs( ( dimensions.clone() ).dot( plane ) );
 
 
-	    function clip( v0, v1, p ) {
+		function clip( v0, v1, p ) {
 
 
-	    	var d0 = v0.vertex.dot( p ) - size,
+			var d0 = v0.vertex.dot( p ) - size,
 				d1 = v1.vertex.dot( p ) - size;
 				d1 = v1.vertex.dot( p ) - size;
 
 
 			var s = d0 / ( d0 - d1 );
 			var s = d0 / ( d0 - d1 );
@@ -60,14 +58,14 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 
 
 			return v;
 			return v;
 
 
-	    }
+		}
 
 
-    	if( inVertices.length === 0 ) return [];
-    	var outVertices = [];
+		if( inVertices.length === 0 ) return [];
+		var outVertices = [];
 
 
-    	for( var j = 0; j < inVertices.length; j += 3 ) {
+		for( var j = 0; j < inVertices.length; j += 3 ) {
 
 
-    		var v1Out, v2Out, v3Out, total = 0;
+			var v1Out, v2Out, v3Out, total = 0;
 
 
 			var d1 = inVertices[ j + 0 ].vertex.dot( plane ) - size,
 			var d1 = inVertices[ j + 0 ].vertex.dot( plane ) - size,
 				d2 = inVertices[ j + 1 ].vertex.dot( plane ) - size,
 				d2 = inVertices[ j + 1 ].vertex.dot( plane ) - size,
@@ -77,24 +75,24 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 			v2Out = d2 > 0;
 			v2Out = d2 > 0;
 			v3Out = d3 > 0;
 			v3Out = d3 > 0;
 
 
-	    	total = ( v1Out?1:0 ) + ( v2Out?1:0 ) + ( v3Out?1:0 );
+			total = ( v1Out?1:0 ) + ( v2Out?1:0 ) + ( v3Out?1:0 );
 
 
-	    	switch( total ) {
-	    		case 0:{
+			switch( total ) {
+				case 0:{
 					outVertices.push( inVertices[ j ] );
 					outVertices.push( inVertices[ j ] );
 					outVertices.push( inVertices[ j + 1 ] );
 					outVertices.push( inVertices[ j + 1 ] );
 					outVertices.push( inVertices[ j + 2 ] );
 					outVertices.push( inVertices[ j + 2 ] );
-		    		break;
-		    	}
-	    		case 1:{
-	    			var nV1, nV2, nV3;
+					break;
+				}
+				case 1:{
+					var nV1, nV2, nV3;
 					if( v1Out ) {
 					if( v1Out ) {
 						nV1 = inVertices[ j + 1 ]; 
 						nV1 = inVertices[ j + 1 ]; 
 						nV2 = inVertices[ j + 2 ];
 						nV2 = inVertices[ j + 2 ];
 						nV3 = clip( inVertices[ j ], nV1, plane );
 						nV3 = clip( inVertices[ j ], nV1, plane );
 						nV4 = clip( inVertices[ j ], nV2, plane );
 						nV4 = clip( inVertices[ j ], nV2, plane );
 					}
 					}
-		    		if( v2Out ) { 
+					if( v2Out ) { 
 						nV1 = inVertices[ j ]; 
 						nV1 = inVertices[ j ]; 
 						nV2 = inVertices[ j + 2 ];
 						nV2 = inVertices[ j + 2 ];
 						nV3 = clip( inVertices[ j + 1 ], nV1, plane );
 						nV3 = clip( inVertices[ j + 1 ], nV1, plane );
@@ -109,7 +107,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 						outVertices.push( nV4 );
 						outVertices.push( nV4 );
 						break;
 						break;
 					}
 					}
-		    		if( v3Out ) { 
+					if( v3Out ) { 
 						nV1 = inVertices[ j ]; 
 						nV1 = inVertices[ j ]; 
 						nV2 = inVertices[ j + 1 ];
 						nV2 = inVertices[ j + 1 ];
 						nV3 = clip( inVertices[ j + 2 ], nV1, plane );
 						nV3 = clip( inVertices[ j + 2 ], nV1, plane );
@@ -124,84 +122,84 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 					outVertices.push( nV3.clone() );
 					outVertices.push( nV3.clone() );
 					outVertices.push( nV2.clone() );
 					outVertices.push( nV2.clone() );
 
 
-		    		break;
-		    	}
-		    	case 2: {
-		    		var nV1, nV2, nV3;
-		    		if( !v1Out ) { 
-		    			nV1 = inVertices[ j ].clone();
-		    			nV2 = clip( nV1, inVertices[ j + 1 ], plane );
-		    			nV3 = clip( nV1, inVertices[ j + 2 ], plane ); 
+					break;
+				}
+				case 2: {
+					var nV1, nV2, nV3;
+					if( !v1Out ) { 
+						nV1 = inVertices[ j ].clone();
+						nV2 = clip( nV1, inVertices[ j + 1 ], plane );
+						nV3 = clip( nV1, inVertices[ j + 2 ], plane ); 
 						outVertices.push( nV1 );
 						outVertices.push( nV1 );
 						outVertices.push( nV2 );
 						outVertices.push( nV2 );
 						outVertices.push( nV3 );
 						outVertices.push( nV3 );
-		    		}
-		    		if( !v2Out ) { 
-		    			nV1 = inVertices[ j + 1 ].clone();
-		    			nV2 = clip( nV1, inVertices[ j + 2 ], plane );
-		    			nV3 = clip( nV1, inVertices[ j ], plane );
+					}
+					if( !v2Out ) { 
+						nV1 = inVertices[ j + 1 ].clone();
+						nV2 = clip( nV1, inVertices[ j + 2 ], plane );
+						nV3 = clip( nV1, inVertices[ j ], plane );
 						outVertices.push( nV1 );
 						outVertices.push( nV1 );
 						outVertices.push( nV2 );
 						outVertices.push( nV2 );
 						outVertices.push( nV3 );
 						outVertices.push( nV3 );
 					}
 					}
-		    		if( !v3Out ) {
-		    			nV1 = inVertices[ j + 2 ].clone();
-		    			nV2 = clip( nV1, inVertices[ j ], plane );
-		    			nV3 = clip( nV1, inVertices[ j + 1 ], plane );
-		    			outVertices.push( nV1 );
-		    			outVertices.push( nV2 );
-		    			outVertices.push( nV3 );
+					if( !v3Out ) {
+						nV1 = inVertices[ j + 2 ].clone();
+						nV2 = clip( nV1, inVertices[ j ], plane );
+						nV3 = clip( nV1, inVertices[ j + 1 ], plane );
+						outVertices.push( nV1 );
+						outVertices.push( nV2 );
+						outVertices.push( nV3 );
 					}
 					}
 
 
-		    		break;
-		    	}
-		    	case 3: {
-		    		break;
-		    	}
-	    	}
+					break;
+				}
+				case 3: {
+					break;
+				}
+			}
 
 
-	    }
+		}
 
 
-	    return outVertices;
+		return outVertices;
 
 
-    }
+	}
 
 
-    this.pushVertex = function( vertices, id, n ){
+	this.pushVertex = function( vertices, id, n ){
 
 
-    	var v = mesh.geometry.vertices[ id ].clone();
-        v.applyMatrix4( mesh.matrix );
-        v.applyMatrix4( this.iCubeMatrix );
-        vertices.push( new THREE.DecalVertex( v, n.clone() ) );
+		var v = mesh.geometry.vertices[ id ].clone();
+		v.applyMatrix4( mesh.matrix );
+		v.applyMatrix4( this.iCubeMatrix );
+		vertices.push( new THREE.DecalVertex( v, n.clone() ) );
 
 
-    }
+	}
 
 
-    this.computeDecal = function() {
+	this.computeDecal = function() {
 
 
-	    var finalVertices = [];
+		var finalVertices = [];
 
 
-	    for( var i = 0; i < mesh.geometry.faces.length; i++ ) {
+		for( var i = 0; i < mesh.geometry.faces.length; i++ ) {
 
 
-	        var f = mesh.geometry.faces[ i ];
-	        var vertices = [];
+			var f = mesh.geometry.faces[ i ];
+			var vertices = [];
 
 
-            this.pushVertex( vertices, f[ this.faceIndices[ 0 ] ], f.vertexNormals[ 0 ] );
-            this.pushVertex( vertices, f[ this.faceIndices[ 1 ] ], f.vertexNormals[ 1 ] );
-            this.pushVertex( vertices, f[ this.faceIndices[ 2 ] ], f.vertexNormals[ 2 ] );
+			this.pushVertex( vertices, f[ this.faceIndices[ 0 ] ], f.vertexNormals[ 0 ] );
+			this.pushVertex( vertices, f[ this.faceIndices[ 1 ] ], f.vertexNormals[ 1 ] );
+			this.pushVertex( vertices, f[ this.faceIndices[ 2 ] ], f.vertexNormals[ 2 ] );
 
 
-	        if( check.x ) {
-	        	vertices = this.clipFace( vertices, new THREE.Vector3( 1, 0, 0 ) );
-	        	vertices = this.clipFace( vertices, new THREE.Vector3( -1, 0, 0 ) );
-	        }
-	        if( check.y ) {
-		       	vertices = this.clipFace( vertices, new THREE.Vector3( 0, 1, 0 ) );
-		       	vertices = this.clipFace( vertices, new THREE.Vector3( 0, -1, 0 ) );
-		    }
-		    if( check.z ) {
-		        vertices = this.clipFace( vertices, new THREE.Vector3( 0, 0, 1 ) );
-		        vertices = this.clipFace( vertices, new THREE.Vector3( 0, 0, -1 ) );
-		    }
+			if( check.x ) {
+				vertices = this.clipFace( vertices, new THREE.Vector3( 1, 0, 0 ) );
+				vertices = this.clipFace( vertices, new THREE.Vector3( -1, 0, 0 ) );
+			}
+			if( check.y ) {
+			   	vertices = this.clipFace( vertices, new THREE.Vector3( 0, 1, 0 ) );
+			   	vertices = this.clipFace( vertices, new THREE.Vector3( 0, -1, 0 ) );
+			}
+			if( check.z ) {
+				vertices = this.clipFace( vertices, new THREE.Vector3( 0, 0, 1 ) );
+				vertices = this.clipFace( vertices, new THREE.Vector3( 0, 0, -1 ) );
+			}
 
 
-	        for( var j = 0; j < vertices.length; j++ ) {
+			for( var j = 0; j < vertices.length; j++ ) {
 
 
 				var v = vertices[ j ];
 				var v = vertices[ j ];
 
 
@@ -212,39 +210,39 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 
 
 				vertices[ j ].vertex.applyMatrix4( this.cube.matrix );
 				vertices[ j ].vertex.applyMatrix4( this.cube.matrix );
 
 
-	        }
+			}
 
 
 			if( vertices.length === 0 ) continue;
 			if( vertices.length === 0 ) continue;
 
 
 			finalVertices = finalVertices.concat( vertices );
 			finalVertices = finalVertices.concat( vertices );
 
 
-	    }
-
-	    for( var k = 0; k < finalVertices.length; k += 3 ) {
-	        
-	        this.vertices.push(
-	        	finalVertices[ k ].vertex,
-	        	finalVertices[ k + 1 ].vertex,
-	        	finalVertices[ k + 2 ].vertex
-	        );
-
-	        var f = new THREE.Face3( 
-	            k, 
-	            k + 1, 
-	            k + 2
-	        ) 
-	    	f.vertexNormals.push( finalVertices[ k + 0 ].normal );
-	    	f.vertexNormals.push( finalVertices[ k + 1 ].normal );
-	    	f.vertexNormals.push( finalVertices[ k + 2 ].normal );
-	    	
-	        this.faces.push( f );
-	        
-	        this.faceVertexUvs[ 0 ].push( [
+		}
+
+		for( var k = 0; k < finalVertices.length; k += 3 ) {
+			
+			this.vertices.push(
+				finalVertices[ k ].vertex,
+				finalVertices[ k + 1 ].vertex,
+				finalVertices[ k + 2 ].vertex
+			);
+
+			var f = new THREE.Face3( 
+				k, 
+				k + 1, 
+				k + 2
+			) 
+			f.vertexNormals.push( finalVertices[ k + 0 ].normal );
+			f.vertexNormals.push( finalVertices[ k + 1 ].normal );
+			f.vertexNormals.push( finalVertices[ k + 2 ].normal );
+			
+			this.faces.push( f );
+			
+			this.faceVertexUvs[ 0 ].push( [
 				this.uvs[ k ],
 				this.uvs[ k ],
 				this.uvs[ k + 1 ], 
 				this.uvs[ k + 1 ], 
 				this.uvs[ k + 2 ]
 				this.uvs[ k + 2 ]
 			] );
 			] );
-	    
+		
 		}
 		}
 
 
 		this.verticesNeedUpdate = true;
 		this.verticesNeedUpdate = true;

+ 259 - 262
examples/webgl_decals.html

@@ -5,369 +5,366 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 		<style>
-			*{ box-sizing: border-box; margin: 0; padding: 0 }
 			body {
 			body {
-				color: #888;
-				font-family: tahoma;
+				color: #fff;
+				font-family:Monospace;
 				font-size:13px;
 				font-size:13px;
-				background-color: #222;
 				margin: 0px;
 				margin: 0px;
+				text-align:center;
 				overflow: hidden;
 				overflow: hidden;
-				text-shadow: 0 1px 0 rgba( 0,0,0,.5 )
 			}
 			}
-			.intro{ position: absolute; left: 10px; top: 10px; line-height: 1.4em }
-			a{ color: inherit }
+			#info{ position: absolute; width: 100%; padding: 5px; }
 			#container canvas{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; bottom: 0;}
 			#container canvas{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; bottom: 0;}
-			b{ color: #aaa;}
 		</style>
 		</style>
 	</head>
 	</head>
 	<body>
 	<body>
 
 
 		<div id="container"></div>
 		<div id="container"></div>
-		<div class="intro">
-			<p><b>Decal Splatter</b> | Click or tap and drag to rotate, mouse wheel or pinch to zoom, click or tap to shoot paint.</p>
+		<div id="info">
+			<strong>Decal Splatter</strong><br />
+			Click or tap to shoot.</p>
 		</div>
 		</div>
 
 
-<script src="../build/three.min.js"></script>
-<script src="js/controls/OrbitControls.js"></script>
-<script src="js/THREE.DecalGeometry.js"></script>
-<script src="js/libs/dat.gui.min.js"></script>
-
-<script>
-
-var container = document.getElementById( 'container' );
-
-var renderer, scene, helperScene, camera, fov = 45;
-var mesh, decal;
-var projector, raycaster;
-var line;
-var spotLight, pointLight, ambientLight;
-
-var intersection = {
-	intersects: false,
-	point: new THREE.Vector3(),
-	normal: new THREE.Vector3()
-};
-var controls, renderHelpers = false;
-var mouseVector = new THREE.Vector3();
-var mouse = new THREE.Vector2();
-
-var decalMaterial = new THREE.MeshPhongMaterial( { 
-	specular: 0xffffff,
-	shininess: 10,
-	map: THREE.ImageUtils.loadTexture( 'textures/decal/decal-diffuse.png' ), 
-	normalMap: THREE.ImageUtils.loadTexture( 'textures/decal/decal-normal.jpg' ),
-	normalScale: new THREE.Vector2( .15, .15 ),
-	shininess: 30,
-	transparent: true, 
-	depthTest: true, 
-	depthWrite: false, 
-	polygonOffset: true,
-	polygonOffsetFactor: -4, 
-	wireframe: false 
-});
-/*decalMaterial = new THREE.MeshNormalMaterial( { 
-	transparent: true, 
-	depthTest: true, 
-	depthWrite: false, 
-	polygonOffset: true,
-	polygonOffsetFactor: -4, 
-	shading: THREE.SmoothShading
-});*/
-var decals = [];
-var decalHelper, mouseHelper;
-var p = new THREE.Vector3( 0, 0, 0 );
-var r = new THREE.Vector3( 0, 0, 0 );
-var s = new THREE.Vector3( 10, 10, 10 );
-var up = new THREE.Vector3( 0, 1, 0 );
-var check = new THREE.Vector3( 1, 1, 1 );
-
-var params = {
-	projection: 'normal',
-	minScale: 10,
-	maxScale: 20,
-	rotate: true,
-	clear: function() {
-		removeDecals();
-	}
-};
-
-window.addEventListener( 'load', init );
-
-function init() {
-
-	renderer = new THREE.WebGLRenderer( { antialias: true });
-	renderer.setSize( window.innerWidth, window.innerHeight );	
-
-	container.appendChild( renderer.domElement );
+		<script src="../build/three.min.js"></script>
+		<script src="js/geometries/DecalGeometry.js"></script>
+		<script src="js/controls/OrbitControls.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<script>
+
+		var container = document.getElementById( 'container' );
+
+		var renderer, scene, helperScene, camera, fov = 45;
+		var mesh, decal;
+		var projector, raycaster;
+		var line;
+		var spotLight, pointLight, ambientLight;
+
+		var intersection = {
+			intersects: false,
+			point: new THREE.Vector3(),
+			normal: new THREE.Vector3()
+		};
+		var controls, renderHelpers = false;
+		var mouseVector = new THREE.Vector3();
+		var mouse = new THREE.Vector2();
+
+		var decalMaterial = new THREE.MeshPhongMaterial( {
+			specular: 0xffffff,
+			shininess: 10,
+			map: THREE.ImageUtils.loadTexture( 'textures/decal/decal-diffuse.png' ),
+			normalMap: THREE.ImageUtils.loadTexture( 'textures/decal/decal-normal.jpg' ),
+			normalScale: new THREE.Vector2( .15, .15 ),
+			shininess: 30,
+			transparent: true,
+			depthTest: true,
+			depthWrite: false,
+			polygonOffset: true,
+			polygonOffsetFactor: -4,
+			wireframe: false
+		});
+		/*decalMaterial = new THREE.MeshNormalMaterial( {
+			transparent: true,
+			depthTest: true,
+			depthWrite: false,
+			polygonOffset: true,
+			polygonOffsetFactor: -4,
+			shading: THREE.SmoothShading
+		});*/
+		var decals = [];
+		var decalHelper, mouseHelper;
+		var p = new THREE.Vector3( 0, 0, 0 );
+		var r = new THREE.Vector3( 0, 0, 0 );
+		var s = new THREE.Vector3( 10, 10, 10 );
+		var up = new THREE.Vector3( 0, 1, 0 );
+		var check = new THREE.Vector3( 1, 1, 1 );
+
+		var params = {
+			projection: 'normal',
+			minScale: 10,
+			maxScale: 20,
+			rotate: true,
+			clear: function() {
+				removeDecals();
+			}
+		};
+
+		window.addEventListener( 'load', init );
+
+		function init() {
+
+			renderer = new THREE.WebGLRenderer( { antialias: true });
+			renderer.setSize( window.innerWidth, window.innerHeight );
+
+			container.appendChild( renderer.domElement );
 	
 	
-	scene = new THREE.Scene();
-	helperScene = new THREE.Scene();
+			scene = new THREE.Scene();
+			helperScene = new THREE.Scene();
 
 
-	camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
-	camera.position.z = 100;
-	camera.target = new THREE.Vector3();
-	controls = new THREE.OrbitControls( camera, renderer.domElement );
+			camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
+			camera.position.z = 100;
+			camera.target = new THREE.Vector3();
+			controls = new THREE.OrbitControls( camera, renderer.domElement );
 	
 	
-	scene.add( camera );
+			scene.add( camera );
 
 
-	ambientLight = new THREE.AmbientLight( 0x111111 );
-	scene.add( ambientLight );
+			ambientLight = new THREE.AmbientLight( 0x111111 );
+			scene.add( ambientLight );
 
 
-	pointLight = new THREE.PointLight( 0xff0000 );
-	pointLight.position.z = 10000;
-	pointLight.distance = 4000;
-	scene.add( pointLight );
+			pointLight = new THREE.PointLight( 0xff0000 );
+			pointLight.position.z = 10000;
+			pointLight.distance = 4000;
+			scene.add( pointLight );
 
 
-	pointLight2 = new THREE.PointLight( 0xff5500 );
-	pointLight2.position.z = 1000;
-	pointLight2.distance = 2000;
-	scene.add( pointLight2 );
+			pointLight2 = new THREE.PointLight( 0xff5500 );
+			pointLight2.position.z = 1000;
+			pointLight2.distance = 2000;
+			scene.add( pointLight2 );
 
 
-	pointLight3 = new THREE.PointLight( 0x0000ff );
-	pointLight3.position.x = -1000;
-	pointLight3.position.z = 1000;
-	pointLight3.distance = 2000;
-	scene.add( pointLight3 );
+			pointLight3 = new THREE.PointLight( 0x0000ff );
+			pointLight3.position.x = -1000;
+			pointLight3.position.z = 1000;
+			pointLight3.distance = 2000;
+			scene.add( pointLight3 );
 
 
-	spotLight = new THREE.SpotLight( 0xaaaaaa );
-	spotLight.position.set( 100, 50, 100 );
-	scene.add( spotLight );
+			spotLight = new THREE.SpotLight( 0xaaaaaa );
+			spotLight.position.set( 100, 50, 100 );
+			scene.add( spotLight );
 
 
-	line = new THREE.Line( new THREE.Geometry( ), new THREE.LineBasicMaterial( { linewidth: 4 }) );
-	line.geometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
-	line.geometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
-	scene.add( line );
+			line = new THREE.Line( new THREE.Geometry( ), new THREE.LineBasicMaterial( { linewidth: 4 }) );
+			line.geometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
+			line.geometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
+			scene.add( line );
 
 
-	loadLeePerrySmith();
+			loadLeePerrySmith();
 
 
-	projector = new THREE.Projector();
-	raycaster = new THREE.Raycaster();
+			projector = new THREE.Projector();
+			raycaster = new THREE.Raycaster();
 
 
-	mouseHelper = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 10 ), new THREE.MeshNormalMaterial() );
-	scene.add( mouseHelper );
-	mouseHelper.visible = false;
+			mouseHelper = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 10 ), new THREE.MeshNormalMaterial() );
+			scene.add( mouseHelper );
+			mouseHelper.visible = false;
 
 
-	window.addEventListener( 'resize', onWindowResize, false );
+			window.addEventListener( 'resize', onWindowResize, false );
 
 
-	var moved = false;
+			var moved = false;
 
 
-	controls.addEventListener( 'change', function() {
+			controls.addEventListener( 'change', function() {
 
 
-		moved = true;
+				moved = true;
 
 
-	} );
+			} );
 
 
-	window.addEventListener( 'mousedown', function () {
+			window.addEventListener( 'mousedown', function () {
 
 
-		moved = false;
+				moved = false;
 	
 	
-	}, false );
+			}, false );
 
 
-	window.addEventListener( 'mouseup', function() {
+			window.addEventListener( 'mouseup', function() {
 
 
-		checkIntersection();
-		if( !moved ) shoot();
+				checkIntersection();
+				if( !moved ) shoot();
 
 
-	} );
+			} );
 
 
-    window.addEventListener( 'mousemove', onTouchMove );
-    window.addEventListener( 'touchmove', onTouchMove );
+			window.addEventListener( 'mousemove', onTouchMove );
+			window.addEventListener( 'touchmove', onTouchMove );
 
 
-    function onTouchMove( event ) {
+			function onTouchMove( event ) {
 
 
-        if( event.changedTouches ) {
-            x = event.changedTouches[ 0 ].pageX;
-            y = event.changedTouches[ 0 ].pageY;
-        } else {
-            x = event.clientX;
-            y = event.clientY;
-        }
+				if( event.changedTouches ) {
+					x = event.changedTouches[ 0 ].pageX;
+					y = event.changedTouches[ 0 ].pageY;
+				} else {
+					x = event.clientX;
+					y = event.clientY;
+				}
 		
 		
-		mouse.x = ( x / window.innerWidth ) * 2 - 1;
-		mouse.y = - ( y / window.innerHeight ) * 2 + 1;
+				mouse.x = ( x / window.innerWidth ) * 2 - 1;
+				mouse.y = - ( y / window.innerHeight ) * 2 + 1;
 
 
-		checkIntersection();
+				checkIntersection();
 
 
-    }
+			}
 
 
-    function checkIntersection() {
+			function checkIntersection() {
 
 
-    	if( !mesh ) return;
-    	
-    	mouseVector.set( mouse.x, mouse.y, 1 );
-		projector.unprojectVector( mouseVector, camera );
+				if( !mesh ) return;
+		
+				mouseVector.set( mouse.x, mouse.y, 1 );
+				projector.unprojectVector( mouseVector, camera );
 
 
-		raycaster.set( camera.position, mouseVector.sub( camera.position ).normalize() );
+				raycaster.set( camera.position, mouseVector.sub( camera.position ).normalize() );
 
 
-		var intersects = raycaster.intersectObjects( [ mesh ] );
+				var intersects = raycaster.intersectObjects( [ mesh ] );
 
 
-		if ( intersects.length > 0 ) {
+				if ( intersects.length > 0 ) {
 
 
-			var p = intersects[ 0 ].point;
-			mouseHelper.position.copy( p );
-			intersection.point.copy( p );
-			var n = intersects[ 0 ].face.normal.clone();
-			n.multiplyScalar( 10 );
-			n.add( intersects[ 0 ].point );
-			intersection.normal.copy( intersects[ 0 ].face.normal );
-			mouseHelper.lookAt( n );
+					var p = intersects[ 0 ].point;
+					mouseHelper.position.copy( p );
+					intersection.point.copy( p );
+					var n = intersects[ 0 ].face.normal.clone();
+					n.multiplyScalar( 10 );
+					n.add( intersects[ 0 ].point );
+					intersection.normal.copy( intersects[ 0 ].face.normal );
+					mouseHelper.lookAt( n );
 
 
-			line.geometry.vertices[ 0 ].copy( intersection.point );
-			line.geometry.vertices[ 1 ].copy( n );
-			line.geometry.verticesNeedUpdate = true;
+					line.geometry.vertices[ 0 ].copy( intersection.point );
+					line.geometry.vertices[ 1 ].copy( n );
+					line.geometry.verticesNeedUpdate = true;
 
 
-			intersection.intersects = true;
+					intersection.intersects = true;
 
 
-		} else {
+				} else {
 
 
-			intersection.intersects = false;
+					intersection.intersects = false;
 
 
-		}
+				}
 
 
-    }
+			}
 	
 	
-	var gui = new dat.GUI();
+			var gui = new dat.GUI();
 
 
-	gui.add( params, 'projection', { 'From cam to mesh': 'camera', 'Normal to mesh': 'normal' } );
-	gui.add( params, 'minScale', 1, 30 );
-	gui.add( params, 'maxScale', 1, 30 );
-	gui.add( params, 'rotate' );
-	gui.add( params, 'clear' );
-	gui.open();
+			gui.add( params, 'projection', { 'From cam to mesh': 'camera', 'Normal to mesh': 'normal' } );
+			gui.add( params, 'minScale', 1, 30 );
+			gui.add( params, 'maxScale', 1, 30 );
+			gui.add( params, 'rotate' );
+			gui.add( params, 'clear' );
+			gui.open();
 
 
-	onWindowResize();
-	render();
+			onWindowResize();
+			render();
 	
 	
-}
+		}
 
 
-function loadLeePerrySmith( callback ) {
+		function loadLeePerrySmith( callback ) {
 
 
-	var loader = new THREE.JSONLoader();
+			var loader = new THREE.JSONLoader();
 
 
-    loader.load( 'obj/leeperrysmith/LeePerrySmith.js', function( geometry ) {
+			loader.load( 'obj/leeperrysmith/LeePerrySmith.js', function( geometry ) {
 
 
-    	geometry.verticesNeedUpdate = true;
-		geometry.elementsNeedUpdate = true;
-		geometry.morphTargetsNeedUpdate = true;
-		geometry.uvsNeedUpdate = true;
-		geometry.normalsNeedUpdate = true;
-		geometry.colorsNeedUpdate = true;
-		geometry.tangentsNeedUpdate = true;
+				geometry.verticesNeedUpdate = true;
+				geometry.elementsNeedUpdate = true;
+				geometry.morphTargetsNeedUpdate = true;
+				geometry.uvsNeedUpdate = true;
+				geometry.normalsNeedUpdate = true;
+				geometry.colorsNeedUpdate = true;
+				geometry.tangentsNeedUpdate = true;
 
 
-		var material = new THREE.MeshPhongMaterial( {
-			map: THREE.ImageUtils.loadTexture( 'obj/leeperrysmith/Map-COL.jpg' ),
-			specularMap: THREE.ImageUtils.loadTexture( 'obj/leeperrysmith/Map-SPEC.jpg' ),
-			normalMap: THREE.ImageUtils.loadTexture( 'obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg' ),
-			shininess: 10
-		} );
+				var material = new THREE.MeshPhongMaterial( {
+					map: THREE.ImageUtils.loadTexture( 'obj/leeperrysmith/Map-COL.jpg' ),
+					specularMap: THREE.ImageUtils.loadTexture( 'obj/leeperrysmith/Map-SPEC.jpg' ),
+					normalMap: THREE.ImageUtils.loadTexture( 'obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg' ),
+					shininess: 10
+				} );
 
 
-		mesh = new THREE.Mesh( geometry, material );
-		scene.add( mesh );
-		mesh.scale.set( 10, 10, 10 );
+				mesh = new THREE.Mesh( geometry, material );
+				scene.add( mesh );
+				mesh.scale.set( 10, 10, 10 );
 
 
-		//scene.add( new THREE.FaceNormalsHelper( mesh, 1 ) );
-		//scene.add( new THREE.VertexNormalsHelper( mesh, 1 ) );
+				//scene.add( new THREE.FaceNormalsHelper( mesh, 1 ) );
+				//scene.add( new THREE.VertexNormalsHelper( mesh, 1 ) );
 
 
-    } );
+			} );
 
 
-}
+		}
 
 
-function shoot() {
+		function shoot() {
 
 
-	if( params.projection == 'camera' ) {
+			if( params.projection == 'camera' ) {
 
 
-		var dir = camera.target.clone();
-		dir.sub( camera.position );
+				var dir = camera.target.clone();
+				dir.sub( camera.position );
 
 
-		p = intersection.point;
+				p = intersection.point;
 
 
-		var m = new THREE.Matrix4();
-		var c = dir.clone();
-		c.negate();
-		c.multiplyScalar( 10 );
-		c.add( p );
-		m.lookAt( p, c, up );
-		m = m.extractRotation( m );
+				var m = new THREE.Matrix4();
+				var c = dir.clone();
+				c.negate();
+				c.multiplyScalar( 10 );
+				c.add( p );
+				m.lookAt( p, c, up );
+				m = m.extractRotation( m );
 
 
-		dummy = new THREE.Object3D();
-		dummy.rotation.setFromRotationMatrix( m );
-		r.set( dummy.rotation.x, dummy.rotation.y, dummy.rotation.z );
+				dummy = new THREE.Object3D();
+				dummy.rotation.setFromRotationMatrix( m );
+				r.set( dummy.rotation.x, dummy.rotation.y, dummy.rotation.z );
 
 
-	} else {
+			} else {
 
 
-		p = intersection.point;
-		r.copy( mouseHelper.rotation );
+				p = intersection.point;
+				r.copy( mouseHelper.rotation );
 
 
-	}
+			}
 
 
-	var scale = params.minScale + Math.random() * ( params.maxScale - params.minScale );
-	s.set( scale, scale, scale );
+			var scale = params.minScale + Math.random() * ( params.maxScale - params.minScale );
+			s.set( scale, scale, scale );
 
 
-	if( params.rotate) r.z = Math.random() * 2 * Math.PI;
+			if( params.rotate) r.z = Math.random() * 2 * Math.PI;
 
 
-	var m = new THREE.Mesh( new THREE.DecalGeometry( mesh, p, r, s, check ), decalMaterial );
-	decals.push( m );
-	scene.add( m );
+			var m = new THREE.Mesh( new THREE.DecalGeometry( mesh, p, r, s, check ), decalMaterial );
+			decals.push( m );
+			scene.add( m );
 
 
-}
+		}
 
 
-function removeDecals() {
+		function removeDecals() {
 
 
-	decals.forEach( function( d ) {
-		scene.remove( d );
-		d = null;
-	} );
-	decals = [];
+			decals.forEach( function( d ) {
+				scene.remove( d );
+				d = null;
+			} );
+			decals = [];
 
 
-};
+		};
 
 
-function mergeDecals() {
+		function mergeDecals() {
 
 
-	var merge = {};
-	decals.forEach(function (decal) {
+			var merge = {};
+			decals.forEach(function (decal) {
 		
 		
-		var uuid = decal.material.uuid;
-		var d = merge[uuid] = merge[uuid] || {};
-		d.material = d.material || decal.material;
-		d.geometry = d.geometry || new THREE.Geometry();
-		d.geometry.merge(decal.geometry, decal.matrix);
+				var uuid = decal.material.uuid;
+				var d = merge[uuid] = merge[uuid] || {};
+				d.material = d.material || decal.material;
+				d.geometry = d.geometry || new THREE.Geometry();
+				d.geometry.merge(decal.geometry, decal.matrix);
 		
 		
-	});
+			});
 
 
-	removeDecals();
+			removeDecals();
 
 
-	for (var key in merge) {
+			for (var key in merge) {
 		
 		
-		var d = merge[key];
-		var mesh = new THREE.Mesh(d.geometry, d.material);
-		scene.add(mesh);
-		decals.push(mesh);
+				var d = merge[key];
+				var mesh = new THREE.Mesh(d.geometry, d.material);
+				scene.add(mesh);
+				decals.push(mesh);
 	
 	
-	}
+			}
 
 
-}
+		}
 
 
-function onWindowResize() {
+		function onWindowResize() {
 
 
-	camera.aspect = window.innerWidth / window.innerHeight;
-	camera.updateProjectionMatrix();
+			camera.aspect = window.innerWidth / window.innerHeight;
+			camera.updateProjectionMatrix();
 
 
-	renderer.setSize( window.innerWidth, window.innerHeight );
+			renderer.setSize( window.innerWidth, window.innerHeight );
 
 
-}
+		}
 
 
-function render() {
+		function render() {
 
 
-	requestAnimationFrame( render );
+			requestAnimationFrame( render );
 	
 	
-	renderer.autoClear = false;
-	renderer.render( scene, camera );
-	if( renderHelpers ) renderer.render( helperScene, camera );
+			renderer.autoClear = false;
+			renderer.render( scene, camera );
+			if( renderHelpers ) renderer.render( helperScene, camera );
 
 
-}
+		}
 
 
-</script>
+		</script>
 
 
 	</body>
 	</body>
 </html>
 </html>