瀏覽代碼

Merge branch 'dev' into refactor_animation_blending

Ian Kerr 11 年之前
父節點
當前提交
68b56d736c
共有 36 個文件被更改,包括 1196 次插入1029 次删除
  1. 1 1
      README.md
  2. 147 410
      build/three.js
  3. 106 129
      build/three.min.js
  4. 3 29
      docs/api/extras/GeometryUtils.html
  5. 19 13
      docs/manual/introduction/Creating-a-scene.html
  6. 2 2
      editor/js/libs/ui.three.js
  7. 6 0
      examples/canvas_particles_shapes.html
  8. 1 0
      examples/index.html
  9. 8 1
      examples/js/Detector.js
  10. 2 1
      examples/js/effects/OculusRiftEffect.js
  11. 263 0
      examples/js/geometries/DecalGeometry.js
  12. 66 4
      examples/js/loaders/STLLoader.js
  13. 1 1
      examples/js/loaders/ctm/CTMLoader.js
  14. 7 0
      examples/js/loaders/ctm/ctm.js
  15. 7 0
      examples/js/loaders/ctm/lzma.js
  16. 二進制
      examples/models/stl/binary/colored.stl
  17. 二進制
      examples/textures/decal/decal-diffuse.png
  18. 二進制
      examples/textures/decal/decal-normal.jpg
  19. 0 5
      examples/webgl_animation_cloth.html
  20. 355 0
      examples/webgl_decals.html
  21. 25 0
      examples/webgl_loader_stl.html
  22. 1 0
      examples/webgl_test_memory.html
  23. 19 51
      src/core/BufferGeometry.js
  24. 6 32
      src/core/Object3D.js
  25. 1 1
      src/extras/helpers/EdgesHelper.js
  26. 12 9
      src/extras/renderers/plugins/DepthPassPlugin.js
  27. 14 11
      src/extras/renderers/plugins/ShadowMapPlugin.js
  28. 0 4
      src/materials/Material.js
  29. 17 14
      src/objects/Skeleton.js
  30. 101 210
      src/renderers/WebGLRenderer.js
  31. 1 1
      src/renderers/shaders/ShaderChunk/envmap_fragment.glsl
  32. 1 1
      src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl
  33. 1 1
      src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl
  34. 1 1
      src/renderers/shaders/ShaderChunk/envmap_vertex.glsl
  35. 2 0
      src/renderers/shaders/ShaderLib.js
  36. 0 97
      src/scenes/Scene.js

+ 1 - 1
README.md

@@ -5,7 +5,7 @@ three.js
 
 The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies. The library provides <canvas>, <svg>, CSS3D and WebGL renderers.
 
-[Examples](http://threejs.org/) — [Documentation](http://threejs.org/docs/) — [Migrating](https://github.com/mrdoob/three.js/wiki/Migration) — [Help](http://stackoverflow.com/questions/tagged/three.js)
+[Examples](http://threejs.org/examples/) — [Documentation](http://threejs.org/docs/) — [Migrating](https://github.com/mrdoob/three.js/wiki/Migration) — [Help](http://stackoverflow.com/questions/tagged/three.js)
 
 
 ### Usage ###

File diff suppressed because it is too large
+ 147 - 410
build/three.js


File diff suppressed because it is too large
+ 106 - 129
build/three.min.js


+ 3 - 29
docs/api/extras/GeometryUtils.html

@@ -31,26 +31,8 @@
 
 		</div>
 
-		<h3> .randomPointInFace( [page:face Face] , [page:geometry Geometry]  , [page:Boolean useCachedAreas])</h3>
-		<div>
-		Face — Face id<br />
-		Geometry — Geometry that contains the Face  <br />
-		useCachedAreas — Flag to use cached areas. Default : False  <br />
-
-		 returns [page:Int Point]
-
-		</div>
-
-		<h3> .randomPointsInGeometry( [page:geometry Geometry]  , [page:Integer Points])</h3>
-		<div>
-		Geometry — Geometry  <br />
-
-		 returns [page:Int Point]
-
-		</div>
-
-
-		<h3> .triangleArea ( [page:Vector VectorA] , [page:Vector VectorB]  , [page:Vector VectorC]) </h3>
+		
+		<h3> .center ( [page:Vector VectorA] , [page:Vector VectorB]  , [page:Vector VectorC]) </h3>
 
 		<div>
 		VectorA — Vector  <br />
@@ -61,7 +43,7 @@
 
 		</div>
 
-		<h3> .center ( [page:geometry Geometry] ) </h3>
+		<h3> .center ( [page:Geometry geometry] ) </h3>
 
 		<div>
 
@@ -69,14 +51,6 @@
 
 		</div>
 
-		<h3> .triangulateQuads ( [page:geometry Geometry] ) </h3>
-
-		<div>
-
-		Geometry — Geometry to triangulate Quads <br />
-
-		</div>
-
 
 		<h2>Source</h2>
 

+ 19 - 13
docs/manual/introduction/Creating-a-scene.html

@@ -24,7 +24,10 @@
 		&lt;html&gt;
 			&lt;head&gt;
 				&lt;title&gt;My first Three.js app&lt;/title&gt;
-				&lt;style&gt;canvas { width: 100%; height: 100% }&lt;/style&gt;
+				&lt;style&gt;
+					body { margin: 0; }
+					canvas { width: 100%; height: 100% }
+				&lt;/style&gt;
 			&lt;/head&gt;
 			&lt;body&gt;
 				&lt;script src="js/three.min.js"&gt;&lt;/script&gt;
@@ -65,7 +68,7 @@
 		<div><em>"That's all good, but where's that cube you promised?"</em> Let's add it now.</div>
 
 		<code>
-		var geometry = new THREE.BoxGeometry(1,1,1);
+		var geometry = new THREE.BoxGeometry( 1, 1, 1 );
 		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
 		var cube = new THREE.Mesh( geometry, material );
 		scene.add( cube );
@@ -87,8 +90,8 @@
 
 		<code>
 		function render() {
-			requestAnimationFrame(render);
-			renderer.render(scene, camera);
+			requestAnimationFrame( render );
+			renderer.render( scene, camera );
 		}
 		render();
 		</code>
@@ -118,27 +121,30 @@
 		&lt;html&gt;
 			&lt;head&gt;
 				&lt;title&gt;My first Three.js app&lt;/title&gt;
-				&lt;style&gt;canvas { width: 100%; height: 100% }&lt;/style&gt;
+				&lt;style&gt;
+					body { margin: 0; }
+					canvas { width: 100%; height: 100% }
+				&lt;/style&gt;
 			&lt;/head&gt;
 			&lt;body&gt;
 				&lt;script src="js/three.min.js"&gt;&lt;/script&gt;
 				&lt;script&gt;
 					var scene = new THREE.Scene();
-					var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
+					var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
 
 					var renderer = new THREE.WebGLRenderer();
-					renderer.setSize(window.innerWidth, window.innerHeight);
-					document.body.appendChild(renderer.domElement);
+					renderer.setSize( window.innerWidth, window.innerHeight );
+					document.body.appendChild( renderer.domElement );
 
-					var geometry = new THREE.BoxGeometry(1,1,1);
-					var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
-					var cube = new THREE.Mesh(geometry, material);
-					scene.add(cube);
+					var geometry = new THREE.BoxGeometry( 1, 1, 1 );
+					var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+					var cube = new THREE.Mesh( geometry, material );
+					scene.add( cube );
 
 					camera.position.z = 5;
 
 					var render = function () {
-						requestAnimationFrame(render);
+						requestAnimationFrame( render );
 
 						cube.rotation.x += 0.1;
 						cube.rotation.y += 0.1;

+ 2 - 2
editor/js/libs/ui.three.js

@@ -98,7 +98,7 @@ UI.Texture.prototype.setValue = function ( texture ) {
 
 		var image = texture.image;
 
-		if ( image.width > 0 ) {
+		if ( image !== undefined && image.width > 0 ) {
 
 			name.value = texture.sourceFile;
 
@@ -232,7 +232,7 @@ UI.CubeTexture.prototype.setValue = function ( texture ) {
 
 		var image = texture.image[ 0 ];
 
-		if ( image.width > 0 ) {
+		if ( image !== undefined && image.width > 0 ) {
 
 			name.value = texture.sourceFile;
 

+ 6 - 0
examples/canvas_particles_shapes.html

@@ -204,6 +204,12 @@
 
 				sparksEmitter.addCallback("created", onParticleCreated);
 				sparksEmitter.addCallback("dead", onParticleDead);
+				sparksEmitter.addCallback("updated", function( particle ) {
+
+					particle.target.position.copy( particle.position );
+
+				});
+
 				sparksEmitter.start();
 
 				// End Particles

+ 1 - 0
examples/index.html

@@ -120,6 +120,7 @@
 				"webgl_custom_attributes_particles",
 				"webgl_custom_attributes_particles2",
 				"webgl_custom_attributes_particles3",
+				"webgl_decals",
 				"webgl_effects_anaglyph",
 				"webgl_effects_oculusrift",
 				"webgl_effects_parallaxbarrier",

+ 8 - 1
examples/js/Detector.js

@@ -56,4 +56,11 @@ var Detector = {
 
 	}
 
-};
+};
+
+// browserify support
+if ( typeof module === 'object' ) {
+
+	module.exports = Detector;
+
+}

+ 2 - 1
examples/js/effects/OculusRiftEffect.js

@@ -23,6 +23,7 @@ THREE.OculusRiftEffect = function ( renderer, options ) {
 		distortionK : [1.0, 0.22, 0.24, 0.0],
 		chromaAbParameter: [ 0.996, -0.004, 1.014, 0.0]
 	};
+	this.HMD = HMD;
 
 	// Perspective camera
 	var pCamera = new THREE.PerspectiveCamera();
@@ -137,7 +138,7 @@ THREE.OculusRiftEffect = function ( renderer, options ) {
 
 		// Create render target
 		if ( renderTarget ) renderTarget.dispose();
-		renderTarget = new THREE.WebGLRenderTarget( HMD.hResolution*distScale/2, HMD.vResolution*distScale, RTParams );
+		renderTarget = new THREE.WebGLRenderTarget( ( HMD.hResolution * distScale / 2 ) * renderer.devicePixelRatio, ( HMD.vResolution * distScale ) * renderer.devicePixelRatio, RTParams );
 		RTMaterial.uniforms[ "texid" ].value = renderTarget;
 
 	}	

+ 263 - 0
examples/js/geometries/DecalGeometry.js

@@ -0,0 +1,263 @@
+THREE.DecalVertex = function( v, n ) {
+
+	this.vertex = v;
+	this.normal = n;
+
+}
+
+THREE.DecalVertex.prototype.clone = function() {
+
+	return new THREE.DecalVertex( this.vertex.clone(), this.normal.clone() );
+
+}
+
+THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
+
+	THREE.Geometry.call( this );
+
+	if( check === undefined ) check = null;
+	check = check || new THREE.Vector3( 1, 1, 1 );
+
+	this.uvs = [];
+
+	this.cube = new THREE.Mesh( new THREE.BoxGeometry( dimensions.x, dimensions.y, dimensions.z ), new THREE.MeshBasicMaterial() );
+	this.cube.rotation.set( rotation.x, rotation.y, rotation.z );
+	this.cube.position.copy( position );
+	this.cube.scale.set( 1, 1, 1 );
+	this.cube.updateMatrix();
+
+	this.iCubeMatrix = ( new THREE.Matrix4() ).getInverse( this.cube.matrix );
+	
+	this.faceIndices = [ 'a', 'b', 'c', 'd' ];
+
+	this.clipFace = function( inVertices, plane ) {
+
+		var size = .5 * Math.abs( ( dimensions.clone() ).dot( plane ) );
+
+		function clip( v0, v1, p ) {
+
+			var d0 = v0.vertex.dot( p ) - size,
+				d1 = v1.vertex.dot( p ) - size;
+
+			var s = d0 / ( d0 - d1 );
+			var v = new THREE.DecalVertex( 
+				new THREE.Vector3( 
+					v0.vertex.x + s * ( v1.vertex.x - v0.vertex.x ),
+					v0.vertex.y + s * ( v1.vertex.y - v0.vertex.y ),
+					v0.vertex.z + s * ( v1.vertex.z - v0.vertex.z ) 
+				),
+				new THREE.Vector3(
+					v0.normal.x + s * ( v1.normal.x - v0.normal.x ),
+					v0.normal.y + s * ( v1.normal.y - v0.normal.y ),
+					v0.normal.z + s * ( v1.normal.z - v0.normal.z ) 
+				)
+			);
+
+			// need to clip more values (texture coordinates)? do it this way:
+			//intersectpoint.value = a.value + s*(b.value-a.value);
+
+			return v;
+
+		}
+
+		if( inVertices.length === 0 ) return [];
+		var outVertices = [];
+
+		for( var j = 0; j < inVertices.length; j += 3 ) {
+
+			var v1Out, v2Out, v3Out, total = 0;
+
+			var d1 = inVertices[ j + 0 ].vertex.dot( plane ) - size,
+				d2 = inVertices[ j + 1 ].vertex.dot( plane ) - size,
+				d3 = inVertices[ j + 2 ].vertex.dot( plane ) - size;
+
+			v1Out = d1 > 0;
+			v2Out = d2 > 0;
+			v3Out = d3 > 0;
+
+			total = ( v1Out?1:0 ) + ( v2Out?1:0 ) + ( v3Out?1:0 );
+
+			switch( total ) {
+				case 0:{
+					outVertices.push( inVertices[ j ] );
+					outVertices.push( inVertices[ j + 1 ] );
+					outVertices.push( inVertices[ j + 2 ] );
+					break;
+				}
+				case 1:{
+					var nV1, nV2, nV3;
+					if( v1Out ) {
+						nV1 = inVertices[ j + 1 ]; 
+						nV2 = inVertices[ j + 2 ];
+						nV3 = clip( inVertices[ j ], nV1, plane );
+						nV4 = clip( inVertices[ j ], nV2, plane );
+					}
+					if( v2Out ) { 
+						nV1 = inVertices[ j ]; 
+						nV2 = inVertices[ j + 2 ];
+						nV3 = clip( inVertices[ j + 1 ], nV1, plane );
+						nV4 = clip( inVertices[ j + 1 ], nV2, plane );
+						
+						outVertices.push( nV3 );
+						outVertices.push( nV2.clone() );
+						outVertices.push( nV1.clone() );
+
+						outVertices.push( nV2.clone() );
+						outVertices.push( nV3.clone() );
+						outVertices.push( nV4 );
+						break;
+					}
+					if( v3Out ) { 
+						nV1 = inVertices[ j ]; 
+						nV2 = inVertices[ j + 1 ];
+						nV3 = clip( inVertices[ j + 2 ], nV1, plane );
+						nV4 = clip( inVertices[ j + 2 ], nV2, plane );
+					}
+
+					outVertices.push( nV1.clone() );
+					outVertices.push( nV2.clone() );
+					outVertices.push( nV3 );
+
+					outVertices.push( nV4 );
+					outVertices.push( nV3.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 ); 
+						outVertices.push( nV1 );
+						outVertices.push( nV2 );
+						outVertices.push( nV3 );
+					}
+					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( 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;
+				}
+			}
+
+		}
+
+		return outVertices;
+
+	}
+
+	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() ) );
+
+	}
+
+	this.computeDecal = function() {
+
+		var finalVertices = [];
+
+		for( var i = 0; i < mesh.geometry.faces.length; i++ ) {
+
+			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 ] );
+
+			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++ ) {
+
+				var v = vertices[ j ];
+
+				this.uvs.push( new THREE.Vector2(
+					.5 + ( v.vertex.x / dimensions.x ),
+					.5 + ( v.vertex.y / dimensions.y )
+				) );
+
+				vertices[ j ].vertex.applyMatrix4( this.cube.matrix );
+
+			}
+
+			if( vertices.length === 0 ) continue;
+
+			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( [
+				this.uvs[ k ],
+				this.uvs[ k + 1 ], 
+				this.uvs[ k + 2 ]
+			] );
+		
+		}
+
+		this.verticesNeedUpdate = true;
+		this.elementsNeedUpdate = true;
+		this.morphTargetsNeedUpdate = true;
+		this.uvsNeedUpdate = true;
+		this.normalsNeedUpdate = true;
+		this.colorsNeedUpdate = true;
+		this.tangentsNeedUpdate = true;
+		this.computeFaceNormals();
+
+	}
+
+	this.computeDecal();
+
+}
+
+THREE.DecalGeometry.prototype = Object.create( THREE.Geometry.prototype );

+ 66 - 4
examples/js/loaders/STLLoader.js

@@ -8,7 +8,7 @@
  * Supports both binary and ASCII encoded files, with automatic detection of type.
  *
  * Limitations:
- * 	Binary decoding ignores header. There doesn't seem to be much of a use for it.
+ * 	Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL).
  * 	There is perhaps some question as to how valid it is to always assume little-endian-ness.
  * 	ASCII decoding assumes file is UTF-8. Seems to work for the examples...
  *
@@ -21,6 +21,14 @@
  *
  * 	} );
  * 	loader.load( './models/stl/slotted_disk.stl' );
+ *
+ * For binary STLs geometry might contain colors for vertices. To use it:
+ *  ... // use the same code to load STL as above
+ *  var geometry = event.content;
+ *  if (geometry.hasColors) {
+ *    material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
+ *  } else { .... }
+ * var mesh = new THREE.Mesh( geometry, material );
  */
 
 
@@ -103,6 +111,28 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 
 	var reader = new DataView( data );
 	var faces = reader.getUint32( 80, true );
+
+	var r, g, b, hasColors = false, colors;
+	var defaultR, defaultG, defaultB, alpha;
+
+	// process STL header
+	// check for default color in header ("COLOR=rgba" sequence).
+	for (var index = 0; index < 80 - 10; index++) {
+
+		if ((reader.getUint32(index, false) == 0x434F4C4F /*COLO*/) &&
+			(reader.getUint8(index + 4) == 0x52 /*'R'*/) &&
+			(reader.getUint8(index + 5) == 0x3D /*'='*/)) {
+
+				hasColors = true;
+				colors = new Float32Array( faces * 3 * 3);
+
+				defaultR = reader.getUint8(index + 6) / 255;
+				defaultG = reader.getUint8(index + 7) / 255;
+				defaultB = reader.getUint8(index + 8) / 255;
+				alpha = reader.getUint8(index + 9) / 255;
+			}
+		}
+
 	var dataOffset = 84;
 	var faceLength = 12 * 4 + 2;
 
@@ -116,6 +146,26 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 	for ( var face = 0; face < faces; face ++ ) {
 
 		var start = dataOffset + face * faceLength;
+		var normalX = reader.getFloat32(start, true);
+		var normalY = reader.getFloat32(start + 4, true);
+		var normalZ = reader.getFloat32(start + 8, true);
+
+		if (hasColors) {
+
+			var packedColor = reader.getUint16(start + 48, true);
+
+			if ((packedColor & 0x8000) === 0) { // facet has its own unique color
+
+				r = (packedColor & 0x1F) / 31;
+				g = ((packedColor >> 5) & 0x1F) / 31;
+				b = ((packedColor >> 10) & 0x1F) / 31;
+			} else {
+
+				r = defaultR;
+				g = defaultG;
+				b = defaultB;
+			}
+		}
 
 		for ( var i = 1; i <= 3; i ++ ) {
 
@@ -125,9 +175,15 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 			vertices[ offset + 1 ] = reader.getFloat32( vertexstart + 4, true );
 			vertices[ offset + 2 ] = reader.getFloat32( vertexstart + 8, true );
 
-			normals[ offset     ] = reader.getFloat32( start    , true );
-			normals[ offset + 1 ] = reader.getFloat32( start + 4, true );
-			normals[ offset + 2 ] = reader.getFloat32( start + 8, true );
+			normals[ offset     ] = normalX;
+			normals[ offset + 1 ] = normalY;
+			normals[ offset + 2 ] = normalZ;
+
+			if (hasColors) {
+				colors[ offset     ] = r;
+				colors[ offset + 1 ] = g;
+				colors[ offset + 2 ] = b;
+			}
 
 			offset += 3;
 
@@ -138,6 +194,12 @@ THREE.STLLoader.prototype.parseBinary = function ( data ) {
 	geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
 	geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
 
+	if (hasColors) {
+		geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
+		geometry.hasColors = true;
+		geometry.alpha = alpha;
+	}
+
 	return geometry;
 
 };

+ 1 - 1
examples/js/loaders/ctm/CTMLoader.js

@@ -109,7 +109,7 @@ THREE.CTMLoader.prototype.load = function( url, callback, parameters ) {
 
 				if ( parameters.useWorker ) {
 
-					var worker = new Worker( "js/loaders/ctm/CTMWorker.js" );
+					var worker = parameters.worker || new Worker( "js/loaders/ctm/CTMWorker.js" );
 
 					worker.onmessage = function( event ) {
 

+ 7 - 0
examples/js/loaders/ctm/ctm.js

@@ -28,6 +28,13 @@ References:
 
 var CTM = CTM || {};
 
+// browserify support
+if ( typeof module === 'object' ) {
+
+	module.exports = CTM;
+
+}
+
 CTM.CompressionMethod = {
   RAW: 0x00574152,
   MG1: 0x0031474d,

+ 7 - 0
examples/js/loaders/ctm/lzma.js

@@ -1,6 +1,13 @@
 
 var LZMA = LZMA || {};
 
+// browserify support
+if ( typeof module === 'object' ) {
+
+	module.exports = LZMA;
+
+}
+
 LZMA.OutWindow = function(){
   this._windowSize = 0;
 };

二進制
examples/models/stl/binary/colored.stl


二進制
examples/textures/decal/decal-diffuse.png


二進制
examples/textures/decal/decal-normal.jpg


+ 0 - 5
examples/webgl_animation_cloth.html

@@ -181,11 +181,6 @@
 
 				scene.add( light );
 
-				light = new THREE.DirectionalLight( 0x3dff0c, 0.35 );
-				light.position.set( 0, -1, 0 );
-
-				scene.add( light );
-
 				// cloth material
 
 				var clothTexture = THREE.ImageUtils.loadTexture( 'textures/patterns/circuit_pattern.png' );

+ 355 - 0
examples/webgl_decals.html

@@ -0,0 +1,355 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<title>WebGL decals</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #fff;
+				font-family:Monospace;
+				font-size:13px;
+				margin: 0px;
+				text-align:center;
+				overflow: hidden;
+			}
+			#info{ position: absolute; width: 100%; padding: 5px; }
+			#container canvas{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; bottom: 0;}
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info">
+			<strong>Decal Splatter</strong><br />
+			Click or tap to shoot.</p>
+		</div>
+
+		<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 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 decalDiffuse = THREE.ImageUtils.loadTexture( 'textures/decal/decal-diffuse.png' );
+		var decalNormal = THREE.ImageUtils.loadTexture( 'textures/decal/decal-normal.jpg' );
+
+		var decalMaterial = new THREE.MeshPhongMaterial( {
+			specular: 0x444444,
+			map: decalDiffuse,
+			normalMap: decalNormal,
+			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();
+
+			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 );
+
+			var light = new THREE.HemisphereLight( 0xffbbbb, 0x000011 );
+			light.position.set( 1, 0.75, 0.5 );
+			scene.add( light );
+
+			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();
+
+			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;
+
+			window.addEventListener( 'resize', onWindowResize, false );
+
+			var moved = false;
+
+			controls.addEventListener( 'change', function() {
+
+				moved = true;
+
+			} );
+
+			window.addEventListener( 'mousedown', function () {
+
+				moved = false;
+	
+			}, false );
+
+			window.addEventListener( 'mouseup', function() {
+
+				checkIntersection();
+				if( !moved ) shoot();
+
+			} );
+
+			window.addEventListener( 'mousemove', onTouchMove );
+			window.addEventListener( 'touchmove', onTouchMove );
+
+			function onTouchMove( event ) {
+
+				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;
+
+				checkIntersection();
+
+			}
+
+			function checkIntersection() {
+
+				if( !mesh ) return;
+		
+				mouseVector.set( mouse.x, mouse.y, 1 );
+				projector.unprojectVector( mouseVector, camera );
+
+				raycaster.set( camera.position, mouseVector.sub( camera.position ).normalize() );
+
+				var intersects = raycaster.intersectObjects( [ mesh ] );
+
+				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 );
+
+					line.geometry.vertices[ 0 ].copy( intersection.point );
+					line.geometry.vertices[ 1 ].copy( n );
+					line.geometry.verticesNeedUpdate = true;
+
+					intersection.intersects = true;
+
+				} else {
+
+					intersection.intersects = false;
+
+				}
+
+			}
+	
+			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();
+
+			onWindowResize();
+			render();
+	
+		}
+
+		function loadLeePerrySmith( callback ) {
+
+			var loader = new THREE.JSONLoader();
+
+			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;
+
+				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 );
+
+				//scene.add( new THREE.FaceNormalsHelper( mesh, 1 ) );
+				//scene.add( new THREE.VertexNormalsHelper( mesh, 1 ) );
+
+			} );
+
+		}
+
+		function shoot() {
+
+			if( params.projection == 'camera' ) {
+
+				var dir = camera.target.clone();
+				dir.sub( camera.position );
+
+				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 );
+
+				dummy = new THREE.Object3D();
+				dummy.rotation.setFromRotationMatrix( m );
+				r.set( dummy.rotation.x, dummy.rotation.y, dummy.rotation.z );
+
+			} else {
+
+				p = intersection.point;
+				r.copy( mouseHelper.rotation );
+
+			}
+
+			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;
+			
+			var material = decalMaterial.clone();
+			material.color.setHex( Math.random() * 0xffffff );
+
+			var m = new THREE.Mesh( new THREE.DecalGeometry( mesh, p, r, s, check ), material );
+			decals.push( m );
+			scene.add( m );
+
+		}
+
+		function removeDecals() {
+
+			decals.forEach( function( d ) {
+				scene.remove( d );
+				d = null;
+			} );
+			decals = [];
+
+		};
+
+		function mergeDecals() {
+
+			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);
+		
+			});
+
+			removeDecals();
+
+			for (var key in merge) {
+		
+				var d = merge[key];
+				var mesh = new THREE.Mesh(d.geometry, d.material);
+				scene.add(mesh);
+				decals.push(mesh);
+	
+			}
+
+		}
+
+		function onWindowResize() {
+
+			camera.aspect = window.innerWidth / window.innerHeight;
+			camera.updateProjectionMatrix();
+
+			renderer.setSize( window.innerWidth, window.innerHeight );
+
+		}
+
+		function render() {
+
+			requestAnimationFrame( render );
+	
+			renderer.autoClear = false;
+			renderer.render( scene, camera );
+			if( renderHelpers ) renderer.render( helperScene, camera );
+
+		}
+
+		</script>
+
+	</body>
+</html>

+ 25 - 0
examples/webgl_loader_stl.html

@@ -146,6 +146,31 @@
 				} );
 				loader.load( './models/stl/binary/pr2_head_tilt.stl' );
 
+				// Colored binary STL
+				var loaderColored = new THREE.STLLoader();
+				loaderColored.addEventListener( 'load', function ( event ) {
+
+					var geometry = event.content;
+
+					var meshMaterial = material;
+					if (geometry.hasColors) {
+						meshMaterial = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
+					}
+
+					var mesh = new THREE.Mesh( geometry, meshMaterial );
+
+					mesh.position.set( 0.5, 0.2, 0 );
+					mesh.rotation.set( - Math.PI / 2, Math.PI / 2, 0 );
+					mesh.scale.set( 0.3, 0.3, 0.3 );
+
+					mesh.castShadow = true;
+					mesh.receiveShadow = true;
+
+					scene.add( mesh );
+
+				} );
+				loaderColored.load( './models/stl/binary/colored.stl' );
+
 
 				// Lights
 

+ 1 - 0
examples/webgl_test_memory.html

@@ -88,6 +88,7 @@
 
 				// clean up
 
+				mesh.dispose();
 				geometry.dispose();
 				material.dispose();
 				texture.dispose();

+ 19 - 51
src/core/BufferGeometry.js

@@ -230,80 +230,48 @@ THREE.BufferGeometry.prototype = {
 
 	computeBoundingBox: function () {
 
-		if ( this.boundingBox === null ) {
-
-			this.boundingBox = new THREE.Box3();
-
-		}
+		var vector = new THREE.Vector3();
 
-		var positions = this.attributes[ 'position' ].array;
+		return function () {
 
-		if ( positions ) {
+			if ( this.boundingBox === null ) {
 
-			var bb = this.boundingBox;
+				this.boundingBox = new THREE.Box3();
 
-			if ( positions.length >= 3 ) {
-				bb.min.x = bb.max.x = positions[ 0 ];
-				bb.min.y = bb.max.y = positions[ 1 ];
-				bb.min.z = bb.max.z = positions[ 2 ];
 			}
 
-			for ( var i = 3, il = positions.length; i < il; i += 3 ) {
-
-				var x = positions[ i ];
-				var y = positions[ i + 1 ];
-				var z = positions[ i + 2 ];
-
-				// bounding box
-
-				if ( x < bb.min.x ) {
-
-					bb.min.x = x;
-
-				} else if ( x > bb.max.x ) {
-
-					bb.max.x = x;
-
-				}
-
-				if ( y < bb.min.y ) {
-
-					bb.min.y = y;
-
-				} else if ( y > bb.max.y ) {
-
-					bb.max.y = y;
-
-				}
+			var positions = this.attributes[ 'position' ].array;
 
-				if ( z < bb.min.z ) {
+			if ( positions ) {
 
-					bb.min.z = z;
+				var bb = this.boundingBox;
+				bb.makeEmpty();
 
-				} else if ( z > bb.max.z ) {
+				for ( var i = 0, il = positions.length; i < il; i += 3 ) {
 
-					bb.max.z = z;
+					vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
+					bb.expandByPoint( vector );
 
 				}
 
 			}
 
-		}
+			if ( positions === undefined || positions.length === 0 ) {
 
-		if ( positions === undefined || positions.length === 0 ) {
+				this.boundingBox.min.set( 0, 0, 0 );
+				this.boundingBox.max.set( 0, 0, 0 );
 
-			this.boundingBox.min.set( 0, 0, 0 );
-			this.boundingBox.max.set( 0, 0, 0 );
+			}
 
-		}
+			if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
 
-		if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
+				console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.' );
 
-			console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.' );
+			}
 
 		}
 
-	},
+	}(),
 
 	computeBoundingSphere: function () {
 

+ 6 - 32
src/core/Object3D.js

@@ -329,22 +329,6 @@ THREE.Object3D.prototype = {
 
 			this.children.push( object );
 
-			// add to scene
-
-			var scene = this;
-
-			while ( scene.parent !== undefined ) {
-
-				scene = scene.parent;
-
-			}
-
-			if ( scene !== undefined && scene instanceof THREE.Scene )  {
-
-				scene.__addObject( object );
-
-			}
-
 		} else {
 		
 			console.error( "THREE.Object3D.add:", object, "is not an instance of THREE.Object3D." );
@@ -376,22 +360,6 @@ THREE.Object3D.prototype = {
 
 			this.children.splice( index, 1 );
 
-			// remove from scene
-
-			var scene = this;
-
-			while ( scene.parent !== undefined ) {
-
-				scene = scene.parent;
-
-			}
-
-			if ( scene !== undefined && scene instanceof THREE.Scene ) {
-
-				scene.__removeObject( object );
-
-			}
-
 		}
 
 	},
@@ -576,6 +544,12 @@ THREE.Object3D.prototype = {
 
 		return object;
 
+	},
+
+	dispose: function () {
+
+		this.dispatchEvent( { type: 'dispose' } );
+
 	}
 
 };

+ 1 - 1
src/extras/helpers/EdgesHelper.js

@@ -48,7 +48,7 @@ THREE.EdgesHelper = function ( object, hex ) {
 
 	}
 
-	geometry.addAttribute( 'position', new THREE.Float32Attribute( numEdges * 2 * 3, 3 ) );
+	geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( numEdges * 2 * 3 ), 3 ) );
 
 	var coords = geometry.attributes.position.array;
 

+ 12 - 9
src/extras/renderers/plugins/DepthPassPlugin.js

@@ -9,16 +9,21 @@ THREE.DepthPassPlugin = function () {
 
 	var _gl,
 	_renderer,
+	_lights, _webglObjects, _webglObjectsImmediate,
 	_depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
 
 	_frustum = new THREE.Frustum(),
 	_projScreenMatrix = new THREE.Matrix4(),
 	_renderList = [];
 
-	this.init = function ( renderer ) {
+	this.init = function ( renderer, lights, webglObjects, webglObjectsImmediate ) {
 
 		_gl = renderer.context;
 		_renderer = renderer;
+		_lights = lights;
+
+		_webglObjects = webglObjects;
+		_webglObjectsImmediate = webglObjectsImmediate;
 
 		var depthShader = THREE.ShaderLib[ "depthRGBA" ];
 		var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
@@ -123,11 +128,11 @@ THREE.DepthPassPlugin = function () {
 
 			if ( buffer instanceof THREE.BufferGeometry ) {
 
-				_renderer.renderBufferDirect( camera, scene.__lights, fog, material, buffer, object );
+				_renderer.renderBufferDirect( camera, _lights, fog, material, buffer, object );
 
 			} else {
 
-				_renderer.renderBuffer( camera, scene.__lights, fog, material, buffer, object );
+				_renderer.renderBuffer( camera, _lights, fog, material, buffer, object );
 
 			}
 
@@ -136,18 +141,16 @@ THREE.DepthPassPlugin = function () {
 
 		// set matrices and render immediate objects
 
-		renderList = scene.__webglObjectsImmediate;
-
-		for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
+		for ( j = 0, jl = _webglObjectsImmediate.length; j < jl; j ++ ) {
 
-			webglObject = renderList[ j ];
+			webglObject = _webglObjectsImmediate[ j ];
 			object = webglObject.object;
 
 			if ( object.visible ) {
 
 				object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
 
-				_renderer.renderImmediateObject( camera, scene.__lights, fog, _depthMaterial, object );
+				_renderer.renderImmediateObject( camera, _lights, fog, _depthMaterial, object );
 
 			}
 
@@ -167,7 +170,7 @@ THREE.DepthPassPlugin = function () {
 		
 		if ( object.visible ) {
 	
-			var webglObjects = scene.__webglObjects[object.id];
+			var webglObjects = _webglObjects[object.id];
 	
 			if (webglObjects && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) {
 		

+ 14 - 11
src/extras/renderers/plugins/ShadowMapPlugin.js

@@ -6,6 +6,7 @@ THREE.ShadowMapPlugin = function () {
 
 	var _gl,
 	_renderer,
+	_lights, _webglObjects, _webglObjectsImmediate,
 	_depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
 
 	_frustum = new THREE.Frustum(),
@@ -18,10 +19,14 @@ THREE.ShadowMapPlugin = function () {
 	
 	_renderList = [];
 
-	this.init = function ( renderer ) {
+	this.init = function ( renderer, lights, webglObjects, webglObjectsImmediate ) {
 
 		_gl = renderer.context;
 		_renderer = renderer;
+		_lights = lights;
+
+		_webglObjects = webglObjects;
+		_webglObjectsImmediate = webglObjectsImmediate;
 
 		var depthShader = THREE.ShaderLib[ "depthRGBA" ];
 		var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
@@ -83,9 +88,9 @@ THREE.ShadowMapPlugin = function () {
 		// 	- skip lights that are not casting shadows
 		//	- create virtual lights for cascaded shadow maps
 
-		for ( i = 0, il = scene.__lights.length; i < il; i ++ ) {
+		for ( i = 0, il = _lights.length; i < il; i ++ ) {
 
-			light = scene.__lights[ i ];
+			light = _lights[ i ];
 
 			if ( ! light.castShadow ) continue;
 
@@ -282,11 +287,11 @@ THREE.ShadowMapPlugin = function () {
 
 				if ( buffer instanceof THREE.BufferGeometry ) {
 
-					_renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object );
+					_renderer.renderBufferDirect( shadowCamera, _lights, fog, material, buffer, object );
 
 				} else {
 
-					_renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object );
+					_renderer.renderBuffer( shadowCamera, _lights, fog, material, buffer, object );
 
 				}
 
@@ -294,18 +299,16 @@ THREE.ShadowMapPlugin = function () {
 
 			// set matrices and render immediate objects
 
-			var renderList = scene.__webglObjectsImmediate;
-
-			for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
+			for ( j = 0, jl = _webglObjectsImmediate.length; j < jl; j ++ ) {
 
-				webglObject = renderList[ j ];
+				webglObject = _webglObjectsImmediate[ j ];
 				object = webglObject.object;
 
 				if ( object.visible && object.castShadow ) {
 
 					object._modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
 
-					_renderer.renderImmediateObject( shadowCamera, scene.__lights, fog, _depthMaterial, object );
+					_renderer.renderImmediateObject( shadowCamera, _lights, fog, _depthMaterial, object );
 
 				}
 
@@ -333,7 +336,7 @@ THREE.ShadowMapPlugin = function () {
 		
 		if ( object.visible ) {
 	
-			var webglObjects = scene.__webglObjects[object.id];
+			var webglObjects = _webglObjects[object.id];
 	
 			if (webglObjects && object.castShadow && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) {
 		

+ 0 - 4
src/materials/Material.js

@@ -32,8 +32,6 @@ THREE.Material = function () {
 
 	this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer
 
-	this.visible = true;
-
 	this.needsUpdate = true;
 
 };
@@ -114,8 +112,6 @@ THREE.Material.prototype = {
 
 		material.overdraw = this.overdraw;
 
-		material.visible = this.visible;
-
 		return material;
 
 	},

+ 17 - 14
src/objects/Skeleton.js

@@ -136,8 +136,7 @@ THREE.Skeleton.prototype.pose = function () {
 				bone.matrix.getInverse( bone.parent.matrixWorld );
 				bone.matrix.multiply( bone.matrixWorld );
 
-			}
-			else {
+			} else {
 
 				bone.matrix.copy( bone.matrixWorld );
 
@@ -151,28 +150,32 @@ THREE.Skeleton.prototype.pose = function () {
 
 };
 
-THREE.Skeleton.prototype.update = function () {
+THREE.Skeleton.prototype.update = ( function () {
 
 	var offsetMatrix = new THREE.Matrix4();
+	
+	return function () {
 
-	// flatten bone matrices to array
+		// flatten bone matrices to array
 
-	for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
+		for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
 
-		// compute the offset between the current and the original transform
+			// compute the offset between the current and the original transform
 
-		var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;
+			var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;
 
-		offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );
-		offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
+			offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );
+			offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
 
-	}
+		}
 
-	if ( this.useVertexTexture ) {
+		if ( this.useVertexTexture ) {
 
-		this.boneTexture.needsUpdate = true;
+			this.boneTexture.needsUpdate = true;
 
-	}
+		}
+		
+	};
 
-};
+} )();
 

+ 101 - 210
src/renderers/WebGLRenderer.js

@@ -27,6 +27,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 	_clearColor = new THREE.Color( 0x000000 ),
 	_clearAlpha = 0;
 	
+	var lights = [];
+	
+	var _webglObjects = {};
+	var _webglObjectsImmediate = [];
+	
 	var opaqueObjects = [];
 	var transparentObjects = [];
 
@@ -406,14 +411,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	this.addPostPlugin = function ( plugin ) {
 
-		plugin.init( this );
+		plugin.init( this, lights, _webglObjects, _webglObjectsImmediate );
 		this.renderPluginsPost.push( plugin );
 
 	};
 
 	this.addPrePlugin = function ( plugin ) {
 
-		plugin.init( this );
+		plugin.init( this, lights, _webglObjects, _webglObjectsImmediate );
 		this.renderPluginsPre.push( plugin );
 
 	};
@@ -432,8 +437,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 		_oldDoubleSided = - 1;
 		_oldFlipSided = - 1;
 
-		initObjects( scene );
-
 		this.shadowMapPlugin.update( scene, camera );
 
 	};
@@ -507,6 +510,16 @@ THREE.WebGLRenderer = function ( parameters ) {
 	};
 
 	// Events
+	
+	var onObjectDispose = function ( event ) {
+
+		var object = event.target;
+
+		object.removeEventListener( 'dispose', onObjectDispose );
+
+		removeObject( object )
+
+	};
 
 	var onGeometryDispose = function ( event ) {
 
@@ -845,19 +858,16 @@ THREE.WebGLRenderer = function ( parameters ) {
 			ntris     = faces3.length * 1,
 			nlines    = faces3.length * 3,
 
-			material = getBufferMaterial( object, geometryGroup ),
-
-			uvType = bufferGuessUVType( material ),
-			normalType = bufferGuessNormalType( material ),
-			vertexColorType = bufferGuessVertexColorType( material );
-
-		// console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
+			material = getBufferMaterial( object, geometryGroup );
 
 		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
+		geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
+		geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
+		geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
 
-		if ( normalType ) {
+		if ( geometry.faceVertexUvs.length > 1 ) {
 
-			geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
+			geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
 
 		}
 
@@ -867,28 +877,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( vertexColorType ) {
-
-			geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
-
-		}
-
-		if ( uvType ) {
-
-			if ( geometry.faceVertexUvs.length > 0 ) {
-
-				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
-
-			}
-
-			if ( geometry.faceVertexUvs.length > 1 ) {
-
-				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
-
-			}
-
-		}
-
 		if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {
 
 			geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
@@ -1004,60 +992,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	function bufferGuessNormalType ( material ) {
-
-		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
-
-		if ( ( material instanceof THREE.MeshBasicMaterial && ! material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
-
-			return false;
-
-		}
-
-		if ( materialNeedsSmoothNormals( material ) ) {
-
-			return THREE.SmoothShading;
-
-		} else {
-
-			return THREE.FlatShading;
-
-		}
-
-	};
-
-	function bufferGuessVertexColorType( material ) {
-
-		if ( material.vertexColors ) {
-
-			return material.vertexColors;
-
-		}
-
-		return false;
-
-	};
-
-	function bufferGuessUVType( material ) {
-
-		// material must use some texture to require uvs
-
-		if ( material.map ||
-				 material.lightMap ||
-				 material.bumpMap ||
-				 material.normalMap ||
-				 material.specularMap ||
-				 material.alphaMap ||
-				 material instanceof THREE.ShaderMaterial ) {
-
-			return true;
-
-		}
-
-		return false;
-
-	};
-
 	//
 
 	function initDirectBuffers( geometry ) {
@@ -1579,11 +1513,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		var normalType = bufferGuessNormalType( material ),
-		vertexColorType = bufferGuessVertexColorType( material ),
-		uvType = bufferGuessUVType( material ),
-
-		needsSmoothNormals = ( normalType === THREE.SmoothShading );
+		var needsSmoothNormals = materialNeedsSmoothNormals( material );
 
 		var f, fl, fi, face,
 		vertexNormals, faceNormal, normal,
@@ -1844,7 +1774,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( dirtyColors && vertexColorType ) {
+		if ( dirtyColors ) {
 
 			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
 
@@ -1853,7 +1783,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 				vertexColors = face.vertexColors;
 				faceColor = face.color;
 
-				if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
+				if ( vertexColors.length === 3 && material.vertexColors === THREE.VertexColors ) {
 
 					c1 = vertexColors[ 0 ];
 					c2 = vertexColors[ 1 ];
@@ -1928,7 +1858,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( dirtyNormals && normalType ) {
+		if ( dirtyNormals ) {
 
 			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
 
@@ -1972,7 +1902,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( dirtyUvs && obj_uvs && uvType ) {
+		if ( dirtyUvs && obj_uvs ) {
 
 			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
 
@@ -2004,7 +1934,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( dirtyUvs && obj_uvs2 && uvType ) {
+		if ( dirtyUvs && obj_uvs2 ) {
 
 			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
 
@@ -2546,8 +2476,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
 
-		if ( material.visible === false ) return;
-
 		var linewidth, a, attribute;
 		var attributeItem, attributeName, attributePointer, attributeSize;
 
@@ -2783,8 +2711,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
 
-		if ( material.visible === false ) return;
-
 		var linewidth, a, attribute, i, il;
 
 		var program = setProgram( camera, lights, fog, material, object );
@@ -3250,7 +3176,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 		webglObject, object,
 		renderList,
 
-		lights = scene.__lights,
 		fog = scene.fog;
 
 		// reset caching for this frame
@@ -3268,7 +3193,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 		if ( camera.parent === undefined ) camera.updateMatrixWorld();
 
 		// update Skeleton objects
-		function updateSkeletons( object ) {
+
+		scene.traverse( function ( object ) {
 
 			if ( object instanceof THREE.SkinnedMesh ) {
 
@@ -3276,23 +3202,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			}
 
-			for ( var i = 0, l = object.children.length; i < l; i ++ ) {
-
-				updateSkeletons( object.children[ i ] );
-
-			}
-
-		}
-
-		updateSkeletons( scene );
+		} );
 
 		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
 
 		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
 		_frustum.setFromMatrix( _projScreenMatrix );
 
-		initObjects( scene );
-
+		lights.length = 0;
 		opaqueObjects.length = 0;
 		transparentObjects.length = 0;
 		
@@ -3324,18 +3241,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		// set matrices for regular objects (frustum culled)
-
-		
-
-
 		// set matrices for immediate objects
 
-		renderList = scene.__webglObjectsImmediate;
-
-		for ( i = 0, il = renderList.length; i < il; i ++ ) {
+		for ( i = 0, il = _webglObjectsImmediate.length; i < il; i ++ ) {
 
-			webglObject = renderList[ i ];
+			webglObject = _webglObjectsImmediate[ i ];
 			object = webglObject.object;
 
 			if ( object.visible ) {
@@ -3359,7 +3269,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			renderObjects( opaqueObjects, camera, lights, fog, true, material );
 			renderObjects( transparentObjects, camera, lights, fog, true, material );
-			renderObjectsImmediate( scene.__webglObjectsImmediate, '', camera, lights, fog, false, material );
+			renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, false, material );
 
 		} else {
 
@@ -3370,12 +3280,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 			this.setBlending( THREE.NoBlending );
 
 			renderObjects( opaqueObjects, camera, lights, fog, false, material );
-			renderObjectsImmediate( scene.__webglObjectsImmediate, 'opaque', camera, lights, fog, false, material );
+			renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, false, material );
 
 			// transparent pass (back-to-front order)
 
 			renderObjects( transparentObjects, camera, lights, fog, true, material );
-			renderObjectsImmediate( scene.__webglObjectsImmediate, 'transparent', camera, lights, fog, true, material );
+			renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, true, material );
 
 		}
 
@@ -3404,33 +3314,49 @@ THREE.WebGLRenderer = function ( parameters ) {
 	function projectObject(scene, object,camera){
 		
 		if ( object.visible === false ) return;
-			
-		var webglObjects = scene.__webglObjects[ object.id ];
 		
-		if ( webglObjects && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
+		if ( object instanceof THREE.Light ) {
+
+			lights.push( object );
+
+		}
+		
+		if ( object instanceof THREE.Scene ) {
+		
+			//
+		
+		} else {
+		
+			initObject( object, scene );
+		
+			var webglObjects = _webglObjects[ object.id ];
+		
+			if ( webglObjects && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
 			
-			updateObject( scene, object );
+				updateObject( object, scene );
 			
-			for ( var i = 0, l = webglObjects.length; i < l; i ++ ) {
+				for ( var i = 0, l = webglObjects.length; i < l; i ++ ) {
 				
-				var webglObject = webglObjects[i];
+					var webglObject = webglObjects[i];
 				
-				unrollBufferMaterial( webglObject );
+					unrollBufferMaterial( webglObject );
 
-				webglObject.render = true;
+					webglObject.render = true;
 
-				if ( _this.sortObjects === true ) {
+					if ( _this.sortObjects === true ) {
 
-					if ( object.renderDepth !== null ) {
+						if ( object.renderDepth !== null ) {
 
-						webglObject.z = object.renderDepth;
+							webglObject.z = object.renderDepth;
 
-					} else {
+						} else {
+
+							_vector3.setFromMatrixPosition( object.matrixWorld );
+							_vector3.applyProjection( _projScreenMatrix );
 
-						_vector3.setFromMatrixPosition( object.matrixWorld );
-						_vector3.applyProjection( _projScreenMatrix );
+							webglObject.z = _vector3.z;
 
-						webglObject.z = _vector3.z;
+						}
 
 					}
 
@@ -3445,7 +3371,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			projectObject( scene, object.children[ i ], camera );
 
 		}
-				
+
 	}
 
 	function renderPlugins( plugins, scene, camera ) {
@@ -3657,49 +3583,19 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	// Objects refresh
-
-	var initObjects = function ( scene ) {
-
-		if ( ! scene.__webglObjects ) {
-
-			scene.__webglObjects = {};
-			scene.__webglObjectsImmediate = [];
-
-		}
-
-		while ( scene.__objectsAdded.length ) {
-
-			addObject( scene.__objectsAdded[ 0 ], scene );
-			scene.__objectsAdded.splice( 0, 1 );
-
-		}
-
-		while ( scene.__objectsRemoved.length ) {
-
-			removeObject( scene.__objectsRemoved[ 0 ], scene );
-			scene.__objectsRemoved.splice( 0, 1 );
-
-		}
-
-	};
-
-	// Objects adding
-
-	function addObject( object, scene ) {
-
-		var g, geometry, geometryGroup;
+	function initObject( object, scene ) {
 
 		if ( object.__webglInit === undefined ) {
 
 			object.__webglInit = true;
+			object.addEventListener( 'dispose', onObjectDispose );
 
 			object._modelViewMatrix = new THREE.Matrix4();
 			object._normalMatrix = new THREE.Matrix3();
 
 		}
 		
-		geometry = object.geometry;
+		var geometry = object.geometry;
 		
 		if ( geometry === undefined ) {
 
@@ -3757,18 +3653,16 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			if ( object instanceof THREE.Mesh ) {
 
-				geometry = object.geometry;
-
 				if ( geometry instanceof THREE.BufferGeometry ) {
 
-					addBuffer( scene.__webglObjects, geometry, object );
+					addBuffer( _webglObjects, geometry, object );
 
 				} else if ( geometry instanceof THREE.Geometry ) {
 
 					for ( var i = 0,l = geometry.geometryGroupsList.length; i<l;i++ ) {
 	
-						geometryGroup = geometry.geometryGroupsList[ i ];
-						addBuffer( scene.__webglObjects, geometryGroup, object );
+						var geometryGroup = geometry.geometryGroupsList[ i ];
+						addBuffer( _webglObjects, geometryGroup, object );
 						
 					}
 				}
@@ -3776,12 +3670,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 			} else if ( object instanceof THREE.Line ||
 						object instanceof THREE.PointCloud ) {
 
-				geometry = object.geometry;
-				addBuffer( scene.__webglObjects, geometry, object );
+				addBuffer( _webglObjects, geometry, object );
 
 			} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
 
-				addBufferImmediate( scene.__webglObjectsImmediate, object );
+				addBufferImmediate( _webglObjectsImmediate, object );
 
 			}
 
@@ -3798,7 +3691,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		if ( geometry.geometryGroups === undefined || geometry.groupsNeedUpdate ) {
 			
-			delete scene.__webglObjects[object.id];
+			delete _webglObjects[object.id];
 			geometry.makeGroups( material instanceof THREE.MeshFaceMaterial, _glExtensionElementIndexUint ? 4294967296 : 65535  );
 			geometry.groupsNeedUpdate = false;
 
@@ -3834,7 +3727,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			}
 			
 			if ( addBuffers || object.__webglActive === undefined ) {
-				addBuffer( scene.__webglObjects, geometryGroup, object );
+				addBuffer( _webglObjects, geometryGroup, object );
 			}
 
 		}
@@ -3875,7 +3768,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	// Objects updates
 
-	function updateObject(scene, object ) {
+	function updateObject( object, scene ) {
 
 		var geometry = object.geometry,
 			geometryGroup, customAttributesDirty, material;
@@ -4003,31 +3896,23 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	// Objects removal
 
-	function removeObject( object, scene ) {
+	function removeObject( object ) {
 
 		if ( object instanceof THREE.Mesh  ||
 			 object instanceof THREE.PointCloud ||
 			 object instanceof THREE.Line ) {
 
-			removeInstancesWebglObjects( scene.__webglObjects, object );
+			delete _webglObjects[ object.id ];
 
 		} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
 
-			removeInstances( scene.__webglObjectsImmediate, object );
+			removeInstances( _webglObjectsImmediate, object );
 
 		}
 
 		delete object.__webglActive;
 
 	};
-	
-	
-
-	function removeInstancesWebglObjects( objlist, object ) {
-
-		delete objlist[ object.id ]; 
-
-	};
 
 	function removeInstances( objlist, object ) {
 
@@ -4045,7 +3930,13 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	// Materials
 
-	this.initMaterial = function ( material, lights, fog, object ) {
+	this.initMaterial = function () {
+	
+		console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
+	
+	};
+
+	function initMaterial( material, lights, fog, object ) {
 
 		material.addEventListener( 'dispose', onMaterialDispose );
 
@@ -4142,8 +4033,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			morphTargets: material.morphTargets,
 			morphNormals: material.morphNormals,
-			maxMorphTargets: this.maxMorphTargets,
-			maxMorphNormals: this.maxMorphNormals,
+			maxMorphTargets: _this.maxMorphTargets,
+			maxMorphNormals: _this.maxMorphNormals,
 
 			maxDirLights: maxLightCount.directional,
 			maxPointLights: maxLightCount.point,
@@ -4151,10 +4042,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 			maxHemiLights: maxLightCount.hemi,
 
 			maxShadows: maxShadows,
-			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow && maxShadows > 0,
-			shadowMapType: this.shadowMapType,
-			shadowMapDebug: this.shadowMapDebug,
-			shadowMapCascade: this.shadowMapCascade,
+			shadowMapEnabled: _this.shadowMapEnabled && object.receiveShadow && maxShadows > 0,
+			shadowMapType: _this.shadowMapType,
+			shadowMapDebug: _this.shadowMapDebug,
+			shadowMapCascade: _this.shadowMapCascade,
 
 			alphaTest: material.alphaTest,
 			metal: material.metal,
@@ -4216,7 +4107,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		if ( program === undefined ) {
 
-			program = new THREE.WebGLProgram( this, code, material, parameters );
+			program = new THREE.WebGLProgram( _this, code, material, parameters );
 			_programs.push( program );
 
 			_this.info.memory.programs = _programs.length;
@@ -4233,7 +4124,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			var id, base = 'morphTarget';
 
-			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
+			for ( i = 0; i < _this.maxMorphTargets; i ++ ) {
 
 				id = base + i;
 
@@ -4253,7 +4144,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			var id, base = 'morphNormal';
 
-			for ( i = 0; i < this.maxMorphNormals; i ++ ) {
+			for ( i = 0; i < _this.maxMorphNormals; i ++ ) {
 
 				id = base + i;
 
@@ -4289,7 +4180,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			if ( material.program ) deallocateMaterial( material );
 
-			_this.initMaterial( material, lights, fog, object );
+			initMaterial( material, lights, fog, object );
 			material.needsUpdate = false;
 
 		}

+ 1 - 1
src/renderers/shaders/ShaderChunk/envmap_fragment.glsl

@@ -2,7 +2,7 @@
 
 	vec3 reflectVec;
 
-	#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )
+	#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
 
 		vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );
 

+ 1 - 1
src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl

@@ -5,7 +5,7 @@
 	uniform float flipEnvMap;
 	uniform int combine;
 
-	#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )
+	#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
 
 		uniform bool useRefract;
 		uniform float refractionRatio;

+ 1 - 1
src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl

@@ -1,4 +1,4 @@
-#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )
+#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )
 
 	varying vec3 vReflect;
 

+ 1 - 1
src/renderers/shaders/ShaderChunk/envmap_vertex.glsl

@@ -1,4 +1,4 @@
-#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )
+#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )
 
 	vec3 worldNormal = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * objectNormal;
 	worldNormal = normalize( worldNormal );

+ 2 - 0
src/renderers/shaders/ShaderLib.js

@@ -293,6 +293,8 @@ THREE.ShaderLib = {
 
 		fragmentShader: [
 
+			"#define PHONG",
+
 			"uniform vec3 diffuse;",
 			"uniform float opacity;",
 

+ 0 - 97
src/scenes/Scene.js

@@ -12,107 +12,10 @@ THREE.Scene = function () {
 	this.autoUpdate = true; // checked by the renderer
 	this.matrixAutoUpdate = false;
 
-	this.__lights = [];
-
-	this.__objectsAdded = [];
-	this.__objectsRemoved = [];
-
 };
 
 THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );
 
-THREE.Scene.prototype.__addObject = function ( object ) {
-
-	if ( object instanceof THREE.Light ) {
-
-		if ( this.__lights.indexOf( object ) === - 1 ) {
-
-			this.__lights.push( object );
-
-		}
-
-		if ( object.target && object.target.parent === undefined ) {
-
-			this.add( object.target );
-
-		}
-
-	} else if ( ! ( object instanceof THREE.Camera || object instanceof THREE.Bone ) ) {
-
-		this.__objectsAdded.push( object );
-
-		// check if previously removed
-
-		var i = this.__objectsRemoved.indexOf( object );
-
-		if ( i !== - 1 ) {
-
-			this.__objectsRemoved.splice( i, 1 );
-
-		}
-
-	}
-
-	this.dispatchEvent( { type: 'objectAdded', object: object } );
-	object.dispatchEvent( { type: 'addedToScene', scene: this } );
-
-	for ( var c = 0; c < object.children.length; c ++ ) {
-
-		this.__addObject( object.children[ c ] );
-
-	}
-
-};
-
-THREE.Scene.prototype.__removeObject = function ( object ) {
-
-	if ( object instanceof THREE.Light ) {
-
-		var i = this.__lights.indexOf( object );
-
-		if ( i !== - 1 ) {
-
-			this.__lights.splice( i, 1 );
-
-		}
-
-		if ( object.shadowCascadeArray ) {
-
-			for ( var x = 0; x < object.shadowCascadeArray.length; x ++ ) {
-
-				this.__removeObject( object.shadowCascadeArray[ x ] );
-
-			}
-
-		}
-
-	} else if ( ! ( object instanceof THREE.Camera ) ) {
-
-		this.__objectsRemoved.push( object );
-
-		// check if previously added
-
-		var i = this.__objectsAdded.indexOf( object );
-
-		if ( i !== - 1 ) {
-
-			this.__objectsAdded.splice( i, 1 );
-
-		}
-
-	}
-
-	this.dispatchEvent( { type: 'objectRemoved', object: object } );
-	object.dispatchEvent( { type: 'removedFromScene', scene: this } );
-
-	for ( var c = 0; c < object.children.length; c ++ ) {
-
-		this.__removeObject( object.children[ c ] );
-
-	}
-
-};
-
 THREE.Scene.prototype.clone = function ( object ) {
 
 	if ( object === undefined ) object = new THREE.Scene();

Some files were not shown because too many files changed in this diff