Browse Source

Merge remote-tracking branch 'remotes/mrdood/dev'

Conflicts:
	build/three.js
	build/three.min.js
Robert Carnecky 13 years ago
parent
commit
fbd22e761e
100 changed files with 5148 additions and 1478 deletions
  1. 161 163
      build/three.min.js
  2. 42 52
      docs/api/core/Matrix4.html
  3. 8 0
      docs/api/core/Object3D.html
  4. 2 2
      docs/api/core/Vector3.html
  5. 2 0
      docs/index.html
  6. 1 1
      docs/page.js
  7. 13 10
      examples/canvas_camera_orthographic.html
  8. 13 10
      examples/canvas_camera_orthographic2.html
  9. 21 35
      examples/canvas_interactive_voxelpainter.html
  10. 13 14
      examples/canvas_materials.html
  11. 13 12
      examples/canvas_performance.html
  12. 13 12
      examples/canvas_sandbox.html
  13. 27 27
      examples/js/ShaderExtras.js
  14. 3 6
      examples/js/ShaderGodRays.js
  15. 58 12
      examples/js/ShaderSkin.js
  16. 85 14
      examples/js/ShaderTerrain.js
  17. 4 4
      examples/js/effects/AnaglyphEffect.js
  18. 4 4
      examples/js/effects/ParallaxBarrierEffect.js
  19. 4 4
      examples/js/loaders/OBJLoader.js
  20. 102 0
      examples/js/loaders/STLLoader.js
  21. 3 3
      examples/js/postprocessing/BloomPass.js
  22. 1 1
      examples/js/postprocessing/DotScreenPass.js
  23. 1 1
      examples/js/postprocessing/FilmPass.js
  24. 1 1
      examples/js/postprocessing/SavePass.js
  25. 1 1
      examples/js/postprocessing/ShaderPass.js
  26. 1 1
      examples/js/postprocessing/TexturePass.js
  27. 3 3
      examples/misc_camera_fly.html
  28. 35 0
      examples/models/skinned/knight.js
  29. 2018 0
      examples/models/stl/slotted_disk.stl
  30. 330 0
      examples/webgl_animation_skinning_morph.html
  31. 167 29
      examples/webgl_buffergeometry.html
  32. 189 0
      examples/webgl_buffergeometry_particles.html
  33. 21 11
      examples/webgl_camera.html
  34. 2 2
      examples/webgl_custom_attributes.html
  35. 0 3
      examples/webgl_custom_attributes_lines.html
  36. 1 1
      examples/webgl_custom_attributes_particles.html
  37. 2 2
      examples/webgl_custom_attributes_particles2.html
  38. 2 2
      examples/webgl_custom_attributes_particles3.html
  39. 37 51
      examples/webgl_geometry_extrude_splines.html
  40. 0 0
      examples/webgl_geometry_subdivision.html
  41. 16 27
      examples/webgl_geometry_text.html
  42. 1 1
      examples/webgl_hdr.html
  43. 8 8
      examples/webgl_interactive_cubes.html
  44. 1 1
      examples/webgl_kinect.html
  45. 324 0
      examples/webgl_lights_hemisphere.html
  46. 3 3
      examples/webgl_loader_ctm.html
  47. 1 1
      examples/webgl_loader_ctm_materials.html
  48. 210 0
      examples/webgl_loader_stl.html
  49. 4 4
      examples/webgl_materials_bumpmap_skin.html
  50. 1 1
      examples/webgl_materials_cars.html
  51. 1 1
      examples/webgl_materials_cars_anaglyph.html
  52. 1 1
      examples/webgl_materials_cars_parallaxbarrier.html
  53. 2 2
      examples/webgl_materials_cubemap.html
  54. 1 1
      examples/webgl_materials_cubemap_balls_reflection.html
  55. 1 1
      examples/webgl_materials_cubemap_balls_reflection_anaglyph.html
  56. 1 1
      examples/webgl_materials_cubemap_balls_refraction.html
  57. 1 1
      examples/webgl_materials_cubemap_balls_refraction_crosseyed.html
  58. 1 1
      examples/webgl_materials_cubemap_dynamic.html
  59. 8 8
      examples/webgl_materials_cubemap_dynamic2.html
  60. 1 1
      examples/webgl_materials_cubemap_escher.html
  61. 1 1
      examples/webgl_materials_cubemap_refraction.html
  62. 4 4
      examples/webgl_materials_normalmap.html
  63. 3 3
      examples/webgl_materials_normalmap2.html
  64. 2 2
      examples/webgl_materials_shaders_fresnel.html
  65. 9 9
      examples/webgl_materials_skin.html
  66. 2 0
      examples/webgl_particles_dynamic.html
  67. 1 1
      examples/webgl_particles_shapes.html
  68. 4 4
      examples/webgl_postprocessing.html
  69. 2 2
      examples/webgl_postprocessing_dof.html
  70. 5 5
      examples/webgl_postprocessing_godrays.html
  71. 1 1
      examples/webgl_rtt.html
  72. 3 3
      examples/webgl_shader2.html
  73. 4 4
      examples/webgl_shader_lava.html
  74. 8 8
      examples/webgl_terrain_dynamic.html
  75. 3 3
      examples/webgl_trackballcamera_earth.html
  76. 29 17
      gui/index.html
  77. 1 1
      src/Three.js
  78. 1 1
      src/cameras/PerspectiveCamera.js
  79. 34 18
      src/core/Object3D.js
  80. 46 73
      src/core/Projector.js
  81. 114 88
      src/core/Ray.js
  82. 54 54
      src/core/Vector3.js
  83. 57 51
      src/core/Vector4.js
  84. 95 15
      src/extras/ShaderUtils.js
  85. 1 1
      src/extras/cameras/CombinedCamera.js
  86. 25 55
      src/extras/geometries/ExtrudeGeometry.js
  87. 2 18
      src/extras/geometries/TextGeometry.js
  88. 25 27
      src/extras/helpers/CameraHelper.js
  89. 9 6
      src/extras/renderers/plugins/ShadowMapPlugin.js
  90. 17 0
      src/lights/HemisphereLight.js
  91. 5 4
      src/loaders/GeometryLoader.js
  92. 2 2
      src/loaders/JSONLoader.js
  93. 4 4
      src/loaders/Loader.js
  94. 9 8
      src/loaders/SceneLoader.js
  95. 37 45
      src/objects/SkinnedMesh.js
  96. 30 38
      src/renderers/CanvasRenderer.js
  97. 282 260
      src/renderers/WebGLRenderer.js
  98. 224 84
      src/renderers/WebGLShaders.js
  99. 1 0
      src/renderers/renderables/RenderableFace3.js
  100. 1 0
      src/renderers/renderables/RenderableFace4.js

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


+ 42 - 52
docs/api/core/Matrix4.html

@@ -135,50 +135,6 @@
 		Flattens this matrix into supplied *flat* array starting from *offset* position in the array.
 		</div>
 
-		<h3>.setTranslation( [page:Float x], [page:Float y], [page:Float z] ) [page:Matrix4]</h3>
-		<div>
-		Sets this matrix as translation transform.
-		</div>
-
-		<h3>.setScale( [page:Float x], [page:Float y], [page:Float z] ) [page:Matrix4]</h3>
-		<div>
-		Sets this matrix as scale transform.
-		</div>
-
-		<h3>.makeRotationX( [page:Float theta] ) [page:Matrix4]</h3>
-		<div>
-		theta — Rotation angle in radians.
-		</div>
-		<div>
-		Sets this matrix as rotation transform around x axis by *theta* radians.
-		</div>
-
-		<h3>.makeRotationY( [page:Float theta] ) [page:Matrix4]</h3>
-		<div>
-		theta — Rotation angle in radians.
-		</div>
-		<div>
-		Sets this matrix as rotation transform around y axis by *theta* radians.
-		</div>
-
-		<h3>.makeRotationZ( [page:Float theta] ) [page:Matrix4]</h3>
-		<div>
-		theta — Rotation angle in radians.
-		</div>
-		<div>
-		Sets this matrix as rotation transform around z axis by *theta* radians.
-		</div>
-
-		<h3>.makeRotationAxis( [page:Vector3 axis], [page:Float theta] ) [page:Matrix4]</h3>
-		<div>
-		axis — Rotation axis.
-		theta — Rotation angle in radians.
-		</div>
-		<div>
-		Sets this matrix as rotation transform around *axis* by *angle* radians.<br />
-		Based on [link:http://www.gamedev.net/reference/articles/article1199.asp].
-		</div>
-
 		<h3>.setPosition( [page:Vector3 v] ) [page:Matrix4]</h3>
 		<div>
 		Sets the position component for this matrix from vector *v*.
@@ -280,19 +236,48 @@
 		Translates this matrix by vector *v*.
 		</div>
 
-		<h3>.clone() [page:Matrix4]</h3>
+		<h3>.makeTranslation( [page:Float x], [page:Float y], [page:Float z] ) [page:Matrix4]</h3>
 		<div>
-		Clones this matrix.
+		Sets this matrix as translation transform.
 		</div>
 
+		<h3>.makeRotationX( [page:Float theta] ) [page:Matrix4]</h3>
+		<div>
+		theta — Rotation angle in radians.
+		</div>
+		<div>
+		Sets this matrix as rotation transform around x axis by *theta* radians.
+		</div>
 
-		<h2>Static methods</h2>
+		<h3>.makeRotationY( [page:Float theta] ) [page:Matrix4]</h3>
+		<div>
+		theta — Rotation angle in radians.
+		</div>
+		<div>
+		Sets this matrix as rotation transform around y axis by *theta* radians.
+		</div>
 
-		<h3>.makeInvert3x3( [page:Matrix4 m] ) [page:Matrix3]</h3>
+		<h3>.makeRotationZ( [page:Float theta] ) [page:Matrix4]</h3>
 		<div>
-		Inverts just the rotation submatrix of matrix *m*.<br />
-		Note: this method returns a reference to the internal 3x3 matrix, make a copy or clone it if you don't use it right away.<br />
-		Based on [link:http://code.google.com/p/webgl-mjs/].
+		theta — Rotation angle in radians.
+		</div>
+		<div>
+		Sets this matrix as rotation transform around z axis by *theta* radians.
+		</div>
+
+		<h3>.makeRotationAxis( [page:Vector3 axis], [page:Float theta] ) [page:Matrix4]</h3>
+		<div>
+		axis — Rotation axis.
+		theta — Rotation angle in radians.
+		</div>
+		<div>
+		Sets this matrix as rotation transform around *axis* by *angle* radians.<br />
+		Based on [link:http://www.gamedev.net/reference/articles/article1199.asp].
+		</div>
+
+		<h3>.makeScale( [page:Float x], [page:Float y], [page:Float z] ) [page:Matrix4]</h3>
+		<div>
+		Sets this matrix as scale transform.
 		</div>
 
 		<h3>.makeFrustum( [page:Float left], [page:Float right], [page:Float bottom], [page:Float top], [page:Float near], [page:Float far] ) [page:Matrix4]</h3>
@@ -305,11 +290,16 @@
 		Creates a perspective projection matrix.
 		</div>
 
-		<h3>.makeOrtho( [page:Float left], [page:Float right], [page:Float bottom], [page:Float top], [page:Float near], [page:Float far] ) [page:Matrix4]</h3>
+		<h3>.makeOrthographic( [page:Float left], [page:Float right], [page:Float bottom], [page:Float top], [page:Float near], [page:Float far] ) [page:Matrix4]</h3>
 		<div>
 		Creates an orthographic projection matrix.
 		</div>
 
+		<h3>.clone() [page:Matrix4]</h3>
+		<div>
+		Clones this matrix.
+		</div>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 8 - 0
docs/api/core/Object3D.html

@@ -170,6 +170,14 @@
 		<div>
 		Gets first child with name matching the argument. Searches whole subgraph recursively if *recursive* is true.
 		</div>
+		
+		<h3>.getDescendants( [page:Array array] )</h3>
+		<div>
+		array - optional argument that returns the the array with descendants.<br />
+		</div>
+		<div>
+		Searches whole subgraph recursively to add all objects in the array.
+		</div>
 
 		<h3>.updateMatrix()</h3>
 		<div>

+ 2 - 2
docs/api/core/Vector3.html

@@ -125,12 +125,12 @@
 		Normalizes this vector.
 		</div>
 
-		<h3>.distanceTo( [page:Vector3 v] ) [page:Vector3]</h3>
+		<h3>.distanceTo( [page:Vector3 v] ) [page:Float]</h3>
 		<div>
 		Computes distance of this vector to *v*.
 		</div>
 
-		<h3>.distanceToSquared( [page:Vector3 v] ) [page:Vector3]</h3>
+		<h3>.distanceToSquared( [page:Vector3 v] ) [page:Float]</h3>
 		<div>
 		Computes squared distance of this vector to *v*.
 		</div>

+ 2 - 0
docs/index.html

@@ -117,6 +117,8 @@
 
 				var path = pages[ name ];
 
+				window.document.title = 'three.js - documentation - ' + name;
+
 				window.location.hash = name;
 				viewer.src = 'api/' + path + '.html';
 

+ 1 - 1
docs/page.js

@@ -11,7 +11,7 @@ var onDocumentLoad = function ( event ) {
 	text = text.replace(/\[page:(\w+) ([\w|\.]+)\]/gi, "<a href=\"javascript:window.parent.goTo('$1')\" title=\"$1\">$2</a>" ); // [page:name title]
 	text = text.replace(/\[link:([\w|\:|\/|\.|\-|\_]+)\]/gi, "[link:$1 $1]" ); // [link:url] to [link:url title]
 	text = text.replace(/\[link:([\w|\:|\/|\.|\-|\_]+) ([\w|\:|\/|\.|\-|\_]+)\]/gi, "<a href=\"$1\"  target=\"_blank\">$2</a>" ); // [link:url title]
-	text = text.replace(/\*([\w|\"][\w|\ |\-|\/|\+|\-|\(|\)|\=|\,|\.\"]+[\w|\"]|\w)\*/gi, "<strong>$1</strong>" ); // *
+	text = text.replace(/\*([\w|\d|\"|\-|\(][\w|\d|\ |\-|\/|\+|\-|\(|\)|\=|\,|\.\"]*[\w|\d|\"|\)]|\w)\*/gi, "<strong>$1</strong>" ); // *
 
 	document.body.innerHTML = text;
 

+ 13 - 10
examples/canvas_camera_orthographic.html

@@ -49,23 +49,26 @@
 
 				// Grid
 
+				var size = 500, step = 50;
+
 				var geometry = new THREE.Geometry();
-				geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
-				geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
 
-				for ( var i = 0; i <= 20; i ++ ) {
+				for ( var i = - size; i <= size; i += step ) {
 
-					var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
-					line.position.z = ( i * 50 ) - 500;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
+					geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );
 
-					var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
-					line.position.x = ( i * 50 ) - 500;
-					line.rotation.y = 90 * Math.PI / 180;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
+					geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );
 
 				}
 
+				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } );
+
+				var line = new THREE.Line( geometry, material );
+				line.type = THREE.LinePieces;
+				scene.add( line );
+
 				// Cubes
 
 				var geometry = new THREE.CubeGeometry( 50, 50, 50 );

+ 13 - 10
examples/canvas_camera_orthographic2.html

@@ -116,23 +116,26 @@
 
 				// Grid
 
+				var size = 500, step = 50;
+
 				var geometry = new THREE.Geometry();
-				geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
-				geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
 
-				for ( var i = 0; i <= 20; i ++ ) {
+				for ( var i = - size; i <= size; i += step ) {
 
-					var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
-					line.position.z = ( i * 50 ) - 500;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
+					geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );
 
-					var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
-					line.position.x = ( i * 50 ) - 500;
-					line.rotation.y = 90 * Math.PI / 180;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
+					geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );
 
 				}
 
+				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } );
+
+				var line = new THREE.Line( geometry, material );
+				line.type = THREE.LinePieces;
+				scene.add( line );
+
 				// Cubes
 
 				var geometry = new THREE.CubeGeometry( 50, 50, 50 );

+ 21 - 35
examples/canvas_interactive_voxelpainter.html

@@ -25,7 +25,7 @@
 			var camera, scene, renderer;
 			var projector, plane;
 			var mouse2D, mouse3D, ray,
-			rollOveredFace, isShiftDown = false,
+			isShiftDown = false,
 			theta = 45, isCtrlDown = false,
 			target = new THREE.Vector3( 0, 200, 0 );
 
@@ -52,29 +52,33 @@
 
 				// Grid
 
-				var geometry = new THREE.Geometry();
-				geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
-				geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
+				var size = 500, step = 50;
 
-				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } );
+				var geometry = new THREE.Geometry();
 
-				for ( var i = 0; i <= 20; i ++ ) {
+				for ( var i = - size; i <= size; i += step ) {
 
-					var line = new THREE.Line( geometry, material );
-					line.position.z = ( i * 50 ) - 500;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
+					geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );
 
-					var line = new THREE.Line( geometry, material );
-					line.position.x = ( i * 50 ) - 500;
-					line.rotation.y = 90 * Math.PI / 180;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
+					geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );
 
 				}
 
+				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } );
+
+				var line = new THREE.Line( geometry, material );
+				line.type = THREE.LinePieces;
+				scene.add( line );
+
+				//
+
 				projector = new THREE.Projector();
 
-				plane = new THREE.Mesh( new THREE.PlaneGeometry( 1000, 1000 ), new THREE.MeshFaceMaterial() );
+				plane = new THREE.Mesh( new THREE.PlaneGeometry( 1000, 1000 ), new THREE.MeshBasicMaterial() );
 				plane.rotation.x = - Math.PI / 2;
+				plane.visible = false;
 				scene.add( plane );
 
 				mouse2D = new THREE.Vector3( 0, 10000, 0.5 );
@@ -142,6 +146,9 @@
 
 				event.preventDefault();
 
+				mouse3D = projector.unprojectVector( mouse2D.clone(), camera );
+				ray.direction = mouse3D.subSelf( camera.position ).normalize();
+
 				var intersects = ray.intersectObjects( scene.children );
 
 				if ( intersects.length > 0 ) {
@@ -221,27 +228,6 @@
 				camera.position.z = 1400 * Math.cos( theta * Math.PI / 360 );
 				camera.lookAt( target );
 
-				mouse3D = projector.unprojectVector( mouse2D.clone(), camera );
-				ray.direction = mouse3D.subSelf( camera.position ).normalize();
-
-				var intersects = ray.intersectObjects( scene.children );
-
-				if ( intersects.length > 0 ) {
-
-					if ( intersects[ 0 ].face != rollOveredFace ) {
-
-						if ( rollOveredFace ) rollOveredFace.materials = [];
-						rollOveredFace = intersects[ 0 ].face;
-						rollOveredFace.materials = [ new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5 } ) ];
-					}
-
-				} else if ( rollOveredFace ) {
-
-					rollOveredFace.materials = [];
-					rollOveredFace = null;
-
-				}
-
 				renderer.render( scene, camera );
 
 			}

+ 13 - 14
examples/canvas_materials.html

@@ -41,27 +41,26 @@
 
 				// Grid
 
-				var geometry = new THREE.Geometry();
-				geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
-				geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
+				var size = 500, step = 100;
 
-				var material = new THREE.LineBasicMaterial( { color: 0xffffff, opacity: 0.2 } );
+				var geometry = new THREE.Geometry();
 
-				for ( var i = 0; i <= 10; i ++ ) {
+				for ( var i = - size; i <= size; i += step ) {
 
-					var line = new THREE.Line( geometry, material );
-					line.position.y = - 120;
-					line.position.z = ( i * 100 ) - 500;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( - size, - 120, i ) );
+					geometry.vertices.push( new THREE.Vector3(   size, - 120, i ) );
 
-					var line = new THREE.Line( geometry, material );
-					line.position.x = ( i * 100 ) - 500;
-					line.position.y = - 120;
-					line.rotation.y = 90 * Math.PI / 180;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( i, - 120, - size ) );
+					geometry.vertices.push( new THREE.Vector3( i, - 120,   size ) );
 
 				}
 
+				var material = new THREE.LineBasicMaterial( { color: 0xffffff, opacity: 0.2 } );
+
+				var line = new THREE.Line( geometry, material );
+				line.type = THREE.LinePieces;
+				scene.add( line );
+
 				// Spheres
 
 				var geometry = new THREE.SphereGeometry( 100, 14, 7, false );

+ 13 - 12
examples/canvas_performance.html

@@ -42,25 +42,26 @@
 
 				// Grid
 
-				var geometry = new THREE.Geometry();
-				geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
-				geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
+				var size = 500, step = 100;
 
-				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.5 } );
+				var geometry = new THREE.Geometry();
 
-				for ( var i = 0; i <= 10; i ++ ) {
+				for ( var i = - size; i <= size; i += step ) {
 
-					var line = new THREE.Line( geometry, material );
-					line.position.z = ( i * 100 ) - 500;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
+					geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );
 
-					var line = new THREE.Line( geometry, material );
-					line.position.x = ( i * 100 ) - 500;
-					line.rotation.y = 90 * Math.PI / 180;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
+					geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );
 
 				}
 
+				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.5 } );
+
+				var line = new THREE.Line( geometry, material );
+				line.type = THREE.LinePieces;
+				scene.add( line );
+
 				// Spheres
 
 				geometry = new THREE.SphereGeometry( 100, 26, 18 );

+ 13 - 12
examples/canvas_sandbox.html

@@ -66,25 +66,26 @@
 
 				// Grid
 
-				var geometry = new THREE.Geometry();
-				geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
-				geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
+				var size = 500, step = 100;
 
-				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.5 } );
+				var geometry = new THREE.Geometry();
 
-				for ( var i = 0; i <= 10; i ++ ) {
+				for ( var i = - size; i <= size; i += step ) {
 
-					var line = new THREE.Line( geometry, material );
-					line.position.z = ( i * 100 ) - 500;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
+					geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );
 
-					var line = new THREE.Line( geometry, material );
-					line.position.x = ( i * 100 ) - 500;
-					line.rotation.y = 90 * Math.PI / 180;
-					scene.add( line );
+					geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
+					geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );
 
 				}
 
+				var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.5 } );
+
+				var line = new THREE.Line( geometry, material );
+				line.type = THREE.LinePieces;
+				scene.add( line );
+
 				// Spheres
 
 				objects = [];

+ 27 - 27
examples/js/ShaderExtras.js

@@ -39,7 +39,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse: { type: "t", value: 0, texture: null },
+			tDiffuse: { type: "t", value: null },
 			opacity:  { type: "f", value: 1.0 }
 
 		},
@@ -86,7 +86,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse" : 		{ type: "t", value: 0, texture: null },
+			"tDiffuse" : 		{ type: "t", value: null },
 			"uImageIncrement" : { type: "v2", value: new THREE.Vector2( 0.001953125, 0.0 ) },
 			"cKernel" : 		{ type: "fv1", value: [] }
 
@@ -165,7 +165,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse:   { type: "t", value: 0, texture: null },
+			tDiffuse:   { type: "t", value: null },
 			time: 	    { type: "f", value: 0.0 },
 			nIntensity: { type: "f", value: 0.5 },
 			sIntensity: { type: "f", value: 0.05 },
@@ -253,8 +253,8 @@ THREE.ShaderExtras = {
 
 	'bokeh'	: {
 
-	uniforms: { tColor:   { type: "t", value: 0, texture: null },
-				tDepth:   { type: "t", value: 1, texture: null },
+	uniforms: { tColor:   { type: "t", value: null },
+				tDepth:   { type: "t", value: null },
 				focus:    { type: "f", value: 1.0 },
 				aspect:   { type: "f", value: 1.0 },
 				aperture: { type: "f", value: 0.025 },
@@ -367,8 +367,8 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tColor:   { type: "t", value: 0, texture: null },
-			tDepth:   { type: "t", value: 1, texture: null },
+			tColor:   { type: "t", value: null },
+			tDepth:   { type: "t", value: null },
 			focus:    { type: "f", value: 1.0 },
 			maxblur:  { type: "f", value: 1.0 }
 
@@ -424,7 +424,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse: { type: "t", value: 0, texture: null },
+			tDiffuse: { type: "t", value: null },
 			amount:   { type: "f", value: 1.0 }
 
 		},
@@ -477,7 +477,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse: { type: "t", value: 0, texture: null },
+			tDiffuse: { type: "t", value: null },
 			tSize:    { type: "v2", value: new THREE.Vector2( 256, 256 ) },
 			center:   { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) },
 			angle:	  { type: "f", value: 1.57 },
@@ -544,7 +544,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse: { type: "t", value: 0, texture: null },
+			tDiffuse: { type: "t", value: null },
 			offset:   { type: "f", value: 1.0 },
 			darkness: { type: "f", value: 1.0 }
 
@@ -606,7 +606,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse: { type: "t", value: 0, texture: null },
+			tDiffuse: { type: "t", value: null },
 			opacity:  { type: "f", value: 1.0 }
 
 		},
@@ -669,7 +669,7 @@ THREE.ShaderExtras = {
 
 		uniforms : {
 
-			"tDiffuse": 		{ type: "t", value: 0, texture: null },
+			"tDiffuse": 		{ type: "t", value: null },
 			"screenWidth": 		{ type: "f", value: 1024 },
 			"screenHeight": 	{ type: "f", value: 1024 },
 			"sampleDistance": 	{ type: "f", value: 0.94 },
@@ -764,7 +764,7 @@ THREE.ShaderExtras = {
 
 		uniforms : {
 
-			"texture": 	{ type: "t", value: 0, texture: null },
+			"texture": 	{ type: "t", value: null },
 			"delta": 	{ type: "v2", value:new THREE.Vector2( 1, 1 )  }
 
 		},
@@ -871,7 +871,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse": { type: "t", value: 0, texture: null },
+			"tDiffuse": { type: "t", value: null },
 			"h": 		{ type: "f", value: 1.0 / 512.0 }
 
 		},
@@ -923,7 +923,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse": { type: "t", value: 0, texture: null },
+			"tDiffuse": { type: "t", value: null },
 			"v": 		{ type: "f", value: 1.0 / 512.0 }
 
 		},
@@ -984,7 +984,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse": { type: "t", value: 0, texture: null },
+			"tDiffuse": { type: "t", value: null },
 			"h": 		{ type: "f", value: 1.0 / 512.0 },
 			"r": 		{ type: "f", value: 0.35 }
 
@@ -1040,7 +1040,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse": { type: "t", value: 0, texture: null },
+			"tDiffuse": { type: "t", value: null },
 			"v": 		{ type: "f", value: 1.0 / 512.0 },
 			"r": 		{ type: "f", value: 0.35 }
 
@@ -1100,8 +1100,8 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse1: { type: "t", value: 0, texture: null },
-			tDiffuse2: { type: "t", value: 1, texture: null },
+			tDiffuse1: { type: "t", value: null },
+			tDiffuse2: { type: "t", value: null },
 			mixRatio:  { type: "f", value: 0.5 },
 			opacity:   { type: "f", value: 1.0 }
 
@@ -1153,7 +1153,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse": 	{ type: "t", value: 0, texture: null },
+			"tDiffuse": 	{ type: "t", value: null },
 			"resolution": 	{ type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 )  }
 
 		},
@@ -1249,7 +1249,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse": 	{ type: "t", value: 0, texture: null }
+			"tDiffuse": 	{ type: "t", value: null }
 
 		},
 
@@ -1297,7 +1297,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse" : 	{ type: "t", value: 0, texture: null },
+			"tDiffuse" : 	{ type: "t", value: null },
 			"powRGB" :		{ type: "v3", value: new THREE.Vector3( 2, 2, 2 ) },
 			"mulRGB" :		{ type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
 
@@ -1345,7 +1345,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"heightMap"	: { type: "t", value: 0, texture: null },
+			"heightMap"	: { type: "t", value: null },
 			"resolution": { type: "v2", value: new THREE.Vector2( 512, 512 ) },
 			"scale"		: { type: "v2", value: new THREE.Vector2( 1, 1 ) },
 			"height"	: { type: "f", value: 0.05 }
@@ -1405,8 +1405,8 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			"tDiffuse": 	{ type: "t", value: 0, texture: null },
-			"tDepth":   	{ type: "t", value: 1, texture: null },
+			"tDiffuse": 	{ type: "t", value: null },
+			"tDepth":   	{ type: "t", value: null },
 			"size": 		{ type: "v2", value: new THREE.Vector2( 512, 512 ) },
 			"cameraNear":	{ type: "f", value: 1 },
 			"cameraFar":	{ type: "f", value: 100 },
@@ -1655,7 +1655,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse: { type: "t", value: 0, texture: null },
+			tDiffuse: { type: "t", value: null },
 			color:    { type: "c", value: new THREE.Color( 0xffffff ) }
 
 		},
@@ -1704,7 +1704,7 @@ THREE.ShaderExtras = {
 
 		uniforms: {
 
-			tDiffuse: { type: "t", value: 0, texture: null },
+			tDiffuse: { type: "t", value: null },
 			opacity:  { type: "f", value: 1.0 }
 
 		},

+ 3 - 6
examples/js/ShaderGodRays.js

@@ -45,8 +45,7 @@ THREE.ShaderGodRays = {
 
 			tInput: {
 				type: "t",
-				value: 0,
-				texture: null
+				value: null
 			},
 
 			fStepSize: {
@@ -148,14 +147,12 @@ THREE.ShaderGodRays = {
 
 			tColors: {
 				type: "t",
-				value: 0,
-				texture: null
+				value: null
 			},
 
 			tGodRays: {
 				type: "t",
-				value: 1,
-				texture: null
+				value: null
 			},
 
 			fGodRayIntensity: {

+ 58 - 12
examples/js/ShaderSkin.js

@@ -14,7 +14,7 @@ THREE.ShaderSkin = {
 	//		- diffuse map
 	//		- bump map
 	//		- specular map
-	//		- point and directional lights (use with "lights: true" material option)
+	//		- point, directional and hemisphere lights (use with "lights: true" material option)
 	//		- fog (use with "fog: true" material option)
 	//		- shadow maps
 	//
@@ -33,8 +33,8 @@ THREE.ShaderSkin = {
 			"enableBump"	: { type: "i", value: 0 },
 			"enableSpecular": { type: "i", value: 0 },
 
-			"tDiffuse"	: { type: "t", value: 0, texture: null },
-			"tBeckmann"	: { type: "t", value: 1, texture: null },
+			"tDiffuse"	: { type: "t", value: null },
+			"tBeckmann"	: { type: "t", value: null },
 
 			"uDiffuseColor":  { type: "c", value: new THREE.Color( 0xeeeeee ) },
 			"uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
@@ -44,10 +44,10 @@ THREE.ShaderSkin = {
 			"uRoughness": 	  		{ type: "f", value: 0.15 },
 			"uSpecularBrightness": 	{ type: "f", value: 0.75 },
 
-			"bumpMap"	: { type: "t", value: 2, texture: null },
+			"bumpMap"	: { type: "t", value: null },
 			"bumpScale" : { type: "f", value: 1 },
 
-			"specularMap" : { type: "t", value: 3, texture: null },
+			"specularMap" : { type: "t", value: null },
 
 			"offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
 
@@ -92,6 +92,14 @@ THREE.ShaderSkin = {
 
 			"#endif",
 
+			"#if MAX_HEMI_LIGHTS > 0",
+
+				"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
+				"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
+				"uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
+
+			"#endif",
+
 			"#if MAX_POINT_LIGHTS > 0",
 
 				"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
@@ -239,6 +247,38 @@ THREE.ShaderSkin = {
 
 				"#endif",
 
+				// hemisphere lights
+
+				"#if MAX_HEMI_LIGHTS > 0",
+
+					"vec3 hemiTotal = vec3( 0.0 );",
+
+					"for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
+
+						"vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
+						"vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
+
+						"float dotProduct = dot( normal, lVector );",
+						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
+
+						"hemiTotal += uDiffuseColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+						// specular (sky light)
+
+						"float hemiSpecularWeight = 0.0;",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
+
+						// specular (ground light)
+
+						"vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );",
+
+						"specularTotal += uSpecularColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
+
+					"}",
+
+				"#endif",
+
 				// all lights contribution summation
 
 				"vec3 totalLight = vec3( 0.0 );",
@@ -251,6 +291,10 @@ THREE.ShaderSkin = {
 					"totalLight += pointTotal;",
 				"#endif",
 
+				"#if MAX_HEMI_LIGHTS > 0",
+					"totalLight += hemiTotal;",
+				"#endif",
+
 				"gl_FragColor.xyz = gl_FragColor.xyz * ( totalLight + ambientLightColor * uAmbientColor ) + specularTotal;",
 
 				THREE.ShaderChunk[ "shadowmap_fragment" ],
@@ -275,6 +319,8 @@ THREE.ShaderSkin = {
 			"void main() {",
 
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
+				"vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
+
 				"vViewPosition = -mvPosition.xyz;",
 
 				"vNormal = normalMatrix * normal;",
@@ -317,15 +363,15 @@ THREE.ShaderSkin = {
 
 			"passID": { type: "i", value: 0 },
 
-			"tDiffuse"	: { type: "t", value: 0, texture: null },
-			"tNormal"	: { type: "t", value: 1, texture: null },
+			"tDiffuse"	: { type: "t", value: null },
+			"tNormal"	: { type: "t", value: null },
 
-			"tBlur1"	: { type: "t", value: 2, texture: null },
-			"tBlur2"	: { type: "t", value: 3, texture: null },
-			"tBlur3"	: { type: "t", value: 4, texture: null },
-			"tBlur4"	: { type: "t", value: 5, texture: null },
+			"tBlur1"	: { type: "t", value: null },
+			"tBlur2"	: { type: "t", value: null },
+			"tBlur3"	: { type: "t", value: null },
+			"tBlur4"	: { type: "t", value: null },
 
-			"tBeckmann"	: { type: "t", value: 6, texture: null },
+			"tBeckmann"	: { type: "t", value: null },
 
 			"uNormalScale": { type: "f", value: 1.0 },
 

+ 85 - 14
examples/js/ShaderTerrain.js

@@ -9,7 +9,8 @@ THREE.ShaderTerrain = {
 	//	Dynamic terrain shader
 	//		- Blinn-Phong
 	//		- height + normal + diffuse1 + diffuse2 + specular + detail maps
-	//		- point and directional lights (use with "lights: true" material option)
+	//		- point, directional and hemisphere lights (use with "lights: true" material option)
+	//		- shadow maps receiving
 	 ------------------------------------------------------------------------- */
 
 	'terrain' : {
@@ -18,6 +19,7 @@ THREE.ShaderTerrain = {
 
 			THREE.UniformsLib[ "fog" ],
 			THREE.UniformsLib[ "lights" ],
+			THREE.UniformsLib[ "shadowmap" ],
 
 			{
 
@@ -26,12 +28,12 @@ THREE.ShaderTerrain = {
 			"enableSpecular"  : { type: "i", value: 0 },
 			"enableReflection": { type: "i", value: 0 },
 
-			"tDiffuse1"	   : { type: "t", value: 0, texture: null },
-			"tDiffuse2"	   : { type: "t", value: 1, texture: null },
-			"tDetail"	   : { type: "t", value: 2, texture: null },
-			"tNormal"	   : { type: "t", value: 3, texture: null },
-			"tSpecular"	   : { type: "t", value: 4, texture: null },
-			"tDisplacement": { type: "t", value: 5, texture: null },
+			"tDiffuse1"	   : { type: "t", value: null },
+			"tDiffuse2"	   : { type: "t", value: null },
+			"tDetail"	   : { type: "t", value: null },
+			"tNormal"	   : { type: "t", value: null },
+			"tSpecular"	   : { type: "t", value: null },
+			"tDisplacement": { type: "t", value: null },
 
 			"uNormalScale": { type: "f", value: 1.0 },
 
@@ -87,18 +89,31 @@ THREE.ShaderTerrain = {
 			"uniform vec3 ambientLightColor;",
 
 			"#if MAX_DIR_LIGHTS > 0",
+
 				"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
 				"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
+
+			"#endif",
+
+			"#if MAX_HEMI_LIGHTS > 0",
+
+				"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
+				"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
+				"uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
+
 			"#endif",
 
 			"#if MAX_POINT_LIGHTS > 0",
+
 				"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
 				"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
 				"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
+
 			"#endif",
 
 			"varying vec3 vViewPosition;",
 
+			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 
 			"void main() {",
@@ -206,6 +221,47 @@ THREE.ShaderTerrain = {
 
 				"#endif",
 
+				// hemisphere lights
+
+				"#if MAX_HEMI_LIGHTS > 0",
+
+					"vec3 hemiDiffuse  = vec3( 0.0 );",
+					"vec3 hemiSpecular = vec3( 0.0 );" ,
+
+					"for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
+
+						"vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
+						"vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
+
+						// diffuse
+
+						"float dotProduct = dot( normal, lVector );",
+						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
+
+						"hemiDiffuse += uDiffuseColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+						// specular (sky light)
+
+						"float hemiSpecularWeight = 0.0;",
+
+						"vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
+						"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
+						"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );",
+
+						// specular (ground light)
+
+						"vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
+
+						"vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
+						"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
+						"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );",
+
+						"hemiSpecular += uSpecularColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
+
+					"}",
+
+				"#endif",
+
 				// all lights contribution summation
 
 				"vec3 totalDiffuse = vec3( 0.0 );",
@@ -218,6 +274,13 @@ THREE.ShaderTerrain = {
 
 				"#endif",
 
+				"#if MAX_HEMI_LIGHTS > 0",
+
+					"totalDiffuse += hemiDiffuse;",
+					"totalSpecular += hemiSpecular;",
+
+				"#endif",
+
 				"#if MAX_POINT_LIGHTS > 0",
 
 					"totalDiffuse += pointDiffuse;",
@@ -228,6 +291,7 @@ THREE.ShaderTerrain = {
 				//"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor) + totalSpecular;",
 				"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );",
 
+				THREE.ShaderChunk[ "shadowmap_fragment" ],
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 
@@ -258,11 +322,9 @@ THREE.ShaderTerrain = {
 
 			"varying vec3 vViewPosition;",
 
-			"void main() {",
-
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
+			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 
-				"vViewPosition = -mvPosition.xyz;",
+			"void main() {",
 
 				"vNormal = normalize( normalMatrix * normal );",
 
@@ -285,18 +347,27 @@ THREE.ShaderTerrain = {
 
 					"vec3 dv = texture2D( tDisplacement, uvBase ).xyz;",
 					"float df = uDisplacementScale * dv.x + uDisplacementBias;",
-					"vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;",
-					"gl_Position = projectionMatrix * displacedPosition;",
+					"vec3 displacedPosition = normal * df + position;",
+
+					"vec4 mPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
+					"vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
 
 				"#else",
 
-					"gl_Position = projectionMatrix * mvPosition;",
+					"vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
+					"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
 
 				"#endif",
 
+				"gl_Position = projectionMatrix * mvPosition;",
+
+				"vViewPosition = -mvPosition.xyz;",
+
 				"vec3 normalTex = texture2D( tNormal, uvBase ).xyz * 2.0 - 1.0;",
 				"vNormal = normalMatrix * normalTex;",
 
+				THREE.ShaderChunk[ "shadowmap_vertex" ],
+
 			"}"
 
 		].join("\n")

+ 4 - 4
examples/js/effects/AnaglyphEffect.js

@@ -32,8 +32,8 @@ THREE.AnaglyphEffect = function ( renderer ) {
 
 		uniforms: {
 
-			"mapLeft": { type: "t", value: 0, texture: _renderTargetL },
-			"mapRight": { type: "t", value: 1, texture: _renderTargetR }
+			"mapLeft": { type: "t", value: _renderTargetL },
+			"mapRight": { type: "t", value: _renderTargetR }
 
 		},
 
@@ -82,8 +82,8 @@ THREE.AnaglyphEffect = function ( renderer ) {
 		_renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
 		_renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
 
-		_material.uniforms[ "mapLeft" ].texture = _renderTargetL;
-		_material.uniforms[ "mapRight" ].texture = _renderTargetR;
+		_material.uniforms[ "mapLeft" ].value = _renderTargetL;
+		_material.uniforms[ "mapRight" ].value = _renderTargetR;
 
 		renderer.setSize( width, height );
 

+ 4 - 4
examples/js/effects/ParallaxBarrierEffect.js

@@ -32,8 +32,8 @@ THREE.ParallaxBarrierEffect = function ( renderer ) {
 
 		uniforms: {
 
-			"mapLeft": { type: "t", value: 0, texture: _renderTargetL },
-			"mapRight": { type: "t", value: 1, texture: _renderTargetR }
+			"mapLeft": { type: "t", value: _renderTargetL },
+			"mapRight": { type: "t", value: _renderTargetR }
 
 		},
 
@@ -84,8 +84,8 @@ THREE.ParallaxBarrierEffect = function ( renderer ) {
 		_renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
 		_renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
 
-		_material.uniforms[ "mapLeft" ].texture = _renderTargetL;
-		_material.uniforms[ "mapRight" ].texture = _renderTargetR;
+		_material.uniforms[ "mapLeft" ].value = _renderTargetL;
+		_material.uniforms[ "mapRight" ].value = _renderTargetR;
 
 		renderer.setSize( width, height );
 

+ 4 - 4
examples/js/loaders/OBJLoader.js

@@ -141,7 +141,7 @@ THREE.OBJLoader.prototype = {
 				// ["f 1 2 3", "1", "2", "3", undefined]
 
 				if ( result[ 4 ] === undefined ) {
-			
+
 					geometry.faces.push( face3(
 						parseInt( result[ 1 ] ) - 1,
 						parseInt( result[ 2 ] ) - 1,
@@ -170,7 +170,7 @@ THREE.OBJLoader.prototype = {
 				// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
 
 				if ( result[ 10 ] === undefined ) {
-			
+
 					geometry.faces.push( face3(
 						parseInt( result[ 2 ] ) - 1,
 						parseInt( result[ 5 ] ) - 1,
@@ -212,7 +212,7 @@ THREE.OBJLoader.prototype = {
 				// ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
 
 				if ( result[ 13 ] === undefined ) {
-			
+
 					geometry.faces.push( face3(
 						parseInt( result[ 2 ] ) - 1,
 						parseInt( result[ 6 ] ) - 1,
@@ -266,7 +266,7 @@ THREE.OBJLoader.prototype = {
 				// ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
 
 				if ( result[ 10 ] === undefined ) {
-			
+
 					geometry.faces.push( face3(
 						parseInt( result[ 2 ] ) - 1,
 						parseInt( result[ 5 ] ) - 1,

+ 102 - 0
examples/js/loaders/STLLoader.js

@@ -0,0 +1,102 @@
+/**
+ * @author aleeper / http://adamleeper.com/
+ * @author mrdoob / http://mrdoob.com/
+ *
+ * Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
+ *
+ * Limitations: Currently supports ASCII format only
+ *
+ * Usage:
+ * 	var loader = new THREE.STLLoader();
+ * 	loader.addEventListener( 'load', function ( event ) {
+ *
+ * 		var geometry = event.content;
+ * 		scene.add( new THREE.Mesh( geometry ) );
+ *
+ * 	} );
+ * 	loader.load( './models/stl/slotted_disk.stl' );
+ */
+
+
+THREE.STLLoader = function () {
+
+	THREE.EventTarget.call( this );
+
+};
+
+THREE.STLLoader.prototype = {
+
+	constructor: THREE.STLLoader,
+
+	load: function ( url ) {
+
+		var scope = this;
+		var xhr = new XMLHttpRequest();
+
+		xhr.addEventListener( 'load', function ( event ) {
+
+			scope.dispatchEvent( { type: 'load', content: scope.parse( event.target.responseText ) } );
+
+		}, false );
+
+		xhr.addEventListener( 'progress', function ( event ) {
+
+			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
+
+		}, false );
+
+		xhr.addEventListener( 'error', function () {
+
+			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+
+		}, false );
+
+		xhr.open( 'GET', url, true );
+		xhr.send( null );
+
+	},
+
+	parse: function ( data ) {
+
+		var geometry = new THREE.Geometry();
+
+		var patternFace = /facet([\s\S]*?)endfacet/g;
+		var result;
+
+		while ( ( result = patternFace.exec( data ) ) != null ) {
+
+			var text = result[ 0 ];
+
+			// Normal
+			var patternNormal = /normal[\s]+([-+]?[0-9]+\.?[0-9]*([eE][-+]?[0-9]+)?)+[\s]+([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)+[\s]+([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)+/g;
+
+			while( ( result = patternNormal.exec( text ) ) != null ) {
+
+				var normal = new THREE.Vector3( result[ 1 ], result[ 3 ], result[ 5 ] );
+
+			}
+
+			// Vertex
+			var patternVertex = /vertex[\s]+([-+]?[0-9]+\.?[0-9]*([eE][-+]?[0-9]+)?)+[\s]+([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)+[\s]+([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)+/g;
+
+			while( ( result = patternVertex.exec( text ) ) != null ) {
+
+				geometry.vertices.push(
+					new THREE.Vector3( result[ 1 ], result[ 3 ], result[ 5 ] )
+				);
+
+			}
+
+			var len = geometry.vertices.length;
+			geometry.faces.push( new THREE.Face3( len - 3, len - 2, len - 1, normal ) );
+
+		}
+
+		geometry.computeCentroids();
+		geometry.computeBoundingSphere();
+
+		return geometry;
+
+	}
+
+};

+ 3 - 3
examples/js/postprocessing/BloomPass.js

@@ -67,7 +67,7 @@ THREE.BloomPass.prototype = {
 
 		THREE.EffectComposer.quad.material = this.materialConvolution;
 
-		this.convolutionUniforms[ "tDiffuse" ].texture = readBuffer;
+		this.convolutionUniforms[ "tDiffuse" ].value = readBuffer;
 		this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX;
 
 		renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetX, true );
@@ -75,7 +75,7 @@ THREE.BloomPass.prototype = {
 
 		// Render quad with blured scene into texture (convolution pass 2)
 
-		this.convolutionUniforms[ "tDiffuse" ].texture = this.renderTargetX;
+		this.convolutionUniforms[ "tDiffuse" ].value = this.renderTargetX;
 		this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY;
 
 		renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetY, true );
@@ -84,7 +84,7 @@ THREE.BloomPass.prototype = {
 
 		THREE.EffectComposer.quad.material = this.materialScreen;
 
-		this.screenUniforms[ "tDiffuse" ].texture = this.renderTargetY;
+		this.screenUniforms[ "tDiffuse" ].value = this.renderTargetY;
 
 		if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
 

+ 1 - 1
examples/js/postprocessing/DotScreenPass.js

@@ -32,7 +32,7 @@ THREE.DotScreenPass.prototype = {
 
 	render: function ( renderer, writeBuffer, readBuffer, delta ) {
 
-		this.uniforms[ "tDiffuse" ].texture = readBuffer;
+		this.uniforms[ "tDiffuse" ].value = readBuffer;
 		this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height );
 
 		THREE.EffectComposer.quad.material = this.material;

+ 1 - 1
examples/js/postprocessing/FilmPass.js

@@ -31,7 +31,7 @@ THREE.FilmPass.prototype = {
 
 	render: function ( renderer, writeBuffer, readBuffer, delta ) {
 
-		this.uniforms[ "tDiffuse" ].texture = readBuffer;
+		this.uniforms[ "tDiffuse" ].value = readBuffer;
 		this.uniforms[ "time" ].value += delta;
 
 		THREE.EffectComposer.quad.material = this.material;

+ 1 - 1
examples/js/postprocessing/SavePass.js

@@ -39,7 +39,7 @@ THREE.SavePass.prototype = {
 
 		if ( this.uniforms[ this.textureID ] ) {
 
-			this.uniforms[ this.textureID ].texture = readBuffer;
+			this.uniforms[ this.textureID ].value = readBuffer;
 
 		}
 

+ 1 - 1
examples/js/postprocessing/ShaderPass.js

@@ -30,7 +30,7 @@ THREE.ShaderPass.prototype = {
 
 		if ( this.uniforms[ this.textureID ] ) {
 
-			this.uniforms[ this.textureID ].texture = readBuffer;
+			this.uniforms[ this.textureID ].value = readBuffer;
 
 		}
 

+ 1 - 1
examples/js/postprocessing/TexturePass.js

@@ -9,7 +9,7 @@ THREE.TexturePass = function ( texture, opacity ) {
 	this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
 	this.uniforms[ "opacity" ].value = ( opacity !== undefined ) ? opacity : 1.0;
-	this.uniforms[ "tDiffuse" ].texture = texture;
+	this.uniforms[ "tDiffuse" ].value = texture;
 
 	this.material = new THREE.ShaderMaterial( {
 

+ 3 - 3
examples/misc_camera_fly.html

@@ -117,11 +117,11 @@
 				var shader = THREE.ShaderUtils.lib[ "normal" ];
 				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-				uniforms[ "tNormal" ].texture = normalTexture;
+				uniforms[ "tNormal" ].value = normalTexture;
 				uniforms[ "uNormalScale" ].value = 0.85;
 
-				uniforms[ "tDiffuse" ].texture = planetTexture;
-				uniforms[ "tSpecular" ].texture = specularTexture;
+				uniforms[ "tDiffuse" ].value = planetTexture;
+				uniforms[ "tSpecular" ].value = specularTexture;
 
 				uniforms[ "enableAO" ].value = false;
 				uniforms[ "enableDiffuse" ].value = true;

File diff suppressed because it is too large
+ 35 - 0
examples/models/skinned/knight.js


+ 2018 - 0
examples/models/stl/slotted_disk.stl

@@ -0,0 +1,2018 @@
+solid DiskBase
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex 0.000000e+000 5.000000e-001 -8.000000e-002
+         vertex 2.506665e-002 1.984229e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex 0.000000e+000 5.000000e-001 -8.000000e-002
+         vertex 8.020564e-002 4.935251e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex 8.020564e-002 4.935251e-001 -8.000000e-002
+         vertex 7.362491e-002 1.859553e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex -2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex -7.362491e-002 1.859553e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex -2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex -1.583340e-001 4.742682e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex -1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex -1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex -8.020564e-002 4.935251e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex -8.020564e-002 4.935251e-001 -8.000000e-002
+         vertex 0.000000e+000 5.000000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex 1.369094e-001 -1.457937e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex 3.315613e-001 -3.742554e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex 3.315613e-001 -3.742554e-001 -8.000000e-002
+         vertex 9.635074e-002 -1.752613e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex 1.902113e-001 -6.180340e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 -8.000000e-002
+         vertex 1.688656e-001 -1.071654e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 -8.000000e-002
+         vertex 4.330127e-001 -2.500000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex 4.330127e-001 -2.500000e-001 -8.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex 4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex 1.964574e-001 3.747626e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex 4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex 4.963544e-001 6.026834e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex 4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex 1.996053e-001 -1.255810e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex 4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -8.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex -4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex -1.541027e-001 1.274848e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex -4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex -3.606012e-001 3.463622e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex -3.606012e-001 3.463622e-001 -8.000000e-002
+         vertex -1.175570e-001 1.618034e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex -3.606012e-001 3.463622e-001 -8.000000e-002
+         vertex -3.003711e-001 3.997214e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex -3.003711e-001 3.997214e-001 -8.000000e-002
+         vertex -2.323616e-001 4.427280e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex 4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex 1.809654e-001 8.515586e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex 4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex 4.517252e-001 2.143463e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex 4.517252e-001 2.143463e-001 -8.000000e-002
+         vertex 4.802591e-001 1.391087e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 8.020564e-002 4.935251e-001 -8.000000e-002
+         vertex 1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex 7.362491e-002 1.859553e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex 1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex 2.323616e-001 4.427280e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex 2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex 1.175570e-001 1.618034e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex 2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex 3.003711e-001 3.997214e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex 3.003711e-001 3.997214e-001 -8.000000e-002
+         vertex 1.541027e-001 1.274848e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex 3.003711e-001 3.997214e-001 -8.000000e-002
+         vertex 3.606012e-001 3.463622e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex 3.606012e-001 3.463622e-001 -8.000000e-002
+         vertex 4.114919e-001 2.840324e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex -4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex -1.809654e-001 8.515586e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex -4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex -4.517252e-001 2.143463e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex -4.517252e-001 2.143463e-001 -8.000000e-002
+         vertex -4.114919e-001 2.840324e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex -1.996053e-001 -1.255810e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -8.000000e-002
+         vertex -1.964574e-001 3.747626e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -8.000000e-002
+         vertex -4.963544e-001 6.026834e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex -4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex -4.802591e-001 1.391087e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex -1.688656e-001 -1.071654e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 -8.000000e-002
+         vertex -1.902113e-001 -6.180340e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 -8.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 -8.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex -9.635074e-002 -1.752613e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex -1.369094e-001 -1.457937e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 -8.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.898587e-017 -2.000000e-001 -8.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex -4.973798e-002 -1.937166e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 -8.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex -4.898587e-017 -2.000000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.898587e-017 -2.000000e-001 -8.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex 1.836970e-016 -5.000000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.898587e-017 -2.000000e-001 -8.000000e-002
+         vertex 1.836970e-016 -5.000000e-001 -8.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 3.315613e-001 -3.742554e-001 -8.000000e-002
+         vertex 2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex 9.635074e-002 -1.752613e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex 2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex 4.973798e-002 -1.937166e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex 1.196578e-001 -4.854709e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex 1.196578e-001 -4.854709e-001 -8.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.963869e-001 -6.000000e-002 4.000000e-002
+         vertex -4.963869e-001 -6.000000e-002 4.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.963869e-001 -6.000000e-002 4.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex 4.330127e-001 -2.500000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex 3.315613e-001 -3.742554e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex 2.672329e-001 -4.225951e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex 1.196578e-001 -4.854709e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 4.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.977564e-001 6.694921e-002 0.000000e+000
+      outer loop
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex -4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.999106e-001 1.337347e-002 0.000000e+000
+      outer loop
+         vertex -4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex -4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.977602e-001 -6.689154e-002 0.000000e+000
+      outer loop
+         vertex -4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -8.000000e-002
+         vertex -4.963869e-001 -6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.927306e-001 -1.203574e-001 0.000000e+000
+      outer loop
+         vertex -4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -8.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.891688e-001 -1.467825e-001 0.000000e+000
+      outer loop
+         vertex -4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex -4.963869e-001 -6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.927306e-001 -1.203574e-001 0.000000e+000
+      outer loop
+         vertex 4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.955921e-001 -9.378949e-002 0.000000e+000
+      outer loop
+         vertex 4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.999130e-001 1.319381e-002 0.000000e+000
+      outer loop
+         vertex 4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -8.000000e-002
+         vertex 4.963869e-001 6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.977564e-001 6.694920e-002 0.000000e+000
+      outer loop
+         vertex 4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -8.000000e-002
+         vertex 4.963544e-001 6.026834e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.927523e-001 1.201789e-001 0.000000e+000
+      outer loop
+         vertex 4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex 4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex 4.963869e-001 6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.848379e-001 -1.734772e-001 0.000000e+000
+      outer loop
+         vertex -4.963869e-001 -6.000000e-002 4.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.676545e-001 -2.522791e-001 0.000000e+000
+      outer loop
+         vertex -4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex -4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.526865e-001 -3.039545e-001 0.000000e+000
+      outer loop
+         vertex -4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 -8.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.146552e-001 -4.042349e-001 0.000000e+000
+      outer loop
+         vertex -4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex -4.675081e-001 -1.773024e-001 -8.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -8.915918e-001 -4.528400e-001 0.000000e+000
+      outer loop
+         vertex -4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 -8.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -8.379669e-001 -5.457212e-001 0.000000e+000
+      outer loop
+         vertex -4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex -4.330127e-001 -2.500000e-001 -8.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -8.074053e-001 -5.899972e-001 0.000000e+000
+      outer loop
+         vertex -4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -7.395756e-001 -6.730735e-001 0.000000e+000
+      outer loop
+         vertex -3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex -3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -7.023074e-001 -7.118738e-001 0.000000e+000
+      outer loop
+         vertex -3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 -8.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -6.220297e-001 -7.829937e-001 0.000000e+000
+      outer loop
+         vertex -3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex -3.315613e-001 -3.742554e-001 -8.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -5.790201e-001 -8.153133e-001 0.000000e+000
+      outer loop
+         vertex -3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -4.883735e-001 -8.726347e-001 0.000000e+000
+      outer loop
+         vertex -2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex -2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -4.407364e-001 -8.976365e-001 0.000000e+000
+      outer loop
+         vertex -2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -3.420688e-001 -9.396749e-001 0.000000e+000
+      outer loop
+         vertex -1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex -1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -2.910380e-001 -9.567115e-001 0.000000e+000
+      outer loop
+         vertex -1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 -8.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -1.869046e-001 -9.823781e-001 0.000000e+000
+      outer loop
+         vertex -1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex -1.196578e-001 -4.854709e-001 -8.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -1.338019e-001 -9.910081e-001 0.000000e+000
+      outer loop
+         vertex -1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -5.368308e-002 -9.985580e-001 0.000000e+000
+      outer loop
+         vertex -4.023328e-002 -4.983787e-001 4.000000e-002
+         vertex -4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex 6.123234e-017 -5.000000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex -4.023328e-002 -4.983787e-001 4.000000e-002
+         vertex 6.123234e-017 -5.000000e-001 -8.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 5.368308e-002 -9.985580e-001 0.000000e+000
+      outer loop
+         vertex 6.123234e-017 -5.000000e-001 -8.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.338019e-001 -9.910081e-001 0.000000e+000
+      outer loop
+         vertex 4.023328e-002 -4.983787e-001 4.000000e-002
+         vertex 4.023328e-002 -4.983787e-001 -8.000000e-002
+         vertex 1.196578e-001 -4.854709e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 1.869046e-001 -9.823781e-001 0.000000e+000
+      outer loop
+         vertex 4.023328e-002 -4.983787e-001 4.000000e-002
+         vertex 1.196578e-001 -4.854709e-001 -8.000000e-002
+         vertex 1.196578e-001 -4.854709e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 2.910380e-001 -9.567115e-001 0.000000e+000
+      outer loop
+         vertex 1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex 1.196578e-001 -4.854709e-001 -8.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 3.420688e-001 -9.396749e-001 0.000000e+000
+      outer loop
+         vertex 1.196578e-001 -4.854709e-001 4.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 4.407365e-001 -8.976365e-001 0.000000e+000
+      outer loop
+         vertex 1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex 1.959833e-001 -4.599897e-001 -8.000000e-002
+         vertex 2.672329e-001 -4.225951e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 4.883735e-001 -8.726346e-001 0.000000e+000
+      outer loop
+         vertex 1.959833e-001 -4.599897e-001 4.000000e-002
+         vertex 2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex 2.672329e-001 -4.225951e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 5.790201e-001 -8.153133e-001 0.000000e+000
+      outer loop
+         vertex 2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex 2.672329e-001 -4.225951e-001 -8.000000e-002
+         vertex 3.315613e-001 -3.742554e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 6.220297e-001 -7.829937e-001 0.000000e+000
+      outer loop
+         vertex 2.672329e-001 -4.225951e-001 4.000000e-002
+         vertex 3.315613e-001 -3.742554e-001 -8.000000e-002
+         vertex 3.315613e-001 -3.742554e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 7.023074e-001 -7.118738e-001 0.000000e+000
+      outer loop
+         vertex 3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex 3.315613e-001 -3.742554e-001 -8.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 7.395756e-001 -6.730735e-001 0.000000e+000
+      outer loop
+         vertex 3.315613e-001 -3.742554e-001 4.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 8.074053e-001 -5.899972e-001 0.000000e+000
+      outer loop
+         vertex 3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex 3.873025e-001 -3.162227e-001 -8.000000e-002
+         vertex 4.330127e-001 -2.500000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 8.379669e-001 -5.457212e-001 0.000000e+000
+      outer loop
+         vertex 3.873025e-001 -3.162227e-001 4.000000e-002
+         vertex 4.330127e-001 -2.500000e-001 -8.000000e-002
+         vertex 4.330127e-001 -2.500000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 8.915918e-001 -4.528400e-001 0.000000e+000
+      outer loop
+         vertex 4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex 4.330127e-001 -2.500000e-001 -8.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.146552e-001 -4.042349e-001 0.000000e+000
+      outer loop
+         vertex 4.330127e-001 -2.500000e-001 4.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 -8.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.526865e-001 -3.039545e-001 0.000000e+000
+      outer loop
+         vertex 4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex 4.675081e-001 -1.773024e-001 -8.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.676545e-001 -2.522791e-001 0.000000e+000
+      outer loop
+         vertex 4.675081e-001 -1.773024e-001 4.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.848379e-001 -1.734772e-001 0.000000e+000
+      outer loop
+         vertex 4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex 4.898953e-001 -1.000128e-001 -8.000000e-002
+         vertex 4.963869e-001 -6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.891688e-001 -1.467825e-001 0.000000e+000
+      outer loop
+         vertex 4.898953e-001 -1.000128e-001 4.000000e-002
+         vertex 4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex 4.963869e-001 -6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.927306e-001 1.203578e-001 0.000000e+000
+      outer loop
+         vertex 4.963869e-001 6.000000e-002 4.000000e-002
+         vertex 4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex 4.963544e-001 6.026834e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.848167e-001 1.735972e-001 0.000000e+000
+      outer loop
+         vertex 4.963544e-001 6.026834e-002 4.000000e-002
+         vertex 4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex 4.802591e-001 1.391087e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.740555e-001 2.263094e-001 0.000000e+000
+      outer loop
+         vertex 4.963544e-001 6.026834e-002 4.000000e-002
+         vertex 4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex 4.802591e-001 1.391087e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 9.442167e-001 3.293249e-001 0.000000e+000
+      outer loop
+         vertex 4.802591e-001 1.391087e-001 4.000000e-002
+         vertex 4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex 4.517252e-001 2.143463e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.251391e-001 3.796282e-001 0.000000e+000
+      outer loop
+         vertex 4.802591e-001 1.391087e-001 4.000000e-002
+         vertex 4.517252e-001 2.143463e-001 -8.000000e-002
+         vertex 4.517252e-001 2.143463e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 8.791618e-001 4.765233e-001 0.000000e+000
+      outer loop
+         vertex 4.517252e-001 2.143463e-001 4.000000e-002
+         vertex 4.517252e-001 2.143463e-001 -8.000000e-002
+         vertex 4.114919e-001 2.840324e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 8.522621e-001 5.231149e-001 0.000000e+000
+      outer loop
+         vertex 4.517252e-001 2.143463e-001 4.000000e-002
+         vertex 4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex 4.114919e-001 2.840324e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 7.913373e-001 6.113799e-001 0.000000e+000
+      outer loop
+         vertex 4.114919e-001 2.840324e-001 4.000000e-002
+         vertex 4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex 3.606012e-001 3.463622e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 7.573121e-001 6.530532e-001 0.000000e+000
+      outer loop
+         vertex 4.114919e-001 2.840324e-001 4.000000e-002
+         vertex 3.606012e-001 3.463622e-001 -8.000000e-002
+         vertex 3.606012e-001 3.463622e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 6.830174e-001 7.304021e-001 0.000000e+000
+      outer loop
+         vertex 3.606012e-001 3.463622e-001 4.000000e-002
+         vertex 3.606012e-001 3.463622e-001 -8.000000e-002
+         vertex 3.003711e-001 3.997214e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 6.427480e-001 7.660777e-001 0.000000e+000
+      outer loop
+         vertex 3.606012e-001 3.463622e-001 4.000000e-002
+         vertex 3.003711e-001 3.997214e-001 -8.000000e-002
+         vertex 3.003711e-001 3.997214e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 5.570078e-001 8.305073e-001 0.000000e+000
+      outer loop
+         vertex 3.003711e-001 3.997214e-001 4.000000e-002
+         vertex 3.003711e-001 3.997214e-001 -8.000000e-002
+         vertex 2.323616e-001 4.427280e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 5.115370e-001 8.592612e-001 0.000000e+000
+      outer loop
+         vertex 3.003711e-001 3.997214e-001 4.000000e-002
+         vertex 2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex 2.323616e-001 4.427280e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 4.165719e-001 9.091027e-001 0.000000e+000
+      outer loop
+         vertex 2.323616e-001 4.427280e-001 4.000000e-002
+         vertex 2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex 1.583340e-001 4.742682e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 3.670776e-001 9.301903e-001 0.000000e+000
+      outer loop
+         vertex 2.323616e-001 4.427280e-001 4.000000e-002
+         vertex 1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex 1.583340e-001 4.742682e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 2.653471e-001 9.641529e-001 0.000000e+000
+      outer loop
+         vertex 1.583340e-001 4.742682e-001 4.000000e-002
+         vertex 1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex 8.020564e-002 4.935251e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 2.131110e-001 9.770280e-001 0.000000e+000
+      outer loop
+         vertex 1.583340e-001 4.742682e-001 4.000000e-002
+         vertex 8.020564e-002 4.935251e-001 -8.000000e-002
+         vertex 8.020564e-002 4.935251e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.072499e-001 9.942321e-001 0.000000e+000
+      outer loop
+         vertex 8.020564e-002 4.935251e-001 4.000000e-002
+         vertex 8.020564e-002 4.935251e-001 -8.000000e-002
+         vertex 0.000000e+000 5.000000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 5.362497e-002 9.985611e-001 0.000000e+000
+      outer loop
+         vertex 8.020564e-002 4.935251e-001 4.000000e-002
+         vertex 0.000000e+000 5.000000e-001 -8.000000e-002
+         vertex 0.000000e+000 5.000000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -5.362497e-002 9.985611e-001 0.000000e+000
+      outer loop
+         vertex 0.000000e+000 5.000000e-001 4.000000e-002
+         vertex 0.000000e+000 5.000000e-001 -8.000000e-002
+         vertex -8.020564e-002 4.935251e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -1.072499e-001 9.942321e-001 0.000000e+000
+      outer loop
+         vertex 0.000000e+000 5.000000e-001 4.000000e-002
+         vertex -8.020564e-002 4.935251e-001 -8.000000e-002
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -2.131110e-001 9.770280e-001 0.000000e+000
+      outer loop
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+         vertex -8.020564e-002 4.935251e-001 -8.000000e-002
+         vertex -1.583340e-001 4.742682e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -2.653471e-001 9.641529e-001 0.000000e+000
+      outer loop
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+         vertex -1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex -1.583340e-001 4.742682e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -3.670776e-001 9.301903e-001 0.000000e+000
+      outer loop
+         vertex -1.583340e-001 4.742682e-001 4.000000e-002
+         vertex -1.583340e-001 4.742682e-001 -8.000000e-002
+         vertex -2.323616e-001 4.427280e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -4.165719e-001 9.091027e-001 0.000000e+000
+      outer loop
+         vertex -1.583340e-001 4.742682e-001 4.000000e-002
+         vertex -2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex -2.323616e-001 4.427280e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -5.115370e-001 8.592612e-001 0.000000e+000
+      outer loop
+         vertex -2.323616e-001 4.427280e-001 4.000000e-002
+         vertex -2.323616e-001 4.427280e-001 -8.000000e-002
+         vertex -3.003711e-001 3.997214e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -5.570078e-001 8.305073e-001 0.000000e+000
+      outer loop
+         vertex -2.323616e-001 4.427280e-001 4.000000e-002
+         vertex -3.003711e-001 3.997214e-001 -8.000000e-002
+         vertex -3.003711e-001 3.997214e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -6.427480e-001 7.660777e-001 0.000000e+000
+      outer loop
+         vertex -3.003711e-001 3.997214e-001 4.000000e-002
+         vertex -3.003711e-001 3.997214e-001 -8.000000e-002
+         vertex -3.606012e-001 3.463622e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -6.830174e-001 7.304021e-001 0.000000e+000
+      outer loop
+         vertex -3.003711e-001 3.997214e-001 4.000000e-002
+         vertex -3.606012e-001 3.463622e-001 -8.000000e-002
+         vertex -3.606012e-001 3.463622e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -7.573121e-001 6.530532e-001 0.000000e+000
+      outer loop
+         vertex -3.606012e-001 3.463622e-001 4.000000e-002
+         vertex -3.606012e-001 3.463622e-001 -8.000000e-002
+         vertex -4.114919e-001 2.840324e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -7.913373e-001 6.113799e-001 0.000000e+000
+      outer loop
+         vertex -3.606012e-001 3.463622e-001 4.000000e-002
+         vertex -4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex -4.114919e-001 2.840324e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -8.522621e-001 5.231149e-001 0.000000e+000
+      outer loop
+         vertex -4.114919e-001 2.840324e-001 4.000000e-002
+         vertex -4.114919e-001 2.840324e-001 -8.000000e-002
+         vertex -4.517252e-001 2.143463e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -8.791618e-001 4.765233e-001 0.000000e+000
+      outer loop
+         vertex -4.114919e-001 2.840324e-001 4.000000e-002
+         vertex -4.517252e-001 2.143463e-001 -8.000000e-002
+         vertex -4.517252e-001 2.143463e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.251391e-001 3.796283e-001 0.000000e+000
+      outer loop
+         vertex -4.517252e-001 2.143463e-001 4.000000e-002
+         vertex -4.517252e-001 2.143463e-001 -8.000000e-002
+         vertex -4.802591e-001 1.391087e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.442167e-001 3.293249e-001 0.000000e+000
+      outer loop
+         vertex -4.517252e-001 2.143463e-001 4.000000e-002
+         vertex -4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex -4.802591e-001 1.391087e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.740555e-001 2.263094e-001 0.000000e+000
+      outer loop
+         vertex -4.802591e-001 1.391087e-001 4.000000e-002
+         vertex -4.802591e-001 1.391087e-001 -8.000000e-002
+         vertex -4.963544e-001 6.026834e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.848167e-001 1.735972e-001 0.000000e+000
+      outer loop
+         vertex -4.802591e-001 1.391087e-001 4.000000e-002
+         vertex -4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex -4.963544e-001 6.026834e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.927306e-001 1.203578e-001 0.000000e+000
+      outer loop
+         vertex -4.963544e-001 6.026834e-002 4.000000e-002
+         vertex -4.963544e-001 6.026834e-002 -8.000000e-002
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal -9.927523e-001 1.201789e-001 0.000000e+000
+      outer loop
+         vertex -4.963544e-001 6.026834e-002 4.000000e-002
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex -4.963869e-001 6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.963869e-001 6.000000e-002 4.000000e-002
+         vertex 2.450000e-001 6.000000e-002 4.000000e-002
+         vertex -4.963544e-001 6.026834e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.963544e-001 6.026834e-002 4.000000e-002
+         vertex 2.450000e-001 6.000000e-002 4.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.963544e-001 6.026834e-002 4.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+         vertex -4.802591e-001 1.391087e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -3.003711e-001 3.997214e-001 4.000000e-002
+         vertex -3.606012e-001 3.463622e-001 4.000000e-002
+         vertex -2.323616e-001 4.427280e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -2.323616e-001 4.427280e-001 4.000000e-002
+         vertex -3.606012e-001 3.463622e-001 4.000000e-002
+         vertex -4.114919e-001 2.840324e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -2.323616e-001 4.427280e-001 4.000000e-002
+         vertex -4.114919e-001 2.840324e-001 4.000000e-002
+         vertex -1.583340e-001 4.742682e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -1.583340e-001 4.742682e-001 4.000000e-002
+         vertex -4.114919e-001 2.840324e-001 4.000000e-002
+         vertex -4.517252e-001 2.143463e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -1.583340e-001 4.742682e-001 4.000000e-002
+         vertex -4.517252e-001 2.143463e-001 4.000000e-002
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 8.020564e-002 4.935251e-001 4.000000e-002
+         vertex 0.000000e+000 5.000000e-001 4.000000e-002
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.550000e-001 6.000000e-002 4.000000e-002
+         vertex 4.963869e-001 6.000000e-002 4.000000e-002
+         vertex 4.963544e-001 6.026834e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.550000e-001 1.600000e-001 4.000000e-002
+         vertex 3.606012e-001 3.463622e-001 4.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+         vertex 3.606012e-001 3.463622e-001 4.000000e-002
+         vertex 3.003711e-001 3.997214e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+         vertex 3.003711e-001 3.997214e-001 4.000000e-002
+         vertex 2.323616e-001 4.427280e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 4.963544e-001 6.026834e-002 4.000000e-002
+         vertex 4.802591e-001 1.391087e-001 4.000000e-002
+         vertex 2.550000e-001 6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.550000e-001 6.000000e-002 4.000000e-002
+         vertex 4.802591e-001 1.391087e-001 4.000000e-002
+         vertex 4.517252e-001 2.143463e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.550000e-001 6.000000e-002 4.000000e-002
+         vertex 4.517252e-001 2.143463e-001 4.000000e-002
+         vertex 2.550000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.550000e-001 1.600000e-001 4.000000e-002
+         vertex 4.517252e-001 2.143463e-001 4.000000e-002
+         vertex 4.114919e-001 2.840324e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.550000e-001 1.600000e-001 4.000000e-002
+         vertex 4.114919e-001 2.840324e-001 4.000000e-002
+         vertex 3.606012e-001 3.463622e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.517252e-001 2.143463e-001 4.000000e-002
+         vertex -4.802591e-001 1.391087e-001 4.000000e-002
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+         vertex -4.802591e-001 1.391087e-001 4.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -8.020564e-002 4.935251e-001 4.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+         vertex 8.020564e-002 4.935251e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 8.020564e-002 4.935251e-001 4.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+         vertex 2.323616e-001 4.427280e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 8.020564e-002 4.935251e-001 4.000000e-002
+         vertex 2.323616e-001 4.427280e-001 4.000000e-002
+         vertex 1.583340e-001 4.742682e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex 4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex -4.995945e-001 -2.013297e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex 4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex 4.995945e-001 -2.013297e-002 -4.000000e-002
+         vertex 4.963869e-001 6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal -1.293022e-016 1.000000e+000 0.000000e+000
+      outer loop
+         vertex 4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex -4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex 4.963869e-001 -6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal -1.293022e-016 1.000000e+000 0.000000e+000
+      outer loop
+         vertex 4.963869e-001 -6.000000e-002 4.000000e-002
+         vertex -4.963869e-001 -6.000000e-002 -4.000000e-002
+         vertex -4.963869e-001 -6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.293022e-016 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.450000e-001 6.000000e-002 4.000000e-002
+         vertex -4.963869e-001 6.000000e-002 4.000000e-002
+         vertex 2.450000e-001 6.000000e-002 2.000000e-002
+      endloop
+   endfacet
+   facet normal 1.293022e-016 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.450000e-001 6.000000e-002 2.000000e-002
+         vertex -4.963869e-001 6.000000e-002 4.000000e-002
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.293022e-016 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.450000e-001 6.000000e-002 2.000000e-002
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex 2.550000e-001 6.000000e-002 2.000000e-002
+      endloop
+   endfacet
+   facet normal 1.293022e-016 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.550000e-001 6.000000e-002 2.000000e-002
+         vertex -4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex 4.963869e-001 6.000000e-002 -4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.293022e-016 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.550000e-001 6.000000e-002 2.000000e-002
+         vertex 4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex 2.550000e-001 6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.293022e-016 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.550000e-001 6.000000e-002 4.000000e-002
+         vertex 4.963869e-001 6.000000e-002 -4.000000e-002
+         vertex 4.963869e-001 6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal -8.370229e-002 9.964908e-001 0.000000e+000
+      outer loop
+         vertex 7.347881e-017 2.000000e-001 -1.800000e-001
+         vertex -2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -2.077190e-001 9.781886e-001 0.000000e+000
+      outer loop
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex -2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex -7.362491e-002 1.859553e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -2.892204e-001 9.572625e-001 0.000000e+000
+      outer loop
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex -7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex -7.362491e-002 1.859553e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -4.444587e-001 8.957993e-001 0.000000e+000
+      outer loop
+         vertex -7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex -7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex -1.175570e-001 1.618034e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -5.181955e-001 8.552622e-001 0.000000e+000
+      outer loop
+         vertex -7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex -1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex -1.175570e-001 1.618034e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -6.532714e-001 7.571238e-001 0.000000e+000
+      outer loop
+         vertex -1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex -1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex -1.541027e-001 1.274848e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -7.146106e-001 6.995225e-001 0.000000e+000
+      outer loop
+         vertex -1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex -1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex -1.541027e-001 1.274848e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -8.210368e-001 5.708753e-001 0.000000e+000
+      outer loop
+         vertex -1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex -1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex -1.809654e-001 8.515586e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -8.661239e-001 4.998294e-001 0.000000e+000
+      outer loop
+         vertex -1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex -1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex -1.809654e-001 8.515586e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.372133e-001 3.487567e-001 0.000000e+000
+      outer loop
+         vertex -1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex -1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex -1.964574e-001 3.747626e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -9.632155e-001 2.687301e-001 0.000000e+000
+      outer loop
+         vertex -1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex -1.964574e-001 3.747626e-002 -1.800000e-001
+         vertex -1.964574e-001 3.747626e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.945013e-001 1.047244e-001 0.000000e+000
+      outer loop
+         vertex -1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex -1.964574e-001 3.747626e-002 -1.800000e-001
+         vertex -1.996053e-001 -1.255810e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -9.997848e-001 2.074543e-002 0.000000e+000
+      outer loop
+         vertex -1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex -1.996053e-001 -1.255810e-002 -1.800000e-001
+         vertex -1.996053e-001 -1.255810e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.893011e-001 -1.458881e-001 0.000000e+000
+      outer loop
+         vertex -1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex -1.996053e-001 -1.255810e-002 -1.800000e-001
+         vertex -1.902113e-001 -6.180340e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -9.735339e-001 -2.285427e-001 0.000000e+000
+      outer loop
+         vertex -1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex -1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex -1.902113e-001 -6.180340e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -9.219395e-001 -3.873340e-001 0.000000e+000
+      outer loop
+         vertex -1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex -1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex -1.688656e-001 -1.071654e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -8.861123e-001 -4.634706e-001 0.000000e+000
+      outer loop
+         vertex -1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex -1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex -1.688656e-001 -1.071654e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -7.966490e-001 -6.044421e-001 0.000000e+000
+      outer loop
+         vertex -1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex -1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex -1.369094e-001 -1.457937e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -7.430130e-001 -6.692770e-001 0.000000e+000
+      outer loop
+         vertex -1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex -1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex -1.369094e-001 -1.457937e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -6.213022e-001 -7.835710e-001 0.000000e+000
+      outer loop
+         vertex -1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex -1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex -9.635074e-002 -1.752613e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -5.532274e-001 -8.330302e-001 0.000000e+000
+      outer loop
+         vertex -1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex -9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex -9.635074e-002 -1.752613e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -4.069166e-001 -9.134653e-001 0.000000e+000
+      outer loop
+         vertex -9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex -9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex -4.973798e-002 -1.937166e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -3.286806e-001 -9.444411e-001 0.000000e+000
+      outer loop
+         vertex -9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex -4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex -4.973798e-002 -1.937166e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal -1.669630e-001 -9.859632e-001 0.000000e+000
+      outer loop
+         vertex -4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex -4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex 0.000000e+000 -2.000000e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -8.348151e-002 -9.965093e-001 0.000000e+000
+      outer loop
+         vertex -4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex 0.000000e+000 -2.000000e-001 -1.800000e-001
+         vertex 0.000000e+000 -2.000000e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 8.348151e-002 -9.965093e-001 0.000000e+000
+      outer loop
+         vertex 0.000000e+000 -2.000000e-001 -8.000000e-002
+         vertex 0.000000e+000 -2.000000e-001 -1.800000e-001
+         vertex 4.973798e-002 -1.937166e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 1.669630e-001 -9.859632e-001 0.000000e+000
+      outer loop
+         vertex 0.000000e+000 -2.000000e-001 -8.000000e-002
+         vertex 4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex 4.973798e-002 -1.937166e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 3.286806e-001 -9.444411e-001 0.000000e+000
+      outer loop
+         vertex 4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex 4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex 9.635074e-002 -1.752613e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 4.069166e-001 -9.134653e-001 0.000000e+000
+      outer loop
+         vertex 4.973798e-002 -1.937166e-001 -8.000000e-002
+         vertex 9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex 9.635074e-002 -1.752613e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 5.532274e-001 -8.330302e-001 0.000000e+000
+      outer loop
+         vertex 9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex 9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex 1.369094e-001 -1.457937e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 6.213022e-001 -7.835710e-001 0.000000e+000
+      outer loop
+         vertex 9.635074e-002 -1.752613e-001 -8.000000e-002
+         vertex 1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex 1.369094e-001 -1.457937e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 7.430130e-001 -6.692770e-001 0.000000e+000
+      outer loop
+         vertex 1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex 1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex 1.688656e-001 -1.071654e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 7.966490e-001 -6.044421e-001 0.000000e+000
+      outer loop
+         vertex 1.369094e-001 -1.457937e-001 -8.000000e-002
+         vertex 1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex 1.688656e-001 -1.071654e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 8.861123e-001 -4.634706e-001 0.000000e+000
+      outer loop
+         vertex 1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex 1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex 1.902113e-001 -6.180340e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 9.219395e-001 -3.873340e-001 0.000000e+000
+      outer loop
+         vertex 1.688656e-001 -1.071654e-001 -8.000000e-002
+         vertex 1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex 1.902113e-001 -6.180340e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.735339e-001 -2.285427e-001 0.000000e+000
+      outer loop
+         vertex 1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex 1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex 1.996053e-001 -1.255810e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 9.893011e-001 -1.458881e-001 0.000000e+000
+      outer loop
+         vertex 1.902113e-001 -6.180340e-002 -8.000000e-002
+         vertex 1.996053e-001 -1.255810e-002 -1.800000e-001
+         vertex 1.996053e-001 -1.255810e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.997848e-001 2.074543e-002 0.000000e+000
+      outer loop
+         vertex 1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex 1.996053e-001 -1.255810e-002 -1.800000e-001
+         vertex 1.964574e-001 3.747626e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 9.945013e-001 1.047244e-001 0.000000e+000
+      outer loop
+         vertex 1.996053e-001 -1.255810e-002 -8.000000e-002
+         vertex 1.964574e-001 3.747626e-002 -1.800000e-001
+         vertex 1.964574e-001 3.747626e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 9.632155e-001 2.687300e-001 0.000000e+000
+      outer loop
+         vertex 1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex 1.964574e-001 3.747626e-002 -1.800000e-001
+         vertex 1.809654e-001 8.515586e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 9.372133e-001 3.487567e-001 0.000000e+000
+      outer loop
+         vertex 1.964574e-001 3.747626e-002 -8.000000e-002
+         vertex 1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex 1.809654e-001 8.515586e-002 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 8.661239e-001 4.998294e-001 0.000000e+000
+      outer loop
+         vertex 1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex 1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex 1.541027e-001 1.274848e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 8.210368e-001 5.708753e-001 0.000000e+000
+      outer loop
+         vertex 1.809654e-001 8.515586e-002 -8.000000e-002
+         vertex 1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex 1.541027e-001 1.274848e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 7.146106e-001 6.995225e-001 0.000000e+000
+      outer loop
+         vertex 1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex 1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex 1.175570e-001 1.618034e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 6.532714e-001 7.571238e-001 0.000000e+000
+      outer loop
+         vertex 1.541027e-001 1.274848e-001 -8.000000e-002
+         vertex 1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex 1.175570e-001 1.618034e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 5.181955e-001 8.552622e-001 0.000000e+000
+      outer loop
+         vertex 1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex 1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex 7.362491e-002 1.859553e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 4.444587e-001 8.957993e-001 0.000000e+000
+      outer loop
+         vertex 1.175570e-001 1.618034e-001 -8.000000e-002
+         vertex 7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex 7.362491e-002 1.859553e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 2.892204e-001 9.572625e-001 0.000000e+000
+      outer loop
+         vertex 7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex 7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex 2.506665e-002 1.984229e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 2.077190e-001 9.781886e-001 0.000000e+000
+      outer loop
+         vertex 7.362491e-002 1.859553e-001 -8.000000e-002
+         vertex 2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex 2.506665e-002 1.984229e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 8.370229e-002 9.964908e-001 0.000000e+000
+      outer loop
+         vertex 2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex 2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex 7.347881e-017 2.000000e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.506665e-002 1.984229e-001 -8.000000e-002
+         vertex 7.347881e-017 2.000000e-001 -1.800000e-001
+         vertex -2.506665e-002 1.984229e-001 -8.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.996053e-001 -1.255810e-002 -1.800000e-001
+         vertex -1.964574e-001 3.747626e-002 -1.800000e-001
+         vertex -1.902113e-001 -6.180340e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex -1.964574e-001 3.747626e-002 -1.800000e-001
+         vertex -1.809654e-001 8.515586e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex -1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex -1.688656e-001 -1.071654e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex -1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex -1.541027e-001 1.274848e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex -1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex -1.369094e-001 -1.457937e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex -1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex -1.175570e-001 1.618034e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex -1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex -9.635074e-002 -1.752613e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex -1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex -7.362491e-002 1.859553e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex -7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex -4.973798e-002 -1.937166e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex -7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex -2.506665e-002 1.984229e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex -2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex 0.000000e+000 -2.000000e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex -2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex 2.449294e-017 2.000000e-001 -1.800000e-001
+         vertex 0.000000e+000 -2.000000e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 0.000000e+000 -2.000000e-001 -1.800000e-001
+         vertex 2.449294e-017 2.000000e-001 -1.800000e-001
+         vertex 2.506665e-002 1.984229e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 0.000000e+000 -2.000000e-001 -1.800000e-001
+         vertex 2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex 4.973798e-002 -1.937166e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex 2.506665e-002 1.984229e-001 -1.800000e-001
+         vertex 7.362491e-002 1.859553e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 4.973798e-002 -1.937166e-001 -1.800000e-001
+         vertex 7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex 9.635074e-002 -1.752613e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex 7.362491e-002 1.859553e-001 -1.800000e-001
+         vertex 1.175570e-001 1.618034e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 9.635074e-002 -1.752613e-001 -1.800000e-001
+         vertex 1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex 1.369094e-001 -1.457937e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex 1.175570e-001 1.618034e-001 -1.800000e-001
+         vertex 1.541027e-001 1.274848e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.369094e-001 -1.457937e-001 -1.800000e-001
+         vertex 1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex 1.688656e-001 -1.071654e-001 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex 1.541027e-001 1.274848e-001 -1.800000e-001
+         vertex 1.809654e-001 8.515586e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.688656e-001 -1.071654e-001 -1.800000e-001
+         vertex 1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex 1.902113e-001 -6.180340e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex 1.809654e-001 8.515586e-002 -1.800000e-001
+         vertex 1.964574e-001 3.747626e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
+      outer loop
+         vertex 1.902113e-001 -6.180340e-002 -1.800000e-001
+         vertex 1.964574e-001 3.747626e-002 -1.800000e-001
+         vertex 1.996053e-001 -1.255810e-002 -1.800000e-001
+      endloop
+   endfacet
+   facet normal -1.000000e+000 0.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.550000e-001 1.600000e-001 2.000000e-002
+         vertex 2.550000e-001 6.000000e-002 2.000000e-002
+         vertex 2.550000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -1.000000e+000 0.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.550000e-001 1.600000e-001 4.000000e-002
+         vertex 2.550000e-001 6.000000e-002 2.000000e-002
+         vertex 2.550000e-001 6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.000000e+000 0.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.450000e-001 6.000000e-002 2.000000e-002
+         vertex 2.450000e-001 1.600000e-001 2.000000e-002
+         vertex 2.450000e-001 6.000000e-002 4.000000e-002
+      endloop
+   endfacet
+   facet normal 1.000000e+000 0.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.450000e-001 6.000000e-002 4.000000e-002
+         vertex 2.450000e-001 1.600000e-001 2.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -2.775558e-015 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.450000e-001 1.600000e-001 2.000000e-002
+         vertex 2.550000e-001 1.600000e-001 2.000000e-002
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal -2.775558e-015 -1.000000e+000 0.000000e+000
+      outer loop
+         vertex 2.450000e-001 1.600000e-001 4.000000e-002
+         vertex 2.550000e-001 1.600000e-001 2.000000e-002
+         vertex 2.550000e-001 1.600000e-001 4.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.450000e-001 1.600000e-001 2.000000e-002
+         vertex 2.450000e-001 6.000000e-002 2.000000e-002
+         vertex 2.550000e-001 1.600000e-001 2.000000e-002
+      endloop
+   endfacet
+   facet normal 0.000000e+000 0.000000e+000 1.000000e+000
+      outer loop
+         vertex 2.550000e-001 1.600000e-001 2.000000e-002
+         vertex 2.450000e-001 6.000000e-002 2.000000e-002
+         vertex 2.550000e-001 6.000000e-002 2.000000e-002
+      endloop
+   endfacet
+endsolid

+ 330 - 0
examples/webgl_animation_skinning_morph.html

@@ -0,0 +1,330 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - skinning + morphing [knight]</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: #000;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+
+				background-color: #fff;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			a {
+				color: #0af;
+			}
+		</style>
+	</head>
+
+	<body>
+
+		<div id="container"></div>
+
+		<div id="info">
+		<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> webgl - skinning + morphing
+		- knight by <a href="http://vimeo.com/36113323">apendua</a>
+		</div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/Stats.js"></script>
+
+		<script>
+
+			var SCREEN_WIDTH = window.innerWidth;
+			var SCREEN_HEIGHT = window.innerHeight;
+			var FLOOR = -250;
+
+			var container,stats;
+
+			var camera, scene;
+			var renderer;
+
+			var mesh;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			var clock = new THREE.Clock();
+
+			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.getElementById( 'container' );
+
+				camera = new THREE.PerspectiveCamera( 30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
+				camera.position.z = 2200;
+
+				scene = new THREE.Scene();
+
+				scene.fog = new THREE.Fog( 0xffffff, 2000, 10000 );
+				scene.fog.color.setHSV( 0.6, 0, 1 );
+
+				scene.add( camera );
+
+				// GROUND
+
+				/*
+				var groundTexture = THREE.ImageUtils.loadTexture( "textures/terrain/grasslight-big.jpg" );
+				groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
+				groundTexture.repeat.set( 16, 16 );
+				groundTexture.anisotropy = 4;
+				*/
+
+				var groundMaterial = new THREE.MeshPhongMaterial( { /*map: groundTexture,*/ emissive: 0xbbbbbb, perPixel: true } );
+				var planeGeometry = new THREE.PlaneGeometry( 16000, 16000 );
+
+				var ground = new THREE.Mesh( planeGeometry, groundMaterial );
+				ground.position.set( 0, FLOOR, 0 );
+				ground.rotation.x = -Math.PI/2;
+				scene.add( ground );
+
+				ground.receiveShadow = true;
+
+
+				// LIGHTS
+
+				var ambient = new THREE.AmbientLight( 0x222222 );
+				scene.add( ambient );
+
+
+				var light = new THREE.DirectionalLight( 0xffffff, 1.6 );
+				light.position.set( 0, 140, 500 );
+				light.position.multiplyScalar( 1.1 );
+				light.color.setHSV( 0.6, 0.075, 1 );
+				scene.add( light );
+
+				light.castShadow = true;
+
+				light.shadowMapWidth = 2048;
+				light.shadowMapHeight = 2048;
+
+				var d = 390;
+
+				light.shadowCameraLeft = -d * 2;
+				light.shadowCameraRight = d * 2;
+				light.shadowCameraTop = d * 1.5;
+				light.shadowCameraBottom = -d;
+
+				light.shadowCameraFar = 3500;
+				//light.shadowCameraVisible = true;
+
+				//
+
+				var light = new THREE.DirectionalLight( 0xffffff, 1 );
+				light.position.set( 0, -1, 0 );
+				light.color.setHSV( 0.25, 0.85, 0.5 );
+				scene.add( light );
+
+				// RENDERER
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+				renderer.domElement.style.position = "relative";
+
+				renderer.setClearColor( scene.fog.color, 1 );
+
+				container.appendChild( renderer.domElement );
+
+				renderer.gammaInput = true;
+				renderer.gammaOutput = true;
+				renderer.physicallyBasedShading = true;
+
+				renderer.shadowMapEnabled = true;
+
+
+				// STATS
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+
+				stats.domElement.children[ 0 ].children[ 0 ].style.color = "#777";
+				stats.domElement.children[ 0 ].style.background = "transparent";
+				stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
+
+				//
+
+				var loader = new THREE.JSONLoader();
+				loader.load( "models/skinned/knight.js", function( geometry ) { createScene( geometry,  0, FLOOR, -300, 60 ) } );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function ensureLoop( animation ) {
+
+				for ( var i = 0; i < animation.hierarchy.length; i ++ ) {
+
+					var bone = animation.hierarchy[ i ];
+
+					var first = bone.keys[ 0 ];
+					var last = bone.keys[ bone.keys.length - 1 ];
+
+					last.pos = first.pos;
+					last.rot = first.rot;
+					last.scl = first.scl;
+
+				}
+
+			}
+
+			function createScene( geometry, x, y, z, s ) {
+
+				ensureLoop( geometry.animation );
+
+				geometry.computeBoundingBox();
+				var bb = geometry.boundingBox;
+
+				THREE.AnimationHandler.add( geometry.animation );
+
+				var path = "textures/cube/Park2/";
+				var format = '.jpg';
+				var urls = [
+						path + 'posx' + format, path + 'negx' + format,
+						path + 'posy' + format, path + 'negy' + format,
+						path + 'posz' + format, path + 'negz' + format
+					];
+
+
+				//var envMap = THREE.ImageUtils.loadTextureCube( urls );
+
+				//var map = THREE.ImageUtils.loadTexture( "textures/ash_uvgrid01.jpg" );
+
+				//var bumpMap = THREE.ImageUtils.generateDataTexture( 1, 1, new THREE.Color() );
+				//var bumpMap = THREE.ImageUtils.loadTexture( "textures/water.jpg" );
+
+				for ( var i = 0; i < geometry.materials.length; i ++ ) {
+
+					var m = geometry.materials[ i ];
+					m.skinning = true;
+					m.morphTargets = true;
+
+					m.specular.setHSV( 0, 0, 0.1 );
+
+					m.color.setHSV( 0.6, 0, 0.6 );
+					m.ambient.copy( m.color );
+
+					//m.map = map;
+					//m.envMap = envMap;
+					//m.bumpMap = bumpMap;
+					//m.bumpScale = 2;
+
+					//m.combine = THREE.MixOperation;
+					//m.reflectivity = 0.75;
+
+					m.wrapAround = true;
+					m.perPixel = true;
+
+				}
+
+				mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshFaceMaterial() );
+				mesh.position.set( x, y - bb.min.y * s, z );
+				mesh.scale.set( s, s, s );
+				scene.add( mesh );
+
+				mesh.castShadow = true;
+				mesh.receiveShadow = true;
+
+				animation = new THREE.Animation( mesh, geometry.animation.name );
+				animation.JITCompile = false;
+				animation.interpolationType = THREE.AnimationHandler.LINEAR;
+
+				animation.play();
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				var delta = 0.75 * clock.getDelta();
+
+				camera.position.x += ( mouseX - camera.position.x ) * .05;
+				camera.position.y = THREE.Math.clamp( camera.position.y + ( - mouseY - camera.position.y ) * .05, 0, 1000 );
+
+				camera.lookAt( scene.position );
+
+				// update skinning
+
+				THREE.AnimationHandler.update( delta );
+
+				// update morphs
+
+				if ( mesh ) {
+
+					var time = Date.now() * 0.001;
+
+					// mouth
+
+					mesh.morphTargetInfluences[ 1 ] = ( 1 + Math.sin( 4 * time ) ) / 2;
+
+					// frown ?
+
+					mesh.morphTargetInfluences[ 2 ] = ( 1 + Math.sin( 2 * time ) ) / 2;
+
+					// eyes
+
+					mesh.morphTargetInfluences[ 3 ] = ( 1 + Math.cos( 4 * time ) ) / 2;
+
+				}
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 167 - 29
examples/webgl_buffergeometry.html

@@ -6,12 +6,12 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 			body {
-				color: #808080;
+				color: #cccccc;
 				font-family:Monospace;
 				font-size:13px;
 				text-align:center;
 
-				background-color: #fff;
+				background-color: #050505;
 				margin: 0px;
 				overflow: hidden;
 			}
@@ -34,7 +34,7 @@
 		<div id="container"></div>
 		<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> webgl - buffergeometry</div>
 
-		<script src="../build/three.js"></script>
+		<script src="../build/three.min.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/Stats.js"></script>
@@ -56,12 +56,29 @@
 
 				container = document.getElementById( 'container' );
 
-				camera = new THREE.PerspectiveCamera( 20, window.innerWidth / window.innerHeight, 1, 10000 );
-				camera.position.z = 1800;
+				//
+
+				camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 3500 );
+				camera.position.z = 2750;
 
 				scene = new THREE.Scene();
+				scene.fog = new THREE.Fog( 0x050505, 2000, 3500 );
+
+				//
 
-				var triangles = 500;
+				scene.add( new THREE.AmbientLight( 0x444444 ) );
+
+				var light1 = new THREE.DirectionalLight( 0xffffff, 0.5 );
+				light1.position.set( 1, 1, 1 );
+				scene.add( light1 );
+
+				var light2 = new THREE.DirectionalLight( 0xffffff, 1.5 );
+				light2.position.set( 0, -1, 0 );
+				scene.add( light2 );
+
+				//
+
+				var triangles = 160000;
 
 				var geometry = new THREE.BufferGeometry();
 				geometry.attributes = {
@@ -74,58 +91,177 @@
 						itemSize: 3,
 						array: new Float32Array( triangles * 3 * 3 ),
 						numItems: triangles * 3 * 3
+					},
+					normal: {
+						itemSize: 3,
+						array: new Float32Array( triangles * 3 * 3 ),
+						numItems: triangles * 3 * 3
+					},
+					color: {
+						itemSize: 3,
+						array: new Float32Array( triangles * 3 * 3 ),
+						numItems: triangles * 3 * 3
 					}
 				}
 
+				// break geometry into
+				// chunks of 20,000 triangles (3 unique vertices per triangle)
+				// for indices to fit into 16 bit integer number
+
+				var chunkSize = 20000;
+
 				var indices = geometry.attributes.index.array;
 
 				for ( var i = 0; i < indices.length; i ++ ) {
 
-					indices[ i ] = i;
+					indices[ i ] = i % ( 3 * chunkSize );
 
 				}
 
 				var positions = geometry.attributes.position.array;
+				var normals = geometry.attributes.normal.array;
+				var colors = geometry.attributes.color.array;
+
+				var color = new THREE.Color();
+
+				var n = 800, n2 = n/2;	// triangles spread in the cube
+				var d = 12, d2 = d/2;	// individual triangle size
+
+				var pA = new THREE.Vector3();
+				var pB = new THREE.Vector3();
+				var pC = new THREE.Vector3();
+
+				var cb = new THREE.Vector3();
+				var ab = new THREE.Vector3();
 
 				for ( var i = 0; i < positions.length; i += 9 ) {
 
-					var x = Math.random() * 400 - 200;
-					var y = Math.random() * 400 - 200;
-					var z = Math.random() * 400 - 200;
+					// positions
+
+					var x = Math.random() * n - n2;
+					var y = Math.random() * n - n2;
+					var z = Math.random() * n - n2;
+
+					var ax = x + Math.random() * d - d2;
+					var ay = y + Math.random() * d - d2;
+					var az = z + Math.random() * d - d2;
+
+					var bx = x + Math.random() * d - d2;
+					var by = y + Math.random() * d - d2;
+					var bz = z + Math.random() * d - d2;
+
+					var cx = x + Math.random() * d - d2;
+					var cy = y + Math.random() * d - d2;
+					var cz = z + Math.random() * d - d2;
+
+					positions[ i ]     = ax;
+					positions[ i + 1 ] = ay;
+					positions[ i + 2 ] = az;
+
+					positions[ i + 3 ] = bx;
+					positions[ i + 4 ] = by;
+					positions[ i + 5 ] = bz;
 
-					positions[ i ] = x + Math.random() * 40 - 20;
-					positions[ i + 1 ] = y + Math.random() * 40 - 20;
-					positions[ i + 2 ] = z + Math.random() * 40 - 20;
+					positions[ i + 6 ] = cx;
+					positions[ i + 7 ] = cy;
+					positions[ i + 8 ] = cz;
 
-					positions[ i + 3 ] = x + Math.random() * 40 - 20;
-					positions[ i + 4 ] = y + Math.random() * 40 - 20;
-					positions[ i + 5 ] = z + Math.random() * 40 - 20;
+					// flat face normals
 
-					positions[ i + 6 ] = x + Math.random() * 40 - 20;
-					positions[ i + 7 ] = y + Math.random() * 40 - 20;
-					positions[ i + 8 ] = z + Math.random() * 40 - 20;
+					pA.set( ax, ay, az );
+					pB.set( bx, by, bz );
+					pC.set( cx, cy, cz );
+
+					cb.sub( pC, pB );
+					ab.sub( pA, pB );
+					cb.crossSelf( ab );
+
+					cb.normalize();
+
+					var nx = cb.x;
+					var ny = cb.y;
+					var nz = cb.z;
+
+					normals[ i ]     = nx;
+					normals[ i + 1 ] = ny;
+					normals[ i + 2 ] = nz;
+
+					normals[ i + 3 ] = nx;
+					normals[ i + 4 ] = ny;
+					normals[ i + 5 ] = nz;
+
+					normals[ i + 6 ] = nx;
+					normals[ i + 7 ] = ny;
+					normals[ i + 8 ] = nz;
+
+					// colors
+
+					var vx = ( x / n ) + 0.5;
+					var vy = ( y / n ) + 0.5;
+					var vz = ( z / n ) + 0.5;
+
+					//color.setHSV( 0.5 + 0.5 * vx, 0.25 + 0.75 * vy, 0.25 + 0.75 * vz );
+					color.setRGB( vx, vy, vz );
+
+					colors[ i ]     = color.r;
+					colors[ i + 1 ] = color.g;
+					colors[ i + 2 ] = color.b;
+
+					colors[ i + 3 ] = color.r;
+					colors[ i + 4 ] = color.g;
+					colors[ i + 5 ] = color.b;
+
+					colors[ i + 6 ] = color.r;
+					colors[ i + 7 ] = color.g;
+					colors[ i + 8 ] = color.b;
 
 				}
 
-				geometry.offsets = [{
-					start: 0,
-					count: triangles * 3,
-					index: 0
-				}]
+				geometry.offsets = [];
+
+				var start = 0;
+				var index = 0;
+				var left = triangles * 3;
+
+				for ( ;; ) {
+
+					var count = Math.min( chunkSize * 3, left );
+
+					var chunk = { start: start, count: count, index: index };
+
+					geometry.offsets.push( chunk );
+
+					start += count;
+					index += chunkSize * 3;
+
+					left -= count;
+
+					if ( left <= 0 ) break;
+
+				}
 
 				geometry.computeBoundingSphere();
-				geometry.computeVertexNormals();
 
-				var material = new THREE.MeshLambertMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+				var material = new THREE.MeshPhongMaterial( { color: 0xaaaaaa, ambient: 0xaaaaaa, specular: 0xffffff, shininess: 250,
+															  side: THREE.DoubleSide, perPixel: true, vertexColors: THREE.VertexColors } );
 
 				mesh = new THREE.Mesh( geometry, material );
 				scene.add( mesh );
 
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: false, clearColor: 0x333333, clearAlpha: 1, alpha: false } );
 				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setClearColor( scene.fog.color, 1 );
+
+				renderer.gammaInput = true;
+				renderer.gammaOutput = true;
+				renderer.physicallyBasedShading = true;
 
 				container.appendChild( renderer.domElement );
 
+				//
+
 				stats = new Stats();
 				stats.domElement.style.position = 'absolute';
 				stats.domElement.style.top = '0px';
@@ -162,8 +298,10 @@
 
 			function render() {
 
-				mesh.rotation.x += 0.01;
-				mesh.rotation.y += 0.02;
+				var time = Date.now() * 0.001;
+
+				mesh.rotation.x = time * 0.25;
+				mesh.rotation.y = time * 0.5;
 
 				renderer.render( scene, camera );
 

+ 189 - 0
examples/webgl_buffergeometry_particles.html

@@ -0,0 +1,189 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - buffergeometry [particles]</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: #cccccc;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+
+				background-color: #050505;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			a {
+
+				color: #0080ff;
+			}
+
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> webgl - buffergeometry - particles</div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/Stats.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var container, stats;
+
+			var camera, scene, renderer;
+
+			var mesh;
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.getElementById( 'container' );
+
+				//
+
+				camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 5, 3500 );
+				camera.position.z = 2750;
+
+				scene = new THREE.Scene();
+				scene.fog = new THREE.Fog( 0x050505, 2000, 3500 );
+
+				//
+
+				var particles = 500000;
+
+				var geometry = new THREE.BufferGeometry();
+				geometry.attributes = {
+
+					position: {
+						itemSize: 3,
+						array: new Float32Array( particles * 3 ),
+						numItems: particles * 3
+					},
+					color: {
+						itemSize: 3,
+						array: new Float32Array( particles * 3 ),
+						numItems: particles * 3
+					}
+
+				}
+
+
+				var positions = geometry.attributes.position.array;
+				var colors = geometry.attributes.color.array;
+
+				var color = new THREE.Color();
+
+				var n = 1000, n2 = n / 2; // particles spread in the cube
+
+				for ( var i = 0; i < positions.length; i += 3 ) {
+
+					// positions
+
+					var x = Math.random() * n - n2;
+					var y = Math.random() * n - n2;
+					var z = Math.random() * n - n2;
+
+					positions[ i ]     = x;
+					positions[ i + 1 ] = y;
+					positions[ i + 2 ] = z;
+
+					// colors
+
+					var vx = ( x / n ) + 0.5;
+					var vy = ( y / n ) + 0.5;
+					var vz = ( z / n ) + 0.5;
+
+					//color.setHSV( 0.5 + 0.5 * vx, 0.25 + 0.75 * vy, 0.25 + 0.75 * vz );
+					color.setRGB( vx, vy, vz );
+
+					colors[ i ]     = color.r;
+					colors[ i + 1 ] = color.g;
+					colors[ i + 2 ] = color.b;
+
+				}
+
+				geometry.computeBoundingSphere();
+
+				//
+
+				var material = new THREE.ParticleBasicMaterial( { size: 15, vertexColors: true } );
+
+				particleSystem = new THREE.ParticleSystem( geometry, material );
+				scene.add( particleSystem );
+
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: false, clearColor: 0x333333, clearAlpha: 1, alpha: false } );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setClearColor( scene.fog.color, 1 );
+
+				container.appendChild( renderer.domElement );
+
+				//
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				var time = Date.now() * 0.001;
+
+				particleSystem.rotation.x = time * 0.25;
+				particleSystem.rotation.y = time * 0.5;
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 21 - 11
examples/webgl_camera.html

@@ -67,19 +67,18 @@
 
 				camera = new THREE.PerspectiveCamera( 50, 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
 				camera.position.z = 2500;
-				scene.add( camera );
 
 				cameraPerspective = new THREE.PerspectiveCamera( 50, 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT, 150, 1000 );
 
 				cameraPerspectiveHelper = new THREE.CameraHelper( cameraPerspective );
-				cameraPerspective.add( cameraPerspectiveHelper );
+				scene.add( cameraPerspectiveHelper );
 
 				//
 
 				cameraOrtho = new THREE.OrthographicCamera( 0.5 * SCREEN_WIDTH / - 2, 0.5 * SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / - 2, 150, 1000 );
 
 				cameraOrthoHelper = new THREE.CameraHelper( cameraOrtho );
-				cameraOrtho.add( cameraOrthoHelper );
+				scene.add( cameraOrthoHelper );
 
 				//
 
@@ -166,8 +165,19 @@
 
 				switch( event.keyCode ) {
 
-					case 79: /*O*/	activeCamera = cameraOrtho; activeHelper = cameraOrthoHelper; break;
-					case 80: /*P*/ 	activeCamera = cameraPerspective; activeHelper = cameraPerspectiveHelper; break;
+					case 79: /*O*/
+
+						activeCamera = cameraOrtho;
+						activeHelper = cameraOrthoHelper;
+
+						break;
+
+					case 80: /*P*/
+
+						activeCamera = cameraPerspective;
+						activeHelper = cameraPerspectiveHelper;
+
+						break;
 
 				}
 
@@ -226,9 +236,9 @@
 					cameraPerspective.updateProjectionMatrix();
 
 					cameraPerspectiveHelper.update();
-					cameraPerspectiveHelper.lines.visible = true;
+					cameraPerspectiveHelper.visible = true;
 
-					cameraOrthoHelper.lines.visible = false;
+					cameraOrthoHelper.visible = false;
 
 				} else {
 
@@ -236,9 +246,9 @@
 					cameraOrtho.updateProjectionMatrix();
 
 					cameraOrthoHelper.update();
-					cameraOrthoHelper.lines.visible = true;
+					cameraOrthoHelper.visible = true;
 
-					cameraPerspectiveHelper.lines.visible = false;
+					cameraPerspectiveHelper.visible = false;
 
 				}
 
@@ -246,12 +256,12 @@
 
 				renderer.clear();
 
-				activeHelper.lines.visible = false;
+				activeHelper.visible = false;
 
 				renderer.setViewport( 0, 0, SCREEN_WIDTH/2, SCREEN_HEIGHT );
 				renderer.render( scene, activeCamera );
 
-				activeHelper.lines.visible = true;
+				activeHelper.visible = true;
 
 				renderer.setViewport( SCREEN_WIDTH/2, 0, SCREEN_WIDTH/2, SCREEN_HEIGHT );
 				renderer.render( scene, camera );

+ 2 - 2
examples/webgl_custom_attributes.html

@@ -115,11 +115,11 @@
 
 				amplitude: { type: "f", value: 1.0 },
 				color:     { type: "c", value: new THREE.Color( 0xff2200 ) },
-				texture:   { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "textures/water.jpg" ) },
+				texture:   { type: "t", value: THREE.ImageUtils.loadTexture( "textures/water.jpg" ) },
 
 			};
 
-			uniforms.texture.texture.wrapS = uniforms.texture.texture.wrapT = THREE.RepeatWrapping;
+			uniforms.texture.value.wrapS = uniforms.texture.value.wrapT = THREE.RepeatWrapping;
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 

+ 0 - 3
examples/webgl_custom_attributes_lines.html

@@ -95,7 +95,6 @@
 			bevelSize = 1.5,
 			bevelSegments = 10,
 			bevelEnabled = true,
-			bend = false,
 
 			font = "helvetiker", 		// helvetiker, optimer, gentilis, droid sans, droid serif
 			weight = "bold",		// normal bold
@@ -158,8 +157,6 @@
 				bevelEnabled: bevelEnabled,
 				bevelSegments: bevelSegments,
 
-				bend: bend,
-
 				steps: steps
 
 			});

+ 1 - 1
examples/webgl_custom_attributes_particles.html

@@ -113,7 +113,7 @@
 
 				amplitude: { type: "f", value: 1.0 },
 				color:     { type: "c", value: new THREE.Color( 0xffffff ) },
-				texture:   { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "textures/sprites/spark1.png" ) },
+				texture:   { type: "t", value: THREE.ImageUtils.loadTexture( "textures/sprites/spark1.png" ) },
 
 			};
 

+ 2 - 2
examples/webgl_custom_attributes_particles2.html

@@ -109,11 +109,11 @@
 
 				amplitude: { type: "f", value: 1.0 },
 				color:     { type: "c", value: new THREE.Color( 0xffffff ) },
-				texture:   { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "textures/sprites/disc.png" ) },
+				texture:   { type: "t", value: THREE.ImageUtils.loadTexture( "textures/sprites/disc.png" ) },
 
 			};
 
-			uniforms.texture.texture.wrapS = uniforms.texture.texture.wrapT = THREE.RepeatWrapping;
+			uniforms.texture.value.wrapS = uniforms.texture.value.wrapT = THREE.RepeatWrapping;
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 

+ 2 - 2
examples/webgl_custom_attributes_particles3.html

@@ -117,11 +117,11 @@
 
 				amplitude: { type: "f", value: 1.0 },
 				color:     { type: "c", value: new THREE.Color( 0xffffff ) },
-				texture:   { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "textures/sprites/ball.png" ) },
+				texture:   { type: "t", value: THREE.ImageUtils.loadTexture( "textures/sprites/ball.png" ) },
 
 			};
 
-			uniforms.texture.texture.wrapS = uniforms.texture.texture.wrapT = THREE.RepeatWrapping;
+			uniforms.texture.value.wrapS = uniforms.texture.value.wrapT = THREE.RepeatWrapping;
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 

+ 37 - 51
examples/webgl_geometry_extrude_splines.html

@@ -156,7 +156,7 @@
 
 			if ( toggle ) {
 
-				animation = !animation;
+				animation = animation === false;
 				document.getElementById('animation').value = 'Camera Spline Animation View: ' + (animation? 'ON': 'OFF');
 
 			}
@@ -165,7 +165,7 @@
 
 			showCameraHelper = document.getElementById('cameraHelper').checked;
 
-			cameraHelper.children[0].visible = showCameraHelper;
+			cameraHelper.visible = showCameraHelper;
 			cameraEye.visible = showCameraHelper;
 		}
 
@@ -199,9 +199,6 @@
 			//
 
 			camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 1000);
-			splineCamera = new THREE.PerspectiveCamera(84, window.innerWidth / window.innerHeight, 0.01, 1000);
-			cameraHelper = new THREE.CameraHelper(splineCamera);
-
 			camera.position.set(0, 50, 500);
 
 			scene = new THREE.Scene();
@@ -212,40 +209,39 @@
 
 			parent = new THREE.Object3D();
 			parent.position.y = 100;
-			scene.add(parent);
+			scene.add( parent );
+
+			splineCamera = new THREE.PerspectiveCamera(84, window.innerWidth / window.innerHeight, 0.01, 1000);
+			parent.add(splineCamera);
+
+			cameraHelper = new THREE.CameraHelper(splineCamera);
+			scene.add(cameraHelper);
 
 			addTube();
 
 			// Debug point
-			cameraEye = new THREE.Mesh(new THREE.SphereGeometry(5), new THREE.MeshBasicMaterial({
-					color: 0xdddddd
-			}));
-
-			cameraHelper.children[0].visible = showCameraHelper;
-			cameraEye.visible = showCameraHelper;
 
+			cameraEye = new THREE.Mesh( new THREE.SphereGeometry( 5 ), new THREE.MeshBasicMaterial( { color: 0xdddddd } ) );
 			parent.add(cameraEye);
 
-			cameraHelper.scale.multiplyScalar(0.1);
-			splineCamera.add(cameraHelper);
-			parent.add(splineCamera);
+			cameraHelper.visible = showCameraHelper;
+			cameraEye.visible = showCameraHelper;
 
 			//
-			renderer = new THREE.WebGLRenderer({
-					antialias: true
-			});
-			renderer.setSize(window.innerWidth, window.innerHeight);
 
-			container.appendChild(renderer.domElement);
+			renderer = new THREE.WebGLRenderer( { antialias: true } );
+			renderer.setSize( window.innerWidth, window.innerHeight );
+
+			container.appendChild( renderer.domElement );
 
 			stats = new Stats();
 			stats.domElement.style.position = 'absolute';
 			stats.domElement.style.top = '0px';
-			container.appendChild(stats.domElement);
+			container.appendChild( stats.domElement );
 
-			renderer.domElement.addEventListener('mousedown', onDocumentMouseDown, false);
-			renderer.domElement.addEventListener('touchstart', onDocumentTouchStart, false);
-			renderer.domElement.addEventListener('touchmove', onDocumentTouchMove, false);
+			renderer.domElement.addEventListener( 'mousedown', onDocumentMouseDown, false );
+			renderer.domElement.addEventListener( 'touchstart', onDocumentTouchStart, false );
+			renderer.domElement.addEventListener( 'touchmove', onDocumentTouchMove, false );
 
 			//
 
@@ -271,9 +267,9 @@
 
 			event.preventDefault();
 
-			renderer.domElement.addEventListener('mousemove', onDocumentMouseMove, false);
-			renderer.domElement.addEventListener('mouseup', onDocumentMouseUp, false);
-			renderer.domElement.addEventListener('mouseout', onDocumentMouseOut, false);
+			renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
+			renderer.domElement.addEventListener( 'mouseup', onDocumentMouseUp, false );
+			renderer.domElement.addEventListener( 'mouseout', onDocumentMouseOut, false );
 
 			mouseXOnMouseDown = event.clientX - windowHalfX;
 			targetRotationOnMouseDown = targetRotation;
@@ -290,17 +286,17 @@
 
 		function onDocumentMouseUp(event) {
 
-			renderer.domElement.removeEventListener('mousemove', onDocumentMouseMove, false);
-			renderer.domElement.removeEventListener('mouseup', onDocumentMouseUp, false);
-			renderer.domElement.removeEventListener('mouseout', onDocumentMouseOut, false);
+			renderer.domElement.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+			renderer.domElement.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+			renderer.domElement.removeEventListener( 'mouseout', onDocumentMouseOut, false );
 
 		}
 
 		function onDocumentMouseOut(event) {
 
-			renderer.domElement.removeEventListener('mousemove', onDocumentMouseMove, false);
-			renderer.domElement.removeEventListener('mouseup', onDocumentMouseUp, false);
-			renderer.domElement.removeEventListener('mouseout', onDocumentMouseOut, false);
+			renderer.domElement.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+			renderer.domElement.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+			renderer.domElement.removeEventListener( 'mouseout', onDocumentMouseOut, false );
 
 		}
 
@@ -308,10 +304,10 @@
 
 			if (event.touches.length == 1) {
 
-					event.preventDefault();
+				event.preventDefault();
 
-					mouseXOnMouseDown = event.touches[0].pageX - windowHalfX;
-					targetRotationOnMouseDown = targetRotation;
+				mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
+				targetRotationOnMouseDown = targetRotation;
 
 			}
 
@@ -321,10 +317,10 @@
 
 			if (event.touches.length == 1) {
 
-					event.preventDefault();
+				event.preventDefault();
 
-					mouseX = event.touches[0].pageX - windowHalfX;
-					targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05;
+				mouseX = event.touches[ 0 ].pageX - windowHalfX;
+				targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05;
 
 			}
 
@@ -388,19 +384,9 @@
 
 			cameraHelper.update();
 
-			parent.rotation.y += (targetRotation - parent.rotation.y) * 0.05;
-
-			if (animation) {
-
-				renderer.render(scene, splineCamera);
-
-			} else {
-
-				renderer.render(scene, camera);
-
-			}
-
+			parent.rotation.y += ( targetRotation - parent.rotation.y ) * 0.05;
 
+			renderer.render( scene, animation === true ? splineCamera : camera );
 
 		}
 	</script>

+ 0 - 0
examples/webgl_geometry_subdivison.html → examples/webgl_geometry_subdivision.html


+ 16 - 27
examples/webgl_geometry_text.html

@@ -33,7 +33,6 @@
 			<span class="button" id="font">change font</span>,
 			<span class="button" id="weight">change weight</span>,
 			<span class="button" id="bevel">change bevel</span>,
-			<span class="button" id="bend">bend</span>,
 			<span class="button" id="postprocessing">change postprocessing</span>,
 			<a id="permalink" href="#">permalink</a>
 		</div>
@@ -95,27 +94,29 @@
 				bevelSize = 1.5,
 				bevelSegments = 3,
 				bevelEnabled = true,
-				bend = true,
 
-				font = "optimer", 		// helvetiker, optimer, gentilis, droid sans, droid serif
-				weight = "bold",		// normal bold
-				style = "normal";		// normal italic
+				font = "optimer", // helvetiker, optimer, gentilis, droid sans, droid serif
+				weight = "bold", // normal bold
+				style = "normal"; // normal italic
 
 			var mirror = true;
 
 			var fontMap = {
-			"helvetiker"  : 0,
-			"optimer"  	  : 1,
-			"gentilis" 	  : 2,
-			"droid sans"  : 3,
-			"droid serif" : 4
+
+				"helvetiker": 0,
+				"optimer": 1,
+				"gentilis": 2,
+				"droid sans": 3,
+				"droid serif": 4
 
 			};
 
 			var weightMap = {
-			"normal"	: 0,
-			"bold"		: 1
-			}
+
+				"normal": 0,
+				"bold": 1
+
+			};
 
 			var reverseFontMap = {};
 			var reverseWeightMap = {};
@@ -196,8 +197,7 @@
 					var weighthash = hash.substring( 7, 8 );
 					var pphash 	   = hash.substring( 8, 9 );
 					var bevelhash  = hash.substring( 9, 10 );
-					var bendhash   = hash.substring( 10, 11 );
-					var texthash   = hash.substring( 12 );
+					var texthash   = hash.substring( 10 );
 
 					hex = colorhash;
 					pointLight.color.setHex( parseInt( colorhash, 16 ) );
@@ -207,7 +207,6 @@
 
 					postprocessing.enabled = parseInt( pphash );
 					bevelEnabled = parseInt( bevelhash );
-					bend = parseInt( bendhash );
 
 					text = decodeURI( texthash );
 
@@ -322,13 +321,6 @@
 
 				}, false );
 
-				document.getElementById( "bend" ).addEventListener( 'click', function() {
-
-					bend = !bend;
-					refreshText();
-
-				}, false );
-
 				document.getElementById( "postprocessing" ).addEventListener( 'click', function() {
 
 					postprocessing.enabled = !postprocessing.enabled;
@@ -393,8 +385,7 @@
 
 			function updatePermalink() {
 
-				var link = hex + fontMap[ font ] + weightMap[ weight ] + boolToNum( postprocessing.enabled ) + boolToNum( bevelEnabled )
-				+ boolToNum( bend ) + "#" + encodeURI( text );
+				var link = hex + fontMap[ font ] + weightMap[ weight ] + boolToNum( postprocessing.enabled ) + boolToNum( bevelEnabled ) + "#" + encodeURI( text );
 
 				permalink.href = "#" + link;
 				window.location.hash = link;
@@ -464,8 +455,6 @@
 					bevelSize: bevelSize,
 					bevelEnabled: bevelEnabled,
 
-					bend: bend,
-
 					material: 0,
 					extrudeMaterial: 1
 

+ 1 - 1
examples/webgl_hdr.html

@@ -133,7 +133,7 @@
 				materialHDR = new THREE.ShaderMaterial( {
 
 					uniforms: {
-						tDiffuse:  { type: "t", value: 0, texture: texture },
+						tDiffuse:  { type: "t", value: texture },
 						exposure:  { type: "f", value: 0.125 },
 						brightMax: { type: "f", value: 0.5 }
 						},

+ 8 - 8
examples/webgl_interactive_cubes.html

@@ -57,7 +57,7 @@
 
 				var geometry = new THREE.CubeGeometry( 20, 20, 20 );
 
-				for ( var i = 0; i < 500; i ++ ) {
+				for ( var i = 0; i < 2000; i ++ ) {
 
 					var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );
 
@@ -69,9 +69,9 @@
 					object.rotation.y = ( Math.random() * 360 ) * Math.PI / 180;
 					object.rotation.z = ( Math.random() * 360 ) * Math.PI / 180;
 
-					object.scale.x = Math.random() * 2 + 1;
-					object.scale.y = Math.random() * 2 + 1;
-					object.scale.z = Math.random() * 2 + 1;
+					object.scale.x = Math.random() + 0.5;
+					object.scale.y = Math.random() + 0.5;
+					object.scale.z = Math.random() + 0.5;
 
 					scene.add( object );
 
@@ -153,17 +153,17 @@
 
 					if ( INTERSECTED != intersects[ 0 ].object ) {
 
-						if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
+						if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
 
 						INTERSECTED = intersects[ 0 ].object;
-						INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
-						INTERSECTED.material.color.setHex( 0xff0000 );
+						INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
+						INTERSECTED.material.emissive.setHex( 0xff0000 );
 
 					}
 
 				} else {
 
-					if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
+					if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
 
 					INTERSECTED = null;
 

+ 1 - 1
examples/webgl_kinect.html

@@ -166,7 +166,7 @@
 
 						uniforms: {
 
-							"map": { type: "t", value: 0, texture: texture },
+							"map": { type: "t", value: texture },
 							"width": { type: "f", value: width },
 							"height": { type: "f", value: height },
 							"nearClipping": { type: "f", value: nearClipping },

+ 324 - 0
examples/webgl_lights_hemisphere.html

@@ -0,0 +1,324 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - lights - hemisphere light</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 {
+				background-color: #fff;
+				color: #111;
+				margin: 0px;
+				overflow: hidden;
+				font-family: Monospace;
+				font-size: 13px;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+				text-align: center;
+			}
+
+			a {
+				color: #0080ff;
+				text-decoration: none;
+			}
+
+			a:hover {
+				color: #f00;
+			}
+			#footer { width: 100%; margin: 2em auto; text-align: center; position: absolute; bottom: 0 }
+			strong { color: red }
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info">
+			<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - webgl hemisphere light example -
+			flamingo by <a href="http://mirada.com/">mirada</a> from <a href="http://ro.me">rome</a><br/>
+		</div>
+		<div id="footer">
+			press <strong>h</strong> to toggle hemisphere light, <strong>d</strong> to toggle directional light
+		</div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/Stats.js"></script>
+
+		<script type="x-shader/x-vertex" id="vertexShader">
+
+			varying vec3 worldPosition;
+
+			void main() {
+
+				vec4 mPosition = modelMatrix * vec4( position, 1.0 );
+
+				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+				worldPosition = mPosition.xyz;
+
+			}
+
+		</script>
+
+		<script type="x-shader/x-fragment" id="fragmentShader">
+
+			uniform vec3 topColor;
+			uniform vec3 bottomColor;
+			uniform float offset;
+			uniform float exponent;
+
+			varying vec3 worldPosition;
+
+			void main() {
+
+				float h = normalize( worldPosition + offset ).y;
+				gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( h, exponent ), 0.0 ) ), 1.0 );
+
+			}
+
+		</script>
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var camera, scene, renderer, dirLight, hemiLight;
+			var morphs = [];
+			var stats;
+
+			var clock = new THREE.Clock();
+
+			init();
+			animate();
+
+			function init() {
+
+				var container = document.getElementById( 'container' );
+
+				camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 5000 );
+				camera.position.set( 0, 0, 250 );
+
+				scene = new THREE.Scene();
+
+				scene.fog = new THREE.Fog( 0xffffff, 1, 5000 );
+				scene.fog.color.setHSV( 0.6, 0, 1 );
+
+				/*
+				controls = new THREE.TrackballControls( camera );
+
+				controls.rotateSpeed = 1.0;
+				controls.zoomSpeed = 1.2;
+				controls.panSpeed = 0.8;
+
+				controls.noZoom = false;
+				controls.noPan = false;
+
+				controls.staticMoving = true;
+				controls.dynamicDampingFactor = 0.15;
+				*/
+
+				// LIGHTS
+
+				hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.6 );
+				hemiLight.color.setHSV( 0.6, 0.75, 1 );
+				hemiLight.groundColor.setHSV( 0.095, 0.5, 1 );
+				hemiLight.position.set( 0, 500, 0 );
+				scene.add( hemiLight );
+
+				//
+
+				dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
+				dirLight.color.setHSV( 0.1, 0.1, 1 );
+				dirLight.position.set( -1, 1.75, 1 );
+				dirLight.position.multiplyScalar( 50 );
+				scene.add( dirLight );
+
+				dirLight.castShadow = true;
+
+				dirLight.shadowMapWidth = 2048;
+				dirLight.shadowMapHeight = 2048;
+
+				var d = 50;
+
+				dirLight.shadowCameraLeft = -d;
+				dirLight.shadowCameraRight = d;
+				dirLight.shadowCameraTop = d;
+				dirLight.shadowCameraBottom = -d;
+
+				dirLight.shadowCameraFar = 3500;
+				dirLight.shadowBias = -0.0001;
+				dirLight.shadowDarkness = 0.35;
+				//dirLight.shadowCameraVisible = true;
+
+				// GROUND
+
+				var groundGeo = new THREE.PlaneGeometry( 10000, 10000 );
+				var groundMat = new THREE.MeshPhongMaterial( { ambient: 0xffffff, color: 0xffffff, specular: 0x050505, perPixel: true } );
+				groundMat.color.setHSV( 0.095, 0.5, 1 );
+
+				var ground = new THREE.Mesh( groundGeo, groundMat );
+				ground.rotation.x = -Math.PI/2;
+				ground.position.y = -33;
+				scene.add( ground );
+
+				ground.receiveShadow = true;
+
+				// SKYDOME
+
+				var vertexShader = document.getElementById( 'vertexShader' ).textContent;
+				var fragmentShader = document.getElementById( 'fragmentShader' ).textContent;
+				var uniforms = {
+					topColor: 	 { type: "c", value: new THREE.Color( 0x0077ff ) },
+					bottomColor: { type: "c", value: new THREE.Color( 0xffffff ) },
+					offset:		 { type: "f", value: 33 },
+					exponent:	 { type: "f", value: 0.6 }
+				}
+				uniforms.topColor.value.copy( hemiLight.color );
+
+				scene.fog.color.copy( uniforms.bottomColor.value );
+
+				var skyGeo = new THREE.SphereGeometry( 4000, 32, 15 );
+				var skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } );
+
+				var sky = new THREE.Mesh( skyGeo, skyMat );
+				scene.add( sky );
+
+				// MODEL
+
+				var loader = new THREE.JSONLoader();
+
+				loader.load( "models/animated/flamingo.js", function( geometry ) {
+
+					morphColorsToFaceColors( geometry );
+					geometry.computeMorphNormals();
+
+					var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0xffffff, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.FlatShading, perPixel: false } );
+					var meshAnim = new THREE.MorphAnimMesh( geometry, material );
+
+					meshAnim.duration = 1000;
+
+					var s = 0.35;
+					meshAnim.scale.set( s, s, s );
+					meshAnim.position.y = 15;
+					meshAnim.rotation.y = -1;
+
+					meshAnim.castShadow = true;
+					meshAnim.receiveShadow = true;
+
+					scene.add( meshAnim );
+					morphs.push( meshAnim );
+
+				} );
+
+				// RENDERER
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				renderer.setClearColor( scene.fog.color, 1 );
+
+				renderer.gammaInput = true;
+				renderer.gammaOutput = true;
+				renderer.physicallyBasedShading = true;
+
+				renderer.shadowMapEnabled = true;
+				renderer.shadowMapCullFrontFaces = false;
+
+				// STATS
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+
+				stats.domElement.children[ 0 ].children[ 0 ].style.color = "#777";
+				stats.domElement.children[ 0 ].style.background = "transparent";
+				stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+				document.addEventListener( 'keydown', onKeyDown, false );
+
+			}
+
+			function morphColorsToFaceColors( geometry ) {
+
+				if ( geometry.morphColors && geometry.morphColors.length ) {
+
+					var colorMap = geometry.morphColors[ 0 ];
+
+					for ( var i = 0; i < colorMap.colors.length; i ++ ) {
+
+						geometry.faces[ i ].color = colorMap.colors[ i ];
+						THREE.ColorUtils.adjustHSV( geometry.faces[ i ].color, 0, -0.1, 0 );
+
+					}
+
+				}
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function onKeyDown ( event ) {
+
+				switch ( event.keyCode ) {
+
+					case 72: /*h*/
+
+					hemiLight.visible = !hemiLight.visible;
+					break;
+
+					case 68: /*d*/
+
+					dirLight.visible = !dirLight.visible;
+					break;
+
+				}
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				var delta = clock.getDelta();
+
+				//controls.update();
+
+				for ( var i = 0; i < morphs.length; i ++ ) {
+
+					morph = morphs[ i ];
+					morph.updateAnimation( 1000 * delta );
+
+				}
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 3 - 3
examples/webgl_loader_ctm.html

@@ -194,11 +194,11 @@
 					var shader = THREE.ShaderUtils.lib[ "normal" ];
 					var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-					uniforms[ "tNormal" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
+					uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
 					uniforms[ "uNormalScale" ].value = 0.8;
 
-					uniforms[ "tDiffuse" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
-					uniforms[ "tSpecular" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
+					uniforms[ "tDiffuse" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
+					uniforms[ "tSpecular" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
 
 					uniforms[ "enableAO" ].value = false;
 					uniforms[ "enableDiffuse" ].value = true;

+ 1 - 1
examples/webgl_loader_ctm_materials.html

@@ -106,7 +106,7 @@
 				textureCube = THREE.ImageUtils.loadTextureCube( urls );
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 210 - 0
examples/webgl_loader_stl.html

@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - STL</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 {
+				font-family: Monospace;
+				background-color: #000000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				z-index: 100;
+				display:block;
+
+			}
+
+			a { color: skyblue }
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> -
+			STL loader test by <a href="https://github.com/aleeper">aleeper</a>
+		</div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/loaders/STLLoader.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/Stats.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var container, stats;
+
+			var camera, scene, renderer, objects;
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 );
+				camera.position.set( 3, 0.5, 3 );
+
+				scene = new THREE.Scene();
+
+				scene.fog = new THREE.Fog( 0xffffff, 2, 15 );
+				scene.fog.color.setHSV( 0.06, 0.2, 0.45 );
+
+				// Grid
+
+				var size = 20, step = 0.25;
+
+				var geometry = new THREE.Geometry();
+				var material = new THREE.LineBasicMaterial( { color: 0x000000 } );
+
+				for ( var i = - size; i <= size; i += step ) {
+
+					geometry.vertices.push( new THREE.Vector3( - size, - 0.04, i ) );
+					geometry.vertices.push( new THREE.Vector3(   size, - 0.04, i ) );
+
+					geometry.vertices.push( new THREE.Vector3( i, - 0.04, - size ) );
+					geometry.vertices.push( new THREE.Vector3( i, - 0.04,   size ) );
+
+				}
+
+				var line = new THREE.Line( geometry, material, THREE.LinePieces );
+				line.position.y = -0.46;
+				scene.add( line );
+
+				// Ground
+
+				var plane = new THREE.Mesh( new THREE.PlaneGeometry( 40, 40 ), new THREE.MeshPhongMaterial( { ambient: 0x999999, color: 0x999999, specular: 0x101010, perPixel: true } ) );
+				plane.rotation.x = -Math.PI/2;
+				plane.position.y = -0.5;
+				scene.add( plane );
+
+				plane.receiveShadow = true;
+
+				// Object
+
+				var loader = new THREE.STLLoader();
+				loader.addEventListener( 'load', function ( event ) {
+
+					var geometry = event.content;
+					var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200, perPixel: true } );
+					var mesh = new THREE.Mesh( geometry, material );
+
+					mesh.castShadow = true;
+					mesh.receiveShadow = true;
+
+					scene.add( mesh );
+
+				} );
+				loader.load( './models/stl/slotted_disk.stl' );
+
+				// Lights
+
+				scene.add( new THREE.AmbientLight( 0x777777 ) );
+
+				addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
+				addShadowedLight( 0.5, 1, -1, 0xffaa00, 1 );
+
+				// renderer
+
+				renderer = new THREE.WebGLRenderer( { antialias: true, clearColor: 0x111111, clearAlpha: 1, alpha: false } );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				renderer.setClearColor( scene.fog.color, 1 );
+
+				renderer.gammaInput = true;
+				renderer.gammaOutput = true;
+				renderer.physicallyBasedShading = true;
+
+				renderer.shadowMapEnabled = true;
+				renderer.shadowMapCullFrontFaces = false;
+
+				container.appendChild( renderer.domElement );
+
+				// stats
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function addShadowedLight( x, y, z, color, intensity ) {
+
+				var directionalLight = new THREE.DirectionalLight( color, intensity );
+				directionalLight.position.set( x, y, z )
+				scene.add( directionalLight );
+
+				directionalLight.castShadow = true;
+				//directionalLight.shadowCameraVisible = true;
+
+				var d = 1;
+				directionalLight.shadowCameraLeft = -d;
+				directionalLight.shadowCameraRight = d;
+				directionalLight.shadowCameraTop = d;
+				directionalLight.shadowCameraBottom = -d;
+
+				directionalLight.shadowCameraNear = 1;
+				directionalLight.shadowCameraFar = 4;
+
+				directionalLight.shadowMapWidth = 2048;
+				directionalLight.shadowMapHeight = 2048;
+
+				directionalLight.shadowBias = -0.005;
+				directionalLight.shadowDarkness = 0.15;
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				var timer = Date.now() * 0.0005;
+
+				camera.position.x = Math.cos( timer ) * 5;
+				camera.position.z = Math.sin( timer ) * 5;
+
+				camera.lookAt( scene.position );
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 4 - 4
examples/webgl_materials_bumpmap_skin.html

@@ -277,11 +277,11 @@
 				uniforms[ "enableBump" ].value = true;
 				uniforms[ "enableSpecular" ].value = true;
 
-				uniforms[ "tBeckmann" ].texture = composerBeckmann.renderTarget1;
-				uniforms[ "tDiffuse" ].texture = mapColor;
+				uniforms[ "tBeckmann" ].value = composerBeckmann.renderTarget1;
+				uniforms[ "tDiffuse" ].value = mapColor;
 
-				uniforms[ "bumpMap" ].texture = mapHeight;
-				uniforms[ "specularMap" ].texture = mapSpecular;
+				uniforms[ "bumpMap" ].value = mapHeight;
+				uniforms[ "specularMap" ].value = mapSpecular;
 
 				uniforms[ "uAmbientColor" ].value.setHex( 0xa0a0a0 );
 				uniforms[ "uDiffuseColor" ].value.setHex( 0xa0a0a0 );

+ 1 - 1
examples/webgl_materials_cars.html

@@ -190,7 +190,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cars_anaglyph.html

@@ -185,7 +185,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cars_parallaxbarrier.html

@@ -185,7 +185,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 2 - 2
examples/webgl_materials_cubemap.html

@@ -107,7 +107,7 @@
 				reflectionCube.format = THREE.RGBFormat;
 
 				var refractionCube = new THREE.Texture( reflectionCube.image, new THREE.CubeRefractionMapping() );
-				reflectionCube.format = THREE.RGBFormat;
+				refractionCube.format = THREE.RGBFormat;
 
 				//var cubeMaterial3 = new THREE.MeshPhongMaterial( { color: 0x000000, specular:0xaa0000, envMap: reflectionCube, combine: THREE.MixOperation, reflectivity: 0.25 } );
 				var cubeMaterial3 = new THREE.MeshLambertMaterial( { color: 0xff6600, ambient: 0x993300, envMap: reflectionCube, combine: THREE.MixOperation, reflectivity: 0.3 } );
@@ -117,7 +117,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = reflectionCube;
+				shader.uniforms[ "tCube" ].value = reflectionCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cubemap_balls_reflection.html

@@ -109,7 +109,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cubemap_balls_reflection_anaglyph.html

@@ -107,7 +107,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cubemap_balls_refraction.html

@@ -108,7 +108,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cubemap_balls_refraction_crosseyed.html

@@ -108,7 +108,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cubemap_dynamic.html

@@ -445,7 +445,7 @@
 
 				// motion blur
 
-				effectBlend.uniforms[ 'tDiffuse2' ].texture = effectSave.renderTarget;
+				effectBlend.uniforms[ 'tDiffuse2' ].value = effectSave.renderTarget;
 				effectBlend.uniforms[ 'mixRatio' ].value = 0.65;
 
 				var renderModel = new THREE.RenderPass( scene, camera );

+ 8 - 8
examples/webgl_materials_cubemap_dynamic2.html

@@ -10,7 +10,7 @@
 				margin: 0px;
 				overflow: hidden;
 			}
-			
+
 			#info {
 				position: absolute;
 				top: 0px; width: 100%;
@@ -37,7 +37,7 @@
 
 			var camera, cubeCamera, scene, renderer;
 			var cube, sphere, torus;
-			
+
 			var fov = 70,
 			isUserInteracting = false,
 			onMouseDownMouseX = 0, onMouseDownMouseY = 0,
@@ -74,7 +74,7 @@
 				//
 
 				var material = new THREE.MeshBasicMaterial( { envMap: cubeCamera.renderTarget } );
-				
+
 				sphere = new THREE.Mesh( new THREE.SphereGeometry( 20, 60, 40 ), material );
 				scene.add( sphere );
 
@@ -90,11 +90,11 @@
 				document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
 				document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false);
 				window.addEventListener( 'resize', onWindowResized, false );
-			
+
 				onWindowResized( null );
 
 			}
-			
+
 			function onWindowResized( event ) {
 
 				renderer.setSize( window.innerWidth, window.innerHeight );
@@ -153,7 +153,7 @@
 				}
 
 				camera.projectionMatrix.makePerspective( fov, window.innerWidth / window.innerHeight, 1, 1100 );
-				
+
 			}
 
 			function animate() {
@@ -164,7 +164,7 @@
 			}
 
 			function render() {
-				
+
 				var time = Date.now();
 
 				lon += .15;
@@ -211,6 +211,6 @@
 			}
 
 		</script>
-	
+
 	</body>
 </html>

+ 1 - 1
examples/webgl_materials_cubemap_escher.html

@@ -87,7 +87,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 1 - 1
examples/webgl_materials_cubemap_refraction.html

@@ -110,7 +110,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 4 - 4
examples/webgl_materials_normalmap.html

@@ -162,10 +162,10 @@
 				uniforms[ "enableReflection" ].value = true;
 				uniforms[ "enableDisplacement" ].value = true;
 
-				uniforms[ "tNormal" ].texture = THREE.ImageUtils.loadTexture( "textures/normal/ninja/normal.jpg" );
-				uniforms[ "tAO" ].texture = THREE.ImageUtils.loadTexture( "textures/normal/ninja/ao.jpg" );
+				uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/normal.jpg" );
+				uniforms[ "tAO" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/ao.jpg" );
 
-				uniforms[ "tDisplacement" ].texture = THREE.ImageUtils.loadTexture( "textures/normal/ninja/displacement.jpg" );
+				uniforms[ "tDisplacement" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/displacement.jpg" );
 				uniforms[ "uDisplacementBias" ].value = - 0.428408;
 				uniforms[ "uDisplacementScale" ].value = 2.436143;
 
@@ -175,7 +175,7 @@
 
 				uniforms[ "uShininess" ].value = shininess;
 
-				uniforms[ "tCube" ].texture = reflectionCube;
+				uniforms[ "tCube" ].value = reflectionCube;
 				uniforms[ "uReflectivity" ].value = 0.1;
 
 				uniforms[ "uDiffuseColor" ].value.convertGammaToLinear();

+ 3 - 3
examples/webgl_materials_normalmap2.html

@@ -124,11 +124,11 @@
 				var shader = THREE.ShaderUtils.lib[ "normal" ];
 				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-				uniforms[ "tNormal" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
+				uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
 				uniforms[ "uNormalScale" ].value = 0.8;
 
-				uniforms[ "tDiffuse" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
-				uniforms[ "tSpecular" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
+				uniforms[ "tDiffuse" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
+				uniforms[ "tSpecular" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
 
 				uniforms[ "enableAO" ].value = false;
 				uniforms[ "enableDiffuse" ].value = true;

+ 2 - 2
examples/webgl_materials_shaders_fresnel.html

@@ -93,7 +93,7 @@
 				var shader = THREE.ShaderUtils.lib[ "fresnel" ];
 				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-				uniforms[ "tCube" ].texture = textureCube;
+				uniforms[ "tCube" ].value = textureCube;
 
 				var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms };
 				var material = new THREE.ShaderMaterial( parameters );
@@ -119,7 +119,7 @@
 				// Skybox
 
 				var shader = THREE.ShaderUtils.lib[ "cube" ];
-				shader.uniforms[ "tCube" ].texture = textureCube;
+				shader.uniforms[ "tCube" ].value = textureCube;
 
 				var material = new THREE.ShaderMaterial( {
 

+ 9 - 9
examples/webgl_materials_skin.html

@@ -114,10 +114,10 @@
 
 				var uniformsUV = THREE.UniformsUtils.clone( shader.uniforms );
 
-				uniformsUV[ "tNormal" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
+				uniformsUV[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
 				uniformsUV[ "uNormalScale" ].value = 0.75;
 
-				uniformsUV[ "tDiffuse" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
+				uniformsUV[ "tDiffuse" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
 
 				uniformsUV[ "passID" ].value = 0;
 
@@ -129,8 +129,8 @@
 				uniformsUV[ "uSpecularBrightness" ].value = 0.8;
 
 				var uniforms = THREE.UniformsUtils.clone( uniformsUV );
-				uniforms[ "tDiffuse" ].texture = uniformsUV[ "tDiffuse" ].texture;
-				uniforms[ "tNormal" ].texture = uniformsUV[ "tNormal" ].texture;
+				uniforms[ "tDiffuse" ].value = uniformsUV[ "tDiffuse" ].value;
+				uniforms[ "tNormal" ].value = uniformsUV[ "tNormal" ].value;
 				uniforms[ "passID" ].value = 1;
 
 				var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
@@ -246,12 +246,12 @@
 
 				//
 
-				uniforms[ "tBlur1" ].texture = composerScene.renderTarget2;
-				uniforms[ "tBlur2" ].texture = composerUV1.renderTarget2;
-				uniforms[ "tBlur3" ].texture = composerUV2.renderTarget2;
-				uniforms[ "tBlur4" ].texture = composerUV3.renderTarget2;
+				uniforms[ "tBlur1" ].value = composerScene.renderTarget2;
+				uniforms[ "tBlur2" ].value = composerUV1.renderTarget2;
+				uniforms[ "tBlur3" ].value = composerUV2.renderTarget2;
+				uniforms[ "tBlur4" ].value = composerUV3.renderTarget2;
 
-				uniforms[ "tBeckmann" ].texture = composerBeckmann.renderTarget1;
+				uniforms[ "tBeckmann" ].value = composerBeckmann.renderTarget1;
 
 				//
 

+ 2 - 0
examples/webgl_particles_dynamic.html

@@ -89,6 +89,8 @@
 				scene = new THREE.Scene();
 				scene.fog = new THREE.FogExp2( 0x000104, 0.0000675 );
 
+				camera.lookAt( scene.position );
+
 				//
 
 				aloader = new THREE.JSONLoader( );

+ 1 - 1
examples/webgl_particles_shapes.html

@@ -262,7 +262,7 @@
 
 				uniforms = {
 
-					texture:   { type: "t", value: 0, texture: texture }
+					texture:   { type: "t", value: texture }
 
 				};
 

+ 4 - 4
examples/webgl_postprocessing.html

@@ -275,7 +275,7 @@
 
 				//onWindowResize();
 
-				renderScene.uniforms[ "tDiffuse" ].texture = composerScene.renderTarget2;
+				renderScene.uniforms[ "tDiffuse" ].value = composerScene.renderTarget2;
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
@@ -305,7 +305,7 @@
 				composer3.reset( new THREE.WebGLRenderTarget( halfWidth, halfHeight, rtParameters ) );
 				composer4.reset( new THREE.WebGLRenderTarget( halfWidth, halfHeight, rtParameters ) );
 
-				renderScene.uniforms[ "tDiffuse" ].texture = composerScene.renderTarget2;
+				renderScene.uniforms[ "tDiffuse" ].value = composerScene.renderTarget2;
 
 				quadBG.scale.set( window.innerWidth, 1, window.innerHeight );
 				quadMask.scale.set( window.innerWidth / 2, 1, window.innerHeight / 2 );
@@ -327,10 +327,10 @@
 				var shader = THREE.ShaderUtils.lib[ "normal" ];
 				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-				uniforms[ "tNormal" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
+				uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
 				uniforms[ "uNormalScale" ].value = 0.75;
 
-				uniforms[ "tDiffuse" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
+				uniforms[ "tDiffuse" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
 
 				uniforms[ "enableAO" ].value = false;
 				uniforms[ "enableDiffuse" ].value = true;

+ 2 - 2
examples/webgl_postprocessing_dof.html

@@ -247,8 +247,8 @@
 
 				postprocessing.bokeh_uniforms = THREE.UniformsUtils.clone( bokeh_shader.uniforms );
 
-				postprocessing.bokeh_uniforms[ "tColor" ].texture = postprocessing.rtTextureColor;
-				postprocessing.bokeh_uniforms[ "tDepth" ].texture = postprocessing.rtTextureDepth;
+				postprocessing.bokeh_uniforms[ "tColor" ].value = postprocessing.rtTextureColor;
+				postprocessing.bokeh_uniforms[ "tDepth" ].value = postprocessing.rtTextureDepth;
 				postprocessing.bokeh_uniforms[ "focus" ].value = 1.1;
 				postprocessing.bokeh_uniforms[ "aspect" ].value = window.innerWidth / height;
 

+ 5 - 5
examples/webgl_postprocessing_godrays.html

@@ -370,7 +370,7 @@
 					var stepLen = filterLen * Math.pow( TAPS_PER_PASS, -pass );
 
 					postprocessing.godrayGenUniforms[ "fStepSize" ].value = stepLen;
-					postprocessing.godrayGenUniforms[ "tInput" ].texture = postprocessing.rtTextureDepth;
+					postprocessing.godrayGenUniforms[ "tInput" ].value = postprocessing.rtTextureDepth;
 
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysGenerate;
 
@@ -382,7 +382,7 @@
 					stepLen = filterLen * Math.pow( TAPS_PER_PASS, -pass );
 
 					postprocessing.godrayGenUniforms[ "fStepSize" ].value = stepLen;
-					postprocessing.godrayGenUniforms[ "tInput" ].texture = postprocessing.rtTextureGodRays2;
+					postprocessing.godrayGenUniforms[ "tInput" ].value = postprocessing.rtTextureGodRays2;
 
 					renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTextureGodRays1  );
 
@@ -392,14 +392,14 @@
 					stepLen = filterLen * Math.pow( TAPS_PER_PASS, -pass );
 
 					postprocessing.godrayGenUniforms[ "fStepSize" ].value = stepLen;
-					postprocessing.godrayGenUniforms[ "tInput" ].texture = postprocessing.rtTextureGodRays1;
+					postprocessing.godrayGenUniforms[ "tInput" ].value = postprocessing.rtTextureGodRays1;
 
 					renderer.render( postprocessing.scene, postprocessing.camera , postprocessing.rtTextureGodRays2  );
 
 					// final pass - composite god-rays onto colors
 
-					postprocessing.godrayCombineUniforms["tColors"].texture = postprocessing.rtTextureColors;
-					postprocessing.godrayCombineUniforms["tGodRays"].texture = postprocessing.rtTextureGodRays2;
+					postprocessing.godrayCombineUniforms["tColors"].value = postprocessing.rtTextureColors;
+					postprocessing.godrayCombineUniforms["tGodRays"].value = postprocessing.rtTextureGodRays2;
 
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysCombine;
 

+ 1 - 1
examples/webgl_rtt.html

@@ -139,7 +139,7 @@
 
 				var materialScreen = new THREE.ShaderMaterial( {
 
-					uniforms: { tDiffuse: { type: "t", value: 0, texture: rtTexture } },
+					uniforms: { tDiffuse: { type: "t", value: rtTexture } },
 					vertexShader: document.getElementById( 'vertexShader' ).textContent,
 					fragmentShader: document.getElementById( 'fragment_shader_screen' ).textContent,
 

+ 3 - 3
examples/webgl_shader2.html

@@ -12,7 +12,7 @@
 				text-align:center;
 				font-weight: bold;
 
-				background-color: #000000;
+				background-color: #050505;
 				margin: 0px;
 				overflow: hidden;
 			}
@@ -207,10 +207,10 @@
 				uniforms2 = {
 					time: { type: "f", value: 1.0 },
 					resolution: { type: "v2", value: new THREE.Vector2() },
-					texture: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "textures/disturb.jpg" ) }
+					texture: { type: "t", value: THREE.ImageUtils.loadTexture( "textures/disturb.jpg" ) }
 				};
 
-				uniforms2.texture.texture.wrapS = uniforms2.texture.texture.wrapT = THREE.RepeatWrapping;
+				uniforms2.texture.value.wrapS = uniforms2.texture.value.wrapT = THREE.RepeatWrapping;
 
 				var size = 0.75, mlib = [],
 					params = [ [ 'fragment_shader1', uniforms1 ],  [ 'fragment_shader2', uniforms2 ], [ 'fragment_shader3', uniforms1 ], [ 'fragment_shader4', uniforms1 ] ];

+ 4 - 4
examples/webgl_shader_lava.html

@@ -154,13 +154,13 @@
 					time: { type: "f", value: 1.0 },
 					resolution: { type: "v2", value: new THREE.Vector2() },
 					uvScale: { type: "v2", value: new THREE.Vector2( 3.0, 1.0 ) },
-					texture1: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "textures/lava/cloud.png" ) },
-					texture2: { type: "t", value: 1, texture: THREE.ImageUtils.loadTexture( "textures/lava/lavatile.jpg" ) }
+					texture1: { type: "t", value: THREE.ImageUtils.loadTexture( "textures/lava/cloud.png" ) },
+					texture2: { type: "t", value: THREE.ImageUtils.loadTexture( "textures/lava/lavatile.jpg" ) }
 
 				};
 
-				uniforms.texture1.texture.wrapS = uniforms.texture1.texture.wrapT = THREE.RepeatWrapping;
-				uniforms.texture2.texture.wrapS = uniforms.texture2.texture.wrapT = THREE.RepeatWrapping;
+				uniforms.texture1.value.wrapS = uniforms.texture1.value.wrapT = THREE.RepeatWrapping;
+				uniforms.texture2.value.wrapS = uniforms.texture2.value.wrapT = THREE.RepeatWrapping;
 
 				var size = 0.65;
 

+ 8 - 8
examples/webgl_terrain_dynamic.html

@@ -339,7 +339,7 @@
 
 				uniformsNormal.height.value = 0.05;
 				uniformsNormal.resolution.value.set( rx, ry );
-				uniformsNormal.heightMap.texture = heightMap;
+				uniformsNormal.heightMap.value = heightMap;
 
 				var vertexShader = document.getElementById( 'vertexShader' ).textContent;
 
@@ -368,15 +368,15 @@
 
 				uniformsTerrain = THREE.UniformsUtils.clone( terrainShader.uniforms );
 
-				uniformsTerrain[ "tNormal" ].texture = normalMap;
+				uniformsTerrain[ "tNormal" ].value = normalMap;
 				uniformsTerrain[ "uNormalScale" ].value = 3.5;
 
-				uniformsTerrain[ "tDisplacement" ].texture = heightMap;
+				uniformsTerrain[ "tDisplacement" ].value = heightMap;
 
-				uniformsTerrain[ "tDiffuse1" ].texture = diffuseTexture1;
-				uniformsTerrain[ "tDiffuse2" ].texture = diffuseTexture2;
-				uniformsTerrain[ "tSpecular" ].texture = specularMap;
-				uniformsTerrain[ "tDetail" ].texture = detailTexture;
+				uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture1;
+				uniformsTerrain[ "tDiffuse2" ].value = diffuseTexture2;
+				uniformsTerrain[ "tSpecular" ].value = specularMap;
+				uniformsTerrain[ "tDetail" ].value = detailTexture;
 
 				uniformsTerrain[ "enableDiffuse1" ].value = true;
 				uniformsTerrain[ "enableDiffuse2" ].value = true;
@@ -625,7 +625,7 @@
 
 				} );
 
-				shaderMaterial.uniforms[ "tDiffuse" ].texture = texture;
+				shaderMaterial.uniforms[ "tDiffuse" ].value = texture;
 
 				var sceneTmp = new THREE.Scene();
 

+ 3 - 3
examples/webgl_trackballcamera_earth.html

@@ -132,11 +132,11 @@
 				var shader = THREE.ShaderUtils.lib[ "normal" ],
 				uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-				uniforms[ "tNormal" ].texture = normalTexture;
+				uniforms[ "tNormal" ].value = normalTexture;
 				uniforms[ "uNormalScale" ].value = 0.85;
 
-				uniforms[ "tDiffuse" ].texture = planetTexture;
-				uniforms[ "tSpecular" ].texture = specularTexture;
+				uniforms[ "tDiffuse" ].value = planetTexture;
+				uniforms[ "tSpecular" ].value = specularTexture;
 
 				uniforms[ "enableAO" ].value = false;
 				uniforms[ "enableDiffuse" ].value = true;

+ 29 - 17
gui/index.html

@@ -19,23 +19,24 @@
 	</head>
 	<body>
 
-		<script type="text/javascript" src="../build/three.min.js"></script>
-		<script type="text/javascript" src="../examples/js/loaders/ColladaLoader.js"></script>
-		<script type="text/javascript" src="../examples/js/loaders/OBJLoader.js"></script>
-		<script type="text/javascript" src="../examples/js/loaders/UTF8Loader.js"></script>
-		<script type="text/javascript" src="../examples/js/loaders/VTKLoader.js"></script>
-
-		<script type="text/javascript" src="js/libs/signals.min.js"></script>
-
-		<script type="text/javascript" src="js/UI.js"></script>
-		<script type="text/javascript" src="js/ui/Menubar.js"></script>
-		<script type="text/javascript" src="js/ui/Viewport.js"></script>
-		<script type="text/javascript" src="js/ui/Sidebar.js"></script>
-		<script type="text/javascript" src="js/ui/Sidebar.Outliner.js"></script>
-		<script type="text/javascript" src="js/ui/Sidebar.Properties.js"></script>
-		<script type="text/javascript" src="js/ui/Sidebar.Properties.Object3D.js"></script>
-		<script type="text/javascript" src="js/ui/Sidebar.Properties.Geometry.js"></script>
-		<script type="text/javascript" src="js/ui/Sidebar.Properties.Material.js"></script>
+		<script src="../build/three.min.js"></script>
+		<script src="../examples/js/loaders/ColladaLoader.js"></script>
+		<script src="../examples/js/loaders/OBJLoader.js"></script>
+		<script src="../examples/js/loaders/STLLoader.js"></script>
+		<script src="../examples/js/loaders/UTF8Loader.js"></script>
+		<script src="../examples/js/loaders/VTKLoader.js"></script>
+
+		<script src="js/libs/signals.min.js"></script>
+
+		<script src="js/UI.js"></script>
+		<script src="js/ui/Menubar.js"></script>
+		<script src="js/ui/Viewport.js"></script>
+		<script src="js/ui/Sidebar.js"></script>
+		<script src="js/ui/Sidebar.Outliner.js"></script>
+		<script src="js/ui/Sidebar.Properties.js"></script>
+		<script src="js/ui/Sidebar.Properties.Object3D.js"></script>
+		<script src="js/ui/Sidebar.Properties.Geometry.js"></script>
+		<script src="js/ui/Sidebar.Properties.Material.js"></script>
 
 		<script>
 
@@ -124,6 +125,17 @@
 
 							break;
 
+						case 'stl':
+
+							var geometry = new THREE.STLLoader().parse( contents );
+
+							var mesh = new THREE.Mesh( geometry );
+
+							signals.objectAdded.dispatch( mesh );
+							signals.objectSelected.dispatch( mesh );
+
+							break;
+
 						case 'utf8':
 
 							// TODO

+ 1 - 1
src/Three.js

@@ -2,7 +2,7 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-var THREE = THREE || { REVISION: '50' };
+var THREE = THREE || { REVISION: '51dev' };
 
 if ( self.console === undefined ) {
 

+ 1 - 1
src/cameras/PerspectiveCamera.js

@@ -28,7 +28,7 @@ THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype );
 
 THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
 
-	frameHeight = frameHeight !== undefined ? frameHeight : 24;
+	if ( frameHeight === undefined ) frameHeight = 24;
 
 	this.fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
 	this.updateProjectionMatrix();

+ 34 - 18
src/core/Object3D.js

@@ -92,6 +92,18 @@ THREE.Object3D.prototype = {
 
 	},
 
+	localToWorld: function ( vector ) {
+
+		return this.matrixWorld.multiplyVector3( vector );
+
+	},
+
+	worldToLocal: function ( vector ) {
+
+		return THREE.Object3D.__m1.getInverse( this.matrixWorld ).multiplyVector3( vector );
+
+	},
+
 	lookAt: function ( vector ) {
 
 		// TODO: Add hierarchy support.
@@ -207,17 +219,33 @@ THREE.Object3D.prototype = {
 
 	},
 
+	getDescendants: function ( array ) {
+
+		if ( array === undefined ) array = [];
+
+		Array.prototype.push.apply( array, this.children );
+
+		for ( var i = 0, l = this.children.length; i < l; i ++ ) {
+
+			this.children[ i ].getDescendants( array );
+
+		};
+
+		return array;
+
+	},
+
 	updateMatrix: function () {
 
 		this.matrix.setPosition( this.position );
 
-		if ( this.useQuaternion === true )  {
+		if ( this.useQuaternion === false )  {
 
-			this.matrix.setRotationFromQuaternion( this.quaternion );
+			this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
 
 		} else {
 
-			this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
+			this.matrix.setRotationFromQuaternion( this.quaternion );
 
 		}
 
@@ -238,13 +266,13 @@ THREE.Object3D.prototype = {
 
 		if ( this.matrixWorldNeedsUpdate === true || force === true ) {
 
-			if ( this.parent !== undefined ) {
+			if ( this.parent === undefined ) {
 
-				this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
+				this.matrixWorld.copy( this.matrix );
 
 			} else {
 
-				this.matrixWorld.copy( this.matrix );
+				this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
 
 			}
 
@@ -264,18 +292,6 @@ THREE.Object3D.prototype = {
 
 	},
 
-	worldToLocal: function ( vector ) {
-
-		return THREE.Object3D.__m1.getInverse( this.matrixWorld ).multiplyVector3( vector );
-
-	},
-
-	localToWorld: function ( vector ) {
-
-		return this.matrixWorld.multiplyVector3( vector );
-
-	},
-
 	clone: function () {
 
 		// TODO

+ 46 - 73
src/core/Projector.js

@@ -6,11 +6,12 @@
 
 THREE.Projector = function() {
 
-	var _object, _objectCount, _objectPool = [],
-	_vertex, _vertexCount, _vertexPool = [],
-	_face, _face3Count, _face3Pool = [], _face4Count, _face4Pool = [],
-	_line, _lineCount, _linePool = [],
-	_particle, _particleCount, _particlePool = [],
+	var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
+	_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
+	_face, _face3Count, _face3Pool = [], _face3PoolLength = 0,
+	_face4Count, _face4Pool = [], _face4PoolLength = 0,
+	_line, _lineCount, _linePool = [], _linePoolLength = 0,
+	_particle, _particleCount, _particlePool = [], _particlePoolLength = 0,
 
 	_renderData = { objects: [], sprites: [], lights: [], elements: [] },
 
@@ -67,7 +68,7 @@ THREE.Projector = function() {
 
 	};
 
-	function projectGraph( root, sort ) {
+	var projectGraph = function ( root, sort ) {
 
 		_objectCount = 0;
 
@@ -293,6 +294,8 @@ THREE.Projector = function() {
 
 					}
 
+					_face.vertexNormalsLength = faceVertexNormals.length;
+
 					for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
 
 						uvs = faceVertexUvs[ c ][ f ];
@@ -320,7 +323,7 @@ THREE.Projector = function() {
 				_modelViewProjectionMatrix.multiply( _viewProjectionMatrix, modelMatrix );
 
 				vertices = object.geometry.vertices;
-				
+
 				v1 = getNextVertexInPool();
 				v1.positionScreen.copy( vertices[ 0 ] );
 				_modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
@@ -411,128 +414,98 @@ THREE.Projector = function() {
 
 	function getNextObjectInPool() {
 
-		var object;
+		if ( _objectCount === _objectPoolLength ) {
 
-		if ( _objectCount === _objectPool.length ) {
-
-			object = new THREE.RenderableObject();
+			var object = new THREE.RenderableObject();
 			_objectPool.push( object );
-
-		} else {
-
-			object =  _objectPool[ _objectCount ];
+			_objectPoolLength ++;
+			_objectCount ++;
+			return object;
 
 		}
 
-		_objectCount ++;
-
-		return object;
+		return _objectPool[ _objectCount ++ ];
 
 	}
 
 	function getNextVertexInPool() {
 
-		var vertex;
-
-		if ( _vertexCount === _vertexPool.length ) {
+		if ( _vertexCount === _vertexPoolLength ) {
 
-			vertex = new THREE.RenderableVertex();
+			var vertex = new THREE.RenderableVertex();
 			_vertexPool.push( vertex );
-
-		} else {
-
-			vertex =  _vertexPool[ _vertexCount ];
+			_vertexPoolLength ++;
+			_vertexCount ++;
+			return vertex;
 
 		}
 
-		_vertexCount ++;
-
-		return vertex;
+		return _vertexPool[ _vertexCount ++ ];
 
 	}
 
 	function getNextFace3InPool() {
 
-		var face;
+		if ( _face3Count === _face3PoolLength ) {
 
-		if ( _face3Count === _face3Pool.length ) {
-
-			face = new THREE.RenderableFace3();
+			var face = new THREE.RenderableFace3();
 			_face3Pool.push( face );
-
-		} else {
-
-			face =  _face3Pool[ _face3Count ];
+			_face3PoolLength ++;
+			_face3Count ++;
+			return face;
 
 		}
 
-		_face3Count ++;
-
-		return face;
+		return _face3Pool[ _face3Count ++ ];
 
 
 	}
 
 	function getNextFace4InPool() {
 
-		var face;
-
-		if ( _face4Count === _face4Pool.length ) {
+		if ( _face4Count === _face4PoolLength ) {
 
-			face = new THREE.RenderableFace4();
+			var face = new THREE.RenderableFace4();
 			_face4Pool.push( face );
-
-		} else {
-
-			face =  _face4Pool[ _face4Count ];
+			_face4PoolLength ++;
+			_face4Count ++;
+			return face;
 
 		}
 
-		_face4Count ++;
-
-		return face;
+		return _face4Pool[ _face4Count ++ ];
 
 	}
 
 	function getNextLineInPool() {
 
-		var line;
+		if ( _lineCount === _linePoolLength ) {
 
-		if ( _lineCount === _linePool.length ) {
-
-			line = new THREE.RenderableLine();
+			var line = new THREE.RenderableLine();
 			_linePool.push( line );
-
-		} else {
-
-			line =  _linePool[ _lineCount ];
+			_linePoolLength ++;
+			_lineCount ++
+			return line;
 
 		}
 
-		_lineCount ++;
-
-		return line;
+		return _linePool[ _lineCount ++ ];
 
 	}
 
 	function getNextParticleInPool() {
 
-		var particle;
-
-		if ( _particleCount === _particlePool.length ) {
+		if ( _particleCount === _particlePoolLength ) {
 
-			particle = new THREE.RenderableParticle();
+			var particle = new THREE.RenderableParticle();
 			_particlePool.push( particle );
-
-		} else {
-
-			particle =  _particlePool[ _particleCount ];
+			_particlePoolLength ++;
+			_particleCount ++
+			return particle;
 
 		}
 
-		_particleCount ++;
-
-		return particle;
+		return _particlePool[ _particleCount ++ ];
 
 	}
 

+ 114 - 88
src/core/Ray.js

@@ -2,105 +2,82 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-THREE.Ray = function ( origin, direction, near, far ) {
+( function ( THREE ) {
 
-	this.origin = origin || new THREE.Vector3();
-	this.direction = direction || new THREE.Vector3();
-	this.near = near || 0;
-	this.far = far || Infinity;
+	THREE.Ray = function ( origin, direction, near, far ) {
 
-	//
+		this.origin = origin || new THREE.Vector3();
+		this.direction = direction || new THREE.Vector3();
+		this.near = near || 0;
+		this.far = far || Infinity;
 
-	var a = new THREE.Vector3();
-	var b = new THREE.Vector3();
-	var c = new THREE.Vector3();
-	var d = new THREE.Vector3();
+	};
 
 	var originCopy = new THREE.Vector3();
-	var directionCopy = new THREE.Vector3();
+
+	var localOriginCopy = new THREE.Vector3();
+	var localDirectionCopy = new THREE.Vector3();
 
 	var vector = new THREE.Vector3();
 	var normal = new THREE.Vector3();
 	var intersectPoint = new THREE.Vector3();
 
+	var inverseMatrix = new THREE.Matrix4();
+
 	var descSort = function ( a, b ) {
 
-			return a.distance - b.distance;
+		return a.distance - b.distance;
 
 	};
 
-	//
-
 	var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
-	var dot, intersect, distance;
 
 	var distanceFromIntersection = function ( origin, direction, position ) {
 
 		v0.sub( position, origin );
-		dot = v0.dot( direction );
 
-		intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
-		distance = position.distanceTo( intersect );
+		var dot = v0.dot( direction );
+
+		var intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
+		var distance = position.distanceTo( intersect );
 
 		return distance;
 
-	}
+	};
 
 	// http://www.blackpawn.com/texts/pointinpoly/default.html
 
-	var dot00, dot01, dot02, dot11, dot12, invDenom, u, v;
-
 	var pointInFace3 = function ( p, a, b, c ) {
 
 		v0.sub( c, a );
 		v1.sub( b, a );
 		v2.sub( p, a );
 
-		dot00 = v0.dot( v0 );
-		dot01 = v0.dot( v1 );
-		dot02 = v0.dot( v2 );
-		dot11 = v1.dot( v1 );
-		dot12 = v1.dot( v2 );
+		var dot00 = v0.dot( v0 );
+		var dot01 = v0.dot( v1 );
+		var dot02 = v0.dot( v2 );
+		var dot11 = v1.dot( v1 );
+		var dot12 = v1.dot( v2 );
 
-		invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
-		u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
-		v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
+		var invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
+		var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
+		var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
 
 		return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );
 
-	}
-
-	//
-
-	var precision = 0.0001;
-
-	this.setPrecision = function ( value ) {
-
-		precision = value;
-
 	};
 
-	this.intersectObject = function ( object, recursive ) {
-
-		var intersect, intersects = [];
+	var intersectObject = function ( object, ray, intersects ) {
 
-		if ( recursive === true ) {
-
-			for ( var i = 0, l = object.children.length; i < l; i ++ ) {
-
-				Array.prototype.push.apply( intersects, this.intersectObject( object.children[ i ], recursive ) );
-
-			}
-
-		}
+		var distance,intersect;
 
 		if ( object instanceof THREE.Particle ) {
 
-			distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
+			distance = distanceFromIntersection( ray.origin, ray.direction, object.matrixWorld.getPosition() );
 
 			if ( distance > object.scale.x ) {
 
-				return [];
+				return intersects;
 
 			}
 
@@ -119,12 +96,11 @@ THREE.Ray = function ( origin, direction, near, far ) {
 
 			// Checking boundingSphere
 
-			var scale = THREE.Frustum.__v1.set( object.matrixWorld.getColumnX().length(), object.matrixWorld.getColumnY().length(), object.matrixWorld.getColumnZ().length() );
-			var scaledRadius = object.geometry.boundingSphere.radius * Math.max( scale.x, Math.max( scale.y, scale.z ) );
+			var scaledRadius = object.geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis();
 
 			// Checking distance to ray
 
-			distance = distanceFromIntersection( this.origin, this.direction, object.matrixWorld.getPosition() );
+			distance = distanceFromIntersection( ray.origin, ray.direction, object.matrixWorld.getPosition() );
 
 			if ( distance > scaledRadius) {
 
@@ -135,38 +111,42 @@ THREE.Ray = function ( origin, direction, near, far ) {
 			// Checking faces
 
 			var f, fl, face, dot, scalar,
-			rangeSq = this.range * this.range,
 			geometry = object.geometry,
 			vertices = geometry.vertices,
 			objMatrix, geometryMaterials,
-			isFaceMaterial, material, side;
+			isFaceMaterial, material, side, point;
 
 			geometryMaterials = object.geometry.materials;
 			isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 			side = object.material.side;
 
+			var a, b, c, d;
+			var precision = ray.precision;
+
 			object.matrixRotationWorld.extractRotation( object.matrixWorld );
 
+			originCopy.copy( ray.origin );
+
+			objMatrix = object.matrixWorld;
+			inverseMatrix.getInverse( objMatrix );
+
+			localOriginCopy.copy( originCopy );
+			inverseMatrix.multiplyVector3( localOriginCopy );
+
+			localDirectionCopy.copy( ray.direction );
+			inverseMatrix.rotateAxis( localDirectionCopy ).normalize();
+
 			for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
 
 				face = geometry.faces[ f ];
 
 				material = isFaceMaterial === true ? geometryMaterials[ face.materialIndex ] : object.material;
 				if ( material === undefined ) continue;
-
 				side = material.side;
 
-				originCopy.copy( this.origin );
-				directionCopy.copy( this.direction );
-
-				objMatrix = object.matrixWorld;
-
-				// determine if ray intersects the plane of the face
-				// note: this works regardless of the direction of the face normal
-
-				vector = objMatrix.multiplyVector3( vector.copy( face.centroid ) ).subSelf( originCopy );
-				normal = object.matrixRotationWorld.multiplyVector3( normal.copy( face.normal ) );
-				dot = directionCopy.dot( normal );
+				vector.sub( face.centroid, localOriginCopy );
+				normal = face.normal;
+				dot = localDirectionCopy.dot( normal );
 
 				// bail if ray and plane are parallel
 
@@ -182,25 +162,25 @@ THREE.Ray = function ( origin, direction, near, far ) {
 
 				if ( side === THREE.DoubleSide || ( side === THREE.FrontSide ? dot < 0 : dot > 0 ) ) {
 
-					intersectPoint.add( originCopy, directionCopy.multiplyScalar( scalar ) );
-
-					distance = originCopy.distanceTo( intersectPoint );
-
-					if ( distance < this.near ) continue;
-					if ( distance > this.far ) continue;
+					intersectPoint.add( localOriginCopy, localDirectionCopy.multiplyScalar( scalar ) );
 
 					if ( face instanceof THREE.Face3 ) {
 
-						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
-						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
-						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );
+						a = vertices[ face.a ];
+						b = vertices[ face.b ];
+						c = vertices[ face.c ];
 
 						if ( pointInFace3( intersectPoint, a, b, c ) ) {
 
+							point = object.matrixWorld.multiplyVector3( intersectPoint.clone() );
+							distance = originCopy.distanceTo( point );
+
+							if ( distance < ray.near || distance > ray.far ) continue;
+
 							intersect = {
 
 								distance: distance,
-								point: intersectPoint.clone(),
+								point: point,
 								face: face,
 								faceIndex: f,
 								object: object
@@ -213,17 +193,22 @@ THREE.Ray = function ( origin, direction, near, far ) {
 
 					} else if ( face instanceof THREE.Face4 ) {
 
-						a = objMatrix.multiplyVector3( a.copy( vertices[ face.a ] ) );
-						b = objMatrix.multiplyVector3( b.copy( vertices[ face.b ] ) );
-						c = objMatrix.multiplyVector3( c.copy( vertices[ face.c ] ) );
-						d = objMatrix.multiplyVector3( d.copy( vertices[ face.d ] ) );
+						a = vertices[ face.a ];
+						b = vertices[ face.b ];
+						c = vertices[ face.c ];
+						d = vertices[ face.d ];
 
 						if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
 
+							point = object.matrixWorld.multiplyVector3( intersectPoint.clone() );
+							distance = originCopy.distanceTo( point );
+
+							if ( distance < ray.near || distance > ray.far ) continue;
+
 							intersect = {
 
 								distance: distance,
-								point: intersectPoint.clone(),
+								point: point,
 								face: face,
 								faceIndex: f,
 								object: object
@@ -242,20 +227,61 @@ THREE.Ray = function ( origin, direction, near, far ) {
 
 		}
 
+	};
+
+	var intersectDescendants = function ( object, ray, intersects ) {
+
+		var descendants = object.getDescendants();
+
+		for ( var i = 0, l = descendants.length; i < l; i ++ ) {
+
+			intersectObject( descendants[ i ], this, intersects );
+
+		}
+	};
+
+	//
+
+	THREE.Ray.prototype.precision = 0.0001;
+    
+    THREE.Ray.prototype.set = function ( origin, direction ) {
+        
+        this.origin = origin;
+        this.direction = direction;
+        
+    };
+
+	THREE.Ray.prototype.intersectObject = function ( object, recursive ) {
+
+		var intersects = [];
+
+		if ( recursive === true ) {
+
+			intersectDescendants( object, this, intersects );
+
+		}
+
+		intersectObject(object,this,intersects);
+
 		intersects.sort( descSort );
 
 		return intersects;
 
 	};
 
-	this.intersectObjects = function ( objects, recursive ) {
+	THREE.Ray.prototype.intersectObjects = function ( objects, recursive ) {
 
 		var intersects = [];
 
 		for ( var i = 0, l = objects.length; i < l; i ++ ) {
 
-			Array.prototype.push.apply( intersects, this.intersectObject( objects[ i ], recursive ) );
+			intersectObject( objects[ i ], this, intersects );
 
+			if ( recursive === true ) {
+
+				intersectDescendants( objects[ i ], this, intersects );
+
+			}
 		}
 
 		intersects.sort( descSort );
@@ -264,4 +290,4 @@ THREE.Ray = function ( origin, direction, near, far ) {
 
 	};
 
-};
+}( THREE ) );

+ 54 - 54
src/core/Vector3.js

@@ -274,7 +274,7 @@ THREE.Vector3.prototype = {
 	setEulerFromRotationMatrix: function ( m, order ) {
 
 		// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
-	
+
 		// clamp, to handle numerical problems
 
 		function clamp( x ) {
@@ -291,101 +291,101 @@ THREE.Vector3.prototype = {
 		if ( order === undefined || order === 'XYZ' ) {
 
 			this.y = Math.asin( clamp( m13 ) );
-		
+
 			if ( Math.abs( m13 ) < 0.99999 ) {
-		
+
 				this.x = Math.atan2( - m23, m33 );
 				this.z = Math.atan2( - m12, m11 );
-		
+
 			} else {
-			
+
 				this.x = Math.atan2( m21, m22 );
 				this.z = 0;
-		
+
 			}
 
 		} else if ( order === 'YXZ' ) {
-				
+
 			this.x = Math.asin( - clamp( m23 ) );
-		
+
 			if ( Math.abs( m23 ) < 0.99999 ) {
-			
+
 				this.y = Math.atan2( m13, m33 );
 				this.z = Math.atan2( m21, m22 );
-				
+
 			} else {
-			
+
 				this.y = Math.atan2( - m31, m11 );
 				this.z = 0;
-				
+
 			}
-				
+
 		} else if ( order === 'ZXY' ) {
-	
+
 			this.x = Math.asin( clamp( m32 ) );
-		
+
 			if ( Math.abs( m32 ) < 0.99999 ) {
-			
+
 				this.y = Math.atan2( - m31, m33 );
 				this.z = Math.atan2( - m12, m22 );
-				
+
 			} else {
-				
+
 				this.y = 0;
 				this.z = Math.atan2( m13, m11 );
-				
+
 			}
 
 		} else if ( order === 'ZYX' ) {
-	
+
 			this.y = Math.asin( - clamp( m31 ) );
-			
+
 			if ( Math.abs( m31 ) < 0.99999 ) {
-			
+
 				this.x = Math.atan2( m32, m33 );
 				this.z = Math.atan2( m21, m11 );
-				
+
 			} else {
-			
+
 				this.x = 0;
 				this.z = Math.atan2( - m12, m22 );
-				
+
 			}
-				
+
 		} else if ( order === 'YZX' ) {
-			
+
 			this.z = Math.asin( clamp( m21 ) );
-		
+
 			if ( Math.abs( m21 ) < 0.99999 ) {
-		
+
 				this.x = Math.atan2( - m23, m22 );
 				this.y = Math.atan2( - m31, m11 );
-		
+
 			} else {
-			
+
 				this.x = 0;
 				this.y = Math.atan2( m31, m33 );
-		
+
 			}
-				
+
 		} else if ( order === 'XZY' ) {
-			
+
 			this.z = Math.asin( - clamp( m12 ) );
-		
+
 			if ( Math.abs( m12 ) < 0.99999 ) {
-		
+
 				this.x = Math.atan2( m32, m22 );
 				this.y = Math.atan2( m13, m11 );
-		
+
 			} else {
-			
+
 				this.x = Math.atan2( - m13, m33 );
 				this.y = 0;
-		
+
 			}
-				
+
 		}
-		
+
 		return this;
 
 	},
@@ -403,7 +403,7 @@ THREE.Vector3.prototype = {
 		}
 
 		// http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
-	
+
 		var sqx = q.x * q.x;
 		var sqy = q.y * q.y;
 		var sqz = q.z * q.z;
@@ -414,39 +414,39 @@ THREE.Vector3.prototype = {
 			this.x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( sqw - sqx - sqy + sqz ) );
 			this.y = Math.asin(  clamp( 2 * ( q.x * q.z + q.y * q.w ) ) );
 			this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );
-	
+
 		} else if ( order ===  'YXZ' ) {
-	
+
 			this.x = Math.asin(  clamp( 2 * ( q.x * q.w - q.y * q.z ) ) );
 			this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw - sqx - sqy + sqz ) );
 			this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw - sqx + sqy - sqz ) );
-	
+
 		} else if ( order === 'ZXY' ) {
-			
+
 			this.x = Math.asin(  clamp( 2 * ( q.x * q.w + q.y * q.z ) ) );
 			this.y = Math.atan2( 2 * ( q.y * q.w - q.z * q.x ), ( sqw - sqx - sqy + sqz ) );
 			this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw - sqx + sqy - sqz ) );
-			
+
 		} else if ( order === 'ZYX' ) {
-			
+
 			this.x = Math.atan2( 2 * ( q.x * q.w + q.z * q.y ), ( sqw - sqx - sqy + sqz ) );
 			this.y = Math.asin(  clamp( 2 * ( q.y * q.w - q.x * q.z ) ) );
 			this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) );
-	
+
 		} else if ( order === 'YZX' ) {
-			
+
 			this.x = Math.atan2( 2 * ( q.x * q.w - q.z * q.y ), ( sqw - sqx + sqy - sqz ) );
 			this.y = Math.atan2( 2 * ( q.y * q.w - q.x * q.z ), ( sqw + sqx - sqy - sqz ) );
 			this.z = Math.asin(  clamp( 2 * ( q.x * q.y + q.z * q.w ) ) );
-			
+
 		} else if ( order === 'XZY' ) {
-			
+
 			this.x = Math.atan2( 2 * ( q.x * q.w + q.y * q.z ), ( sqw - sqx + sqy - sqz ) );
 			this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw + sqx - sqy - sqz ) );
 			this.z = Math.asin(  clamp( 2 * ( q.z * q.w - q.x * q.y ) ) );
-	
+
 		}
-		
+
 		return this;
 
 	},

+ 57 - 51
src/core/Vector4.js

@@ -143,6 +143,12 @@ THREE.Vector4.prototype = {
 
 	},
 
+	lengthManhattan: function () {
+
+		return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
+
+	},
+
 	normalize: function () {
 
 		return this.divideScalar( this.length() );
@@ -175,27 +181,27 @@ THREE.Vector4.prototype = {
 	setAxisAngleFromQuaternion: function ( q ) {
 
 		// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
-		
+
 		// q is assumed to be normalized
-		
+
 		this.w = 2 * Math.acos( q.w );
-		
+
 		var s = Math.sqrt( 1 - q.w * q.w );
-		
+
 		if ( s < 0.0001 ) {
-		
+
 			 this.x = 1;
 			 this.y = 0;
 			 this.z = 0;
-		 
+
 		} else {
-		
+
 			 this.x = q.x / s;
 			 this.y = q.y / s;
 			 this.z = q.z / s;
-		 
+
 		}
-	
+
 		return this;
 
 	},
@@ -203,15 +209,15 @@ THREE.Vector4.prototype = {
 	setAxisAngleFromRotationMatrix: function ( m ) {
 
 		// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
-		
+
 		// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
-		
+
 		var angle, x, y, z,		// variables for result
 			epsilon = 0.01,		// margin to allow for rounding errors
 			epsilon2 = 0.1,		// margin to distinguish between 0 and 180 degrees
-		
+
 			te = m.elements,
-			
+
 			m11 = te[0], m12 = te[4], m13 = te[8],
 			m21 = te[1], m22 = te[5], m23 = te[9],
 			m31 = te[2], m32 = te[6], m33 = te[10];
@@ -219,107 +225,107 @@ THREE.Vector4.prototype = {
 		if ( ( Math.abs( m12 - m21 ) < epsilon )
 		  && ( Math.abs( m13 - m31 ) < epsilon )
 		  && ( Math.abs( m23 - m32 ) < epsilon ) ) {
-			
+
 			// singularity found
 			// first check for identity matrix which must have +1 for all terms
 			// in leading diagonal and zero in other terms
-			
+
 			if ( ( Math.abs( m12 + m21 ) < epsilon2 )
 			  && ( Math.abs( m13 + m31 ) < epsilon2 )
 			  && ( Math.abs( m23 + m32 ) < epsilon2 )
 			  && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
-				
+
 				// this singularity is identity matrix so angle = 0
-				
+
 				this.set( 1, 0, 0, 0 );
-				
+
 				return this; // zero angle, arbitrary axis
-				
+
 			}
-			
+
 			// otherwise this singularity is angle = 180
-			
+
 			angle = Math.PI;
-			
+
 			var xx = ( m11 + 1 ) / 2;
 			var yy = ( m22 + 1 ) / 2;
 			var zz = ( m33 + 1 ) / 2;
 			var xy = ( m12 + m21 ) / 4;
 			var xz = ( m13 + m31 ) / 4;
 			var yz = ( m23 + m32 ) / 4;
-			
+
 			if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term
-			
+
 				if ( xx < epsilon ) {
-				
+
 					x = 0;
 					y = 0.707106781;
 					z = 0.707106781;
-					
+
 				} else {
-				
+
 					x = Math.sqrt( xx );
 					y = xy / x;
 					z = xz / x;
-					
+
 				}
-				
+
 			} else if ( yy > zz ) { // m22 is the largest diagonal term
-			
+
 				if ( yy < epsilon ) {
-				
+
 					x = 0.707106781;
 					y = 0;
 					z = 0.707106781;
-					
+
 				} else {
-				
+
 					y = Math.sqrt( yy );
 					x = xy / y;
 					z = yz / y;
-					
-				}	
-				
+
+				}
+
 			} else { // m33 is the largest diagonal term so base result on this
-			
+
 				if ( zz < epsilon ) {
-				
+
 					x = 0.707106781;
 					y = 0.707106781;
 					z = 0;
-					
+
 				} else {
-				
+
 					z = Math.sqrt( zz );
 					x = xz / z;
 					y = yz / z;
-					
+
 				}
-				
+
 			}
-			
+
 			this.set( x, y, z, angle );
-			
+
 			return this; // return 180 deg rotation
-	
+
 		}
-		
+
 		// as we have reached here there are no singularities so we can handle normally
-		
+
 		var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 )
 						 + ( m13 - m31 ) * ( m13 - m31 )
 						 + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
-			
+
 		if ( Math.abs( s ) < 0.001 ) s = 1; 
-		
+
 		// prevent divide by zero, should not happen if matrix is orthogonal and should be
 		// caught by singularity test above, but I've left it in just in case
-		
+
 		this.x = ( m32 - m23 ) / s;
 		this.y = ( m13 - m31 ) / s;
 		this.z = ( m21 - m12 ) / s;
 		this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
-	
+
 		return this;
 
 	}

+ 95 - 15
src/extras/ShaderUtils.js

@@ -29,7 +29,7 @@ THREE.ShaderUtils = {
 				"mFresnelBias": { type: "f", value: 0.1 },
 				"mFresnelPower": { type: "f", value: 2.0 },
 				"mFresnelScale": { type: "f", value: 1.0 },
-				"tCube": { type: "t", value: 1, texture: null }
+				"tCube": { type: "t", value: null }
 
 			},
 
@@ -114,12 +114,12 @@ THREE.ShaderUtils = {
 				"enableReflection": { type: "i", value: 0 },
 				"enableDisplacement": { type: "i", value: 0 },
 
-				"tDiffuse"	   : { type: "t", value: 0, texture: null },
-				"tCube"		   : { type: "t", value: 1, texture: null },
-				"tNormal"	   : { type: "t", value: 2, texture: null },
-				"tSpecular"	   : { type: "t", value: 3, texture: null },
-				"tAO"		   : { type: "t", value: 4, texture: null },
-				"tDisplacement": { type: "t", value: 5, texture: null },
+				"tDisplacement": { type: "t", value: null }, // must go first as this is vertex texture
+				"tDiffuse"	   : { type: "t", value: null },
+				"tCube"		   : { type: "t", value: null },
+				"tNormal"	   : { type: "t", value: null },
+				"tSpecular"	   : { type: "t", value: null },
+				"tAO"		   : { type: "t", value: null },
 
 				"uNormalScale": { type: "f", value: 1.0 },
 
@@ -185,6 +185,14 @@ THREE.ShaderUtils = {
 
 				"#endif",
 
+				"#if MAX_HEMI_LIGHTS > 0",
+
+					"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
+					"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
+					"uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
+
+				"#endif",
+
 				"#if MAX_POINT_LIGHTS > 0",
 
 					"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
@@ -267,6 +275,12 @@ THREE.ShaderUtils = {
 					"mat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );",
 					"vec3 finalNormal = tsb * normalTex;",
 
+					"#ifdef FLIP_SIDED",
+
+						"finalNormal = -finalNormal;",
+
+					"#endif",
+
 					"vec3 normal = normalize( finalNormal );",
 					"vec3 viewPosition = normalize( vViewPosition );",
 
@@ -452,6 +466,61 @@ THREE.ShaderUtils = {
 
 					"#endif",
 
+					// hemisphere lights
+
+					"#if MAX_HEMI_LIGHTS > 0",
+
+						"vec3 hemiDiffuse  = vec3( 0.0 );",
+						"vec3 hemiSpecular = vec3( 0.0 );" ,
+
+						"for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
+
+							"vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
+							"vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
+
+							// diffuse
+
+							"float dotProduct = dot( normal, lVector );",
+							"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
+
+							"hemiDiffuse += uDiffuseColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+							// specular (sky light)
+
+							"float hemiSpecularWeight = 0.0;",
+
+							"vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
+							"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
+							"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );",
+
+							// specular (ground light)
+
+							"vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
+
+							"vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
+							"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
+							"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );",
+
+							"#ifdef PHYSICALLY_BASED_SHADING",
+
+								// 2.0 => 2.0001 is hack to work around ANGLE bug
+
+								"float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
+
+								"vec3 schlickSky = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
+								"vec3 schlickGround = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
+								"hemiSpecular += ( schlickSky + schlickGround ) * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight * specularNormalization;",
+
+							"#else",
+
+								"hemiSpecular += uSpecularColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
+
+							"#endif",
+
+						"}",
+
+					"#endif",
+
 					// all lights contribution summation
 
 					"vec3 totalDiffuse = vec3( 0.0 );",
@@ -464,6 +533,13 @@ THREE.ShaderUtils = {
 
 					"#endif",
 
+					"#if MAX_HEMI_LIGHTS > 0",
+
+						"totalDiffuse += hemiDiffuse;",
+						"totalSpecular += hemiSpecular;",
+
+					"#endif",
+
 					"#if MAX_POINT_LIGHTS > 0",
 
 						"totalDiffuse += pointDiffuse;",
@@ -591,8 +667,10 @@ THREE.ShaderUtils = {
 
 							"#ifdef USE_SKINNING",
 
-								"vec4 skinned  = boneMatX * skinVertexA * skinWeight.x;",
-								"skinned 	  += boneMatY * skinVertexB * skinWeight.y;",
+								"vec4 skinVertex = vec4( position, 1.0 );",
+
+								"vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
+								"skinned 	  += boneMatY * skinVertex * skinWeight.y;",
 
 								"displacedPosition  = skinned.xyz;",
 
@@ -608,8 +686,10 @@ THREE.ShaderUtils = {
 
 						"#ifdef USE_SKINNING",
 
-							"vec4 skinned  = boneMatX * skinVertexA * skinWeight.x;",
-							"skinned 	  += boneMatY * skinVertexB * skinWeight.y;",
+							"vec4 skinVertex = vec4( position, 1.0 );",
+
+							"vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
+							"skinned 	  += boneMatY * skinVertex * skinWeight.y;",
 
 							"displacedPosition  = skinned.xyz;",
 
@@ -624,13 +704,13 @@ THREE.ShaderUtils = {
 					//
 
 					"vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
-					"vec4 wPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
+					"vec4 mPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
 
 					"gl_Position = projectionMatrix * mvPosition;",
 
 					//
 
-					"vWorldPosition = wPosition.xyz;",
+					"vWorldPosition = mPosition.xyz;",
 
 					// shadows
 
@@ -638,7 +718,7 @@ THREE.ShaderUtils = {
 
 						"for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
 
-							"vShadowCoord[ i ] = shadowMatrix[ i ] * wPosition;",
+							"vShadowCoord[ i ] = shadowMatrix[ i ] * mPosition;",
 
 						"}",
 
@@ -656,7 +736,7 @@ THREE.ShaderUtils = {
 
 		'cube': {
 
-			uniforms: { "tCube": { type: "t", value: 1, texture: null },
+			uniforms: { "tCube": { type: "t", value: null },
 						"tFlip": { type: "f", value: -1 } },
 
 			vertexShader: [

+ 1 - 1
src/extras/cameras/CombinedCamera.js

@@ -152,7 +152,7 @@ THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {
 */
 THREE.CombinedCamera.prototype.setLens = function ( focalLength, frameHeight ) {
 
-	frameHeight = frameHeight !== undefined ? frameHeight : 24;
+	if ( frameHeight === undefined ) frameHeight = 24;
 
 	var fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
 

+ 25 - 55
src/extras/geometries/ExtrudeGeometry.js

@@ -5,30 +5,28 @@
  *
  * parameters = {
  *
- *  size: 			<float>, 	// size of the text
- *  height: 		<float>, 	// thickness to extrude text
- *  curveSegments: 	<int>,		// number of points on the curves
- *  steps: 			<int>,		// number of points for z-side extrusions / used for subdividing segements of extrude spline too
- 	amount: <int>,	// Amount
+ *  size: <float>, // size of the text
+ *  height: <float>, // thickness to extrude text
+ *  curveSegments: <int>, // number of points on the curves
+ *  steps: <int>, // number of points for z-side extrusions / used for subdividing segements of extrude spline too
+ *  amount: <int>, // Amount
  *
- *  bevelEnabled:	<bool>,			// turn on bevel
- *  bevelThickness: <float>, 		// how deep into text bevel goes
- *  bevelSize:		<float>, 		// how far from text outline is bevel
- *  bevelSegments:	<int>, 			// number of bevel layers
+ *  bevelEnabled: <bool>, // turn on bevel
+ *  bevelThickness: <float>, // how deep into text bevel goes
+ *  bevelSize: <float>, // how far from text outline is bevel
+ *  bevelSegments: <int>, // number of bevel layers
  *
- *  extrudePath:	<THREE.CurvePath>	// 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)
- *  frames:			<THREE.TubeGeometry.FrenetFrames> // containing arrays of tangents, normals, binormals
- *  bendPath:		<THREE.CurvePath> 	// 2d path for bend the shape around x/y plane
+ *  extrudePath: <THREE.CurvePath> // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)
+ *  frames: <THREE.TubeGeometry.FrenetFrames> // containing arrays of tangents, normals, binormals
  *
- *  material:		 <int>	// material index for front and back faces
- *  extrudeMaterial: <int>	// material index for extrusion and beveled faces
- *  uvGenerator:	 <Object> // object that provides UV generator functions
+ *  material: <int> // material index for front and back faces
+ *  extrudeMaterial: <int> // material index for extrusion and beveled faces
+ *  uvGenerator: <Object> // object that provides UV generator functions
  *
- *  }
-  **/
+ * }
+ **/
 
-
-THREE.ExtrudeGeometry = function( shapes, options ) {
+THREE.ExtrudeGeometry = function ( shapes, options ) {
 
 	if ( typeof( shapes ) === "undefined" ) {
 		shapes = [];
@@ -58,7 +56,7 @@ THREE.ExtrudeGeometry = function( shapes, options ) {
 
 THREE.ExtrudeGeometry.prototype = Object.create( THREE.Geometry.prototype );
 
-THREE.ExtrudeGeometry.prototype.addShapeList = function(shapes, options) {
+THREE.ExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {
 	var sl = shapes.length;
 
 	for ( var s = 0; s < sl; s ++ ) {
@@ -67,7 +65,7 @@ THREE.ExtrudeGeometry.prototype.addShapeList = function(shapes, options) {
 	}
 };
 
-THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
+THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 
 	var amount = options.amount !== undefined ? options.amount : 100;
 
@@ -81,8 +79,6 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 
 	var steps = options.steps !== undefined ? options.steps : 1;
 
-	var bendPath = options.bendPath;
-
 	var extrudePath = options.extrudePath;
 	var extrudePts, extrudeByPath = false;
 
@@ -110,9 +106,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 		// Reuse TNB from TubeGeomtry for now.
 		// TODO1 - have a .isClosed in spline?
 
-		splineTube = options.frames !== undefined ?
-			options.frames :
-			new THREE.TubeGeometry.FrenetFrames(extrudePath, steps, false);
+		splineTube = options.frames !== undefined ? options.frames : new THREE.TubeGeometry.FrenetFrames(extrudePath, steps, false);
 
 		// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
 
@@ -140,15 +134,9 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 
 	var shapesOffset = this.vertices.length;
 
-	if ( bendPath ) {
-
-		shape.addWrapPath( bendPath );
-
-	}
-
 	var shapePoints = shape.extractPoints();
 
-    var vertices = shapePoints.shape;
+	var vertices = shapePoints.shape;
 	var holes = shapePoints.holes;
 
 	var reverse = !THREE.Shape.Utils.isClockWise( vertices ) ;
@@ -177,18 +165,8 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 
 
 	var faces = THREE.Shape.Utils.triangulateShape ( vertices, holes );
-	//var faces = THREE.Shape.Utils.triangulate2( vertices, holes );
-
-	// Would it be better to move points after triangulation?
-	// shapePoints = shape.extractAllPointsWithBend( curveSegments, bendPath );
-	// 	vertices = shapePoints.shape;
-	// 	holes = shapePoints.holes;
 
-	//console.log(faces);
-
-	////
-	///   Handle Vertices
-	////
+	/* Vertices */
 
 	var contour = vertices; // vertices has all points but contour has only points of circumference
 
@@ -215,9 +193,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 		cont, clen = contour.length;
 
 
-	//------
 	// Find directions for point movement
-	//
 
 	var RAD_TO_DEGREES = 180 / Math.PI;
 
@@ -530,11 +506,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 
 	}
 
-
-
-	////
-	///   Handle Faces
-	////
+	/* Faces */
 
 	// Top and bottom faces
 
@@ -666,8 +638,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 		// normal, color, material
 		scope.faces.push( new THREE.Face3( a, b, c, null, null, material ) );
 
-		var uvs = isBottom ? uvgen.generateBottomUV( scope, shape, options, a, b, c )
-		                   : uvgen.generateTopUV( scope, shape, options, a, b, c );
+		var uvs = isBottom ? uvgen.generateBottomUV( scope, shape, options, a, b, c ) : uvgen.generateTopUV( scope, shape, options, a, b, c );
 
  		scope.faceVertexUvs[ 0 ].push( uvs );
 
@@ -690,8 +661,6 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
 
 };
 
-
-
 THREE.ExtrudeGeometry.WorldUVGenerator = {
 
 	generateTopUV: function( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ) {
@@ -721,6 +690,7 @@ THREE.ExtrudeGeometry.WorldUVGenerator = {
 	generateSideWallUV: function( geometry, extrudedShape, wallContour, extrudeOptions,
 	                              indexA, indexB, indexC, indexD, stepIndex, stepsLength,
 	                              contourIndex1, contourIndex2 ) {
+
 		var ax = geometry.vertices[ indexA ].x,
 			ay = geometry.vertices[ indexA ].y,
 			az = geometry.vertices[ indexA ].z,

+ 2 - 18
src/extras/geometries/TextGeometry.js

@@ -18,15 +18,12 @@
  *  bevelEnabled:	<bool>,			// turn on bevel
  *  bevelThickness: <float>, 		// how deep into text bevel goes
  *  bevelSize:		<float>, 		// how far from text outline is bevel
- *
- *  bend:			<bool>			// bend according to hardcoded curve (generates bendPath)
- *  bendPath:       <curve>         // wraps text according to bend Path
  *  }
  *
  */
 
 /*	Usage Examples
-	
+
 	// TextGeometry wrapper
 
 	var text3d = new TextGeometry( text, options );
@@ -35,7 +32,7 @@
 
 	var textShapes = THREE.FontUtils.generateShapes( text, options );
 	var text3d = new ExtrudeGeometry( textShapes, options );
-	
+
 */
 
 
@@ -53,19 +50,6 @@ THREE.TextGeometry = function ( text, parameters ) {
 	if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
 	if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
 
-	if ( parameters.bend ) {
-
-		var b = textShapes[ textShapes.length - 1 ].getBoundingBox();
-		var max = b.maxX;
-
-		parameters.bendPath = new THREE.QuadraticBezierCurve(
-			new THREE.Vector2( 0, 0 ),
-			new THREE.Vector2( max / 2, 120 ),
-			new THREE.Vector2( max, 0 )
-		);
-
-	}
-
 	THREE.ExtrudeGeometry.call( this, textShapes, parameters );
 
 };

+ 25 - 27
src/extras/helpers/CameraHelper.js

@@ -9,22 +9,26 @@
 
 THREE.CameraHelper = function ( camera ) {
 
-	THREE.Object3D.call( this );
+	THREE.Line.call( this );
 
-	var _this = this;
+	var scope = this;
 
-	this.lineGeometry = new THREE.Geometry();
-	this.lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } );
+	this.geometry = new THREE.Geometry();
+	this.material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } );
+	this.type = THREE.LinePieces;
+
+	this.matrixWorld = camera.matrixWorld;
+	this.matrixAutoUpdate = false;
 
 	this.pointMap = {};
 
 	// colors
 
-	var hexFrustum = 0xffaa00,
-	hexCone	   	   = 0xff0000,
-	hexUp	   	   = 0x00aaff,
-	hexTarget  	   = 0xffffff,
-	hexCross   	   = 0x333333;
+	var hexFrustum = 0xffaa00;
+	var hexCone = 0xff0000;
+	var hexUp = 0x00aaff;
+	var hexTarget = 0xffffff;
+	var hexCross = 0x333333;
 
 	// near
 
@@ -84,36 +88,31 @@ THREE.CameraHelper = function ( camera ) {
 
 	function addPoint( id, hex ) {
 
-		_this.lineGeometry.vertices.push( new THREE.Vector3() );
-		_this.lineGeometry.colors.push( new THREE.Color( hex ) );
+		scope.geometry.vertices.push( new THREE.Vector3() );
+		scope.geometry.colors.push( new THREE.Color( hex ) );
+
+		if ( scope.pointMap[ id ] === undefined ) scope.pointMap[ id ] = [];
 
-		if ( _this.pointMap[ id ] === undefined ) _this.pointMap[ id ] = [];
-		_this.pointMap[ id ].push( _this.lineGeometry.vertices.length - 1 );
+		scope.pointMap[ id ].push( scope.geometry.vertices.length - 1 );
 
 	}
 
 	this.update( camera );
 
-	this.lines = new THREE.Line( this.lineGeometry, this.lineMaterial, THREE.LinePieces );
-	this.add( this.lines );
-
 };
 
-THREE.CameraHelper.prototype = Object.create( THREE.Object3D.prototype );
+THREE.CameraHelper.prototype = Object.create( THREE.Line.prototype );
 
 THREE.CameraHelper.prototype.update = function () {
 
-	var camera = this.camera;
-
-	var w = 1;
-	var h = 1;
+	var scope = this;
 
-	var _this = this;
+	var w = 1, h = 1;
 
 	// we need just camera projection matrix
 	// world matrix must be identity
 
-	THREE.CameraHelper.__c.projectionMatrix.copy( camera.projectionMatrix );
+	THREE.CameraHelper.__c.projectionMatrix.copy( this.camera.projectionMatrix );
 
 	// center / target
 
@@ -157,14 +156,13 @@ THREE.CameraHelper.prototype.update = function () {
 		THREE.CameraHelper.__v.set( x, y, z );
 		THREE.CameraHelper.__projector.unprojectVector( THREE.CameraHelper.__v, THREE.CameraHelper.__c );
 
-		var points = _this.pointMap[ point ];
+		var points = scope.pointMap[ point ];
 
 		if ( points !== undefined ) {
 
 			for ( var i = 0, il = points.length; i < il; i ++ ) {
 
-				var j = points[ i ];
-				_this.lineGeometry.vertices[ j ].copy( THREE.CameraHelper.__v );
+				scope.geometry.vertices[ points[ i ] ].copy( THREE.CameraHelper.__v );
 
 			}
 
@@ -172,7 +170,7 @@ THREE.CameraHelper.prototype.update = function () {
 
 	}
 
-	this.lineGeometry.verticesNeedUpdate = true;
+	this.geometry.verticesNeedUpdate = true;
 
 };
 

+ 9 - 6
src/extras/renderers/plugins/ShadowMapPlugin.js

@@ -6,7 +6,7 @@ THREE.ShadowMapPlugin = function ( ) {
 
 	var _gl,
 	_renderer,
-	_depthMaterial, _depthMaterialMorph, _depthMaterialSkin,
+	_depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
 
 	_frustum = new THREE.Frustum(),
 	_projScreenMatrix = new THREE.Matrix4(),
@@ -25,10 +25,12 @@ THREE.ShadowMapPlugin = function ( ) {
 		_depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
 		_depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
 		_depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } );
+		_depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } );
 
 		_depthMaterial._shadowPass = true;
 		_depthMaterialMorph._shadowPass = true;
 		_depthMaterialSkin._shadowPass = true;
+		_depthMaterialMorphSkin._shadowPass = true;
 
 	};
 
@@ -60,6 +62,7 @@ THREE.ShadowMapPlugin = function ( ) {
 		_gl.disable( _gl.BLEND );
 
 		_gl.enable( _gl.CULL_FACE );
+		_gl.frontFace( _gl.CCW );
 
 		if ( _renderer.shadowMapCullFrontFaces ) {
 
@@ -191,7 +194,7 @@ THREE.ShadowMapPlugin = function ( ) {
 
 			shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
 
-			if ( light.cameraHelper ) light.cameraHelper.lines.visible = light.shadowCameraVisible;
+			if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
 			if ( light.shadowCameraVisible ) light.cameraHelper.update();
 
 			// compute shadow matrix
@@ -263,13 +266,13 @@ THREE.ShadowMapPlugin = function ( ) {
 
 						material = object.customDepthMaterial;
 
-					} else if ( object.geometry.morphTargets.length ) {
+					} else if ( object instanceof THREE.SkinnedMesh ) {
 
-						material = _depthMaterialMorph;
+						material = object.geometry.morphTargets.length ? _depthMaterialMorphSkin : _depthMaterialSkin;
 
-					} else if ( object instanceof THREE.SkinnedMesh ) {
+					} else if ( object.geometry.morphTargets.length ) {
 
-						material = _depthMaterialSkin;
+						material = _depthMaterialMorph;
 
 					} else {
 

+ 17 - 0
src/lights/HemisphereLight.js

@@ -0,0 +1,17 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ */
+
+THREE.HemisphereLight = function ( skyColorHex, groundColorHex, intensity ) {
+
+	THREE.Light.call( this, skyColorHex );
+
+	this.groundColor = new THREE.Color( groundColorHex );
+
+	this.position = new THREE.Vector3( 0, 100, 0 );
+
+	this.intensity = ( intensity !== undefined ) ? intensity : 1;
+
+};
+
+THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype );

+ 5 - 4
src/loaders/GeometryLoader.js

@@ -54,6 +54,7 @@ THREE.GeometryLoader.prototype = {
 		}, false );
 
 		xhr.open( 'GET', url, true );
+		xhr.setRequestHeader( "Content-Type", "application/json" );
 		xhr.send( null );
 
 		//
@@ -331,7 +332,7 @@ THREE.GeometryLoader.prototype = {
 					var shader = THREE.ShaderUtils.lib[ "normal" ];
 					var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-					uniforms[ "tNormal" ].texture = mpars.normalMap;
+					uniforms[ "tNormal" ].value = mpars.normalMap;
 
 					if ( m.mapNormalFactor ) {
 
@@ -341,21 +342,21 @@ THREE.GeometryLoader.prototype = {
 
 					if ( mpars.map ) {
 
-						uniforms[ "tDiffuse" ].texture = mpars.map;
+						uniforms[ "tDiffuse" ].value = mpars.map;
 						uniforms[ "enableDiffuse" ].value = true;
 
 					}
 
 					if ( mpars.specularMap ) {
 
-						uniforms[ "tSpecular" ].texture = mpars.specularMap;
+						uniforms[ "tSpecular" ].value = mpars.specularMap;
 						uniforms[ "enableSpecular" ].value = true;
 
 					}
 
 					if ( mpars.lightMap ) {
 
-						uniforms[ "tAO" ].texture = mpars.lightMap;
+						uniforms[ "tAO" ].value = mpars.lightMap;
 						uniforms[ "enableAO" ].value = true;
 
 					}

+ 2 - 2
src/loaders/JSONLoader.js

@@ -80,8 +80,8 @@ THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, tex
 	};
 
 	xhr.open( "GET", url, true );
-	if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
-	xhr.setRequestHeader( "Content-Type", "text/plain" );
+	if ( xhr.overrideMimeType ) xhr.overrideMimeType( "application/json; charset=x-user-defined" );
+	xhr.setRequestHeader( "Content-Type", "application/json" );
 	xhr.send( null );
 
 };

+ 4 - 4
src/loaders/Loader.js

@@ -342,7 +342,7 @@ THREE.Loader.prototype = {
 			var shader = THREE.ShaderUtils.lib[ "normal" ];
 			var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
-			uniforms[ "tNormal" ].texture = mpars.normalMap;
+			uniforms[ "tNormal" ].value = mpars.normalMap;
 
 			if ( m.mapNormalFactor ) {
 
@@ -352,21 +352,21 @@ THREE.Loader.prototype = {
 
 			if ( mpars.map ) {
 
-				uniforms[ "tDiffuse" ].texture = mpars.map;
+				uniforms[ "tDiffuse" ].value = mpars.map;
 				uniforms[ "enableDiffuse" ].value = true;
 
 			}
 
 			if ( mpars.specularMap ) {
 
-				uniforms[ "tSpecular" ].texture = mpars.specularMap;
+				uniforms[ "tSpecular" ].value = mpars.specularMap;
 				uniforms[ "enableSpecular" ].value = true;
 
 			}
 
 			if ( mpars.lightMap ) {
 
-				uniforms[ "tAO" ].texture = mpars.lightMap;
+				uniforms[ "tAO" ].value = mpars.lightMap;
 				uniforms[ "enableAO" ].value = true;
 
 			}

+ 9 - 8
src/loaders/SceneLoader.js

@@ -41,8 +41,8 @@ THREE.SceneLoader.prototype.load = function( url, callbackFinished ) {
 	};
 
 	xhr.open( "GET", url, true );
-	if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
-	xhr.setRequestHeader( "Content-Type", "text/plain" );
+	if ( xhr.overrideMimeType ) xhr.overrideMimeType( "application/json; charset=x-user-defined" );
+	xhr.setRequestHeader( "Content-Type", "application/json" );
 	xhr.send( null );
 
 };
@@ -131,14 +131,15 @@ THREE.SceneLoader.prototype.createScene = function ( json, callbackFinished, url
 
 	}
 
-        // handle all the children from the loaded json and attach them to given parent        
+	// handle all the children from the loaded json and attach them to given parent
+
 	function handle_children( parent, children ) {
 
 		var object;
 
 		for ( dd in children ) {
 
-			// check by id if child has already been handled, 
+			// check by id if child has already been handled,
 			// if not, create new object
 
 			if ( result.objects[ dd ] === undefined ) {
@@ -724,7 +725,7 @@ THREE.SceneLoader.prototype.createScene = function ( json, callbackFinished, url
 			var ambient = m.parameters.ambient;
 			var shininess = m.parameters.shininess;
 
-			uniforms[ "tNormal" ].texture = result.textures[ m.parameters.normalMap ];
+			uniforms[ "tNormal" ].value = result.textures[ m.parameters.normalMap ];
 
 			if ( m.parameters.normalMapFactor ) {
 
@@ -734,21 +735,21 @@ THREE.SceneLoader.prototype.createScene = function ( json, callbackFinished, url
 
 			if ( m.parameters.map ) {
 
-				uniforms[ "tDiffuse" ].texture = m.parameters.map;
+				uniforms[ "tDiffuse" ].value = m.parameters.map;
 				uniforms[ "enableDiffuse" ].value = true;
 
 			}
 
 			if ( m.parameters.lightMap ) {
 
-				uniforms[ "tAO" ].texture = m.parameters.lightMap;
+				uniforms[ "tAO" ].value = m.parameters.lightMap;
 				uniforms[ "enableAO" ].value = true;
 
 			}
 
 			if ( m.parameters.specularMap ) {
 
-				uniforms[ "tSpecular" ].texture = result.textures[ m.parameters.specularMap ];
+				uniforms[ "tSpecular" ].value = result.textures[ m.parameters.specularMap ];
 				uniforms[ "enableSpecular" ].value = true;
 
 			}

+ 37 - 45
src/objects/SkinnedMesh.js

@@ -170,85 +170,77 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
 
 	}
 
-	// flatten bone matrices to array
+	// make a snapshot of the bones' rest position
 
-	var b, bl = this.bones.length,
-		ba = this.bones,
-		bm = this.boneMatrices;
+	if ( this.boneInverses == undefined ) {
 
-	for ( b = 0; b < bl; b ++ ) {
+		this.boneInverses = [];
 
-		ba[ b ].skinMatrix.flattenToArrayOffset( bm, b * 16 );
+		for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
 
-	}
+			var inverse = new THREE.Matrix4();
 
-	if ( this.useVertexTexture ) {
+			inverse.getInverse( this.bones[ b ].skinMatrix );
 
-		this.boneTexture.needsUpdate = true;
+			this.boneInverses.push( inverse );
 
-	}
+		}
 
-};
+	}
 
-/*
- * Pose
- */
+	// flatten bone matrices to array
 
-THREE.SkinnedMesh.prototype.pose = function() {
+	for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
 
-	this.updateMatrixWorld( true );
+		// compute the offset between the current and the original transform;
 
-	var bim, bone, boneInverses = [];
+		//TODO: we could get rid of this multiplication step if the skinMatrix
+		// was already representing the offset; however, this requires some
+		// major changes to the animation system
 
-	for ( var b = 0; b < this.bones.length; b ++ ) {
+		THREE.SkinnedMesh.offsetMatrix.multiply( this.bones[ b ].skinMatrix, this.boneInverses[ b ] );
 
-		bone = this.bones[ b ];
+		THREE.SkinnedMesh.offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
 
-		var inverseMatrix = new THREE.Matrix4();
-		inverseMatrix.getInverse( bone.skinMatrix );
+	}
 
-		boneInverses.push( inverseMatrix );
+	if ( this.useVertexTexture ) {
 
-		bone.skinMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
+		this.boneTexture.needsUpdate = true;
 
 	}
 
-	// project vertices to local
-
-	if ( this.geometry.skinVerticesA === undefined ) {
-
-		this.geometry.skinVerticesA = [];
-		this.geometry.skinVerticesB = [];
+};
 
-		var orgVertex, vertex;
+/*
+ * Pose
+ */
 
-		for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
+THREE.SkinnedMesh.prototype.pose = function() {
 
-			orgVertex = this.geometry.vertices[ i ];
+	this.updateMatrixWorld( true );
 
-			var indexA = this.geometry.skinIndices[ i ].x;
-			var indexB = this.geometry.skinIndices[ i ].y;
+	for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
 
-			vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
-			this.geometry.skinVerticesA.push( boneInverses[ indexA ].multiplyVector3( vertex ) );
+		// normalize weights
 
-			vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
-			this.geometry.skinVerticesB.push( boneInverses[ indexB ].multiplyVector3( vertex ) );
+		var sw = this.geometry.skinWeights[ i ];
 
-			// todo: add more influences
+		var scale = 1.0 / sw.lengthManhattan();
 
-			// normalize weights
+		if ( scale !== Infinity ) {
 
-			if ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y !== 1 ) {
+			sw.multiplyScalar( scale );
 
-				var len = ( 1.0 - ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y ) ) * 0.5;
-				this.geometry.skinWeights[ i ].x += len;
-				this.geometry.skinWeights[ i ].y += len;
+		} else {
 
-			}
+			sw.set( 1 ); // this will be normalized by the shader anyway
 
 		}
 
 	}
 
 };
+
+THREE.SkinnedMesh.offsetMatrix = new THREE.Matrix4();
+

+ 30 - 38
src/renderers/CanvasRenderer.js

@@ -202,7 +202,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 		if ( _enableLighting === true ) {
 
-			 calculateLights( _lights );
+			 calculateLights();
 
 		}
 
@@ -323,18 +323,16 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 		//
 
-		function calculateLights( lights ) {
-
-			var l, ll, light, lightColor;
+		function calculateLights() {
 
 			_ambientLight.setRGB( 0, 0, 0 );
 			_directionalLights.setRGB( 0, 0, 0 );
 			_pointLights.setRGB( 0, 0, 0 );
 
-			for ( l = 0, ll = lights.length; l < ll; l ++ ) {
+			for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
 
-				light = lights[ l ];
-				lightColor = light.color;
+				var light = _lights[ l ];
+				var lightColor = light.color;
 
 				if ( light instanceof THREE.AmbientLight ) {
 
@@ -364,20 +362,18 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 		}
 
-		function calculateLight( lights, position, normal, color ) {
-
-			var l, ll, light, lightColor, lightPosition, amount;
+		function calculateLight( position, normal, color ) {
 
-			for ( l = 0, ll = lights.length; l < ll; l ++ ) {
+			for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
 
-				light = lights[ l ];
-				lightColor = light.color;
+				var light = _lights[ l ];
+				var lightColor = light.color;
 
 				if ( light instanceof THREE.DirectionalLight ) {
 
-					lightPosition = light.matrixWorld.getPosition().normalize();
+					var lightPosition = light.matrixWorld.getPosition().normalize();
 
-					amount = normal.dot( lightPosition );
+					var amount = normal.dot( lightPosition );
 
 					if ( amount <= 0 ) continue;
 
@@ -389,9 +385,9 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 				} else if ( light instanceof THREE.PointLight ) {
 
-					lightPosition = light.matrixWorld.getPosition();
+					var lightPosition = light.matrixWorld.getPosition();
 
-					amount = normal.dot( _vector3.sub( lightPosition, position ).normalize() );
+					var amount = normal.dot( _vector3.sub( lightPosition, position ).normalize() );
 
 					if ( amount <= 0 ) continue;
 
@@ -528,7 +524,6 @@ THREE.CanvasRenderer = function ( parameters ) {
 			_context.beginPath();
 			_context.moveTo( v1.positionScreen.x, v1.positionScreen.y );
 			_context.lineTo( v2.positionScreen.x, v2.positionScreen.y );
-			_context.closePath();
 
 			if ( material instanceof THREE.LineBasicMaterial ) {
 
@@ -607,15 +602,15 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 				if ( _enableLighting === true ) {
 
-					if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsWorld.length == 3 ) {
+					if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 3 ) {
 
 						_color1.r = _color2.r = _color3.r = _ambientLight.r;
 						_color1.g = _color2.g = _color3.g = _ambientLight.g;
 						_color1.b = _color2.b = _color3.b = _ambientLight.b;
 
-						calculateLight( _lights, element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
-						calculateLight( _lights, element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
-						calculateLight( _lights, element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color3 );
+						calculateLight( element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
+						calculateLight( element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
+						calculateLight( element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color3 );
 
 						_color1.r = Math.max( 0, Math.min( material.color.r * _color1.r, 1 ) );
 						_color1.g = Math.max( 0, Math.min( material.color.g * _color1.g, 1 ) );
@@ -643,7 +638,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 						_color.g = _ambientLight.g;
 						_color.b = _ambientLight.b;
 
-						calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
+						calculateLight( element.centroidWorld, element.normalWorld, _color );
 
 						_color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
 						_color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
@@ -724,16 +719,16 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 				if ( _enableLighting === true ) {
 
-					if ( !material.wireframe && material.shading == THREE.SmoothShading && element.vertexNormalsWorld.length == 4 ) {
+					if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 4 ) {
 
 						_color1.r = _color2.r = _color3.r = _color4.r = _ambientLight.r;
 						_color1.g = _color2.g = _color3.g = _color4.g = _ambientLight.g;
 						_color1.b = _color2.b = _color3.b = _color4.b = _ambientLight.b;
 
-						calculateLight( _lights, element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
-						calculateLight( _lights, element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
-						calculateLight( _lights, element.v4.positionWorld, element.vertexNormalsWorld[ 3 ], _color3 );
-						calculateLight( _lights, element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color4 );
+						calculateLight( element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
+						calculateLight( element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
+						calculateLight( element.v4.positionWorld, element.vertexNormalsWorld[ 3 ], _color3 );
+						calculateLight( element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color4 );
 
 						_color1.r = Math.max( 0, Math.min( material.color.r * _color1.r, 1 ) );
 						_color1.g = Math.max( 0, Math.min( material.color.g * _color1.g, 1 ) );
@@ -767,7 +762,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 						_color.g = _ambientLight.g;
 						_color.b = _ambientLight.b;
 
-						calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
+						calculateLight( element.centroidWorld, element.normalWorld, _color );
 
 						_color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
 						_color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
@@ -829,7 +824,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 			_context.moveTo( x0, y0 );
 			_context.lineTo( x1, y1 );
 			_context.lineTo( x2, y2 );
-			_context.lineTo( x0, y0 );
+			_context.closePath();
 
 		}
 
@@ -840,7 +835,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 			_context.lineTo( x1, y1 );
 			_context.lineTo( x2, y2 );
 			_context.lineTo( x3, y3 );
-			_context.lineTo( x0, y0 );
+			_context.closePath();
 
 		}
 
@@ -919,9 +914,6 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 					_imagedatas[ texture.id ] = context.getImageData( 0, 0, texture.image.width, texture.image.height ).data;
 
-					// variables cannot be deleted in ES5 strict mode
-					//delete canvas;
-
 				}
 
 				var data = _imagedatas[ texture.id ];
@@ -993,10 +985,10 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 			// http://mrdoob.com/blog/post/710
 
-			var c1r = ~~ ( color1.r * 255 ), c1g = ~~ ( color1.g * 255 ), c1b = ~~ ( color1.b * 255 ),
-			c2r = ~~ ( color2.r * 255 ), c2g = ~~ ( color2.g * 255 ), c2b = ~~ ( color2.b * 255 ),
-			c3r = ~~ ( color3.r * 255 ), c3g = ~~ ( color3.g * 255 ), c3b = ~~ ( color3.b * 255 ),
-			c4r = ~~ ( color4.r * 255 ), c4g = ~~ ( color4.g * 255 ), c4b = ~~ ( color4.b * 255 );
+			var c1r = ( color1.r * 255 ) | 0, c1g = ( color1.g * 255 ) | 0, c1b = ( color1.b * 255 ) | 0;
+			var c2r = ( color2.r * 255 ) | 0, c2g = ( color2.g * 255 ) | 0, c2b = ( color2.b * 255 ) | 0;
+			var c3r = ( color3.r * 255 ) | 0, c3g = ( color3.g * 255 ) | 0, c3b = ( color3.b * 255 ) | 0;
+			var c4r = ( color4.r * 255 ) | 0, c4g = ( color4.g * 255 ) | 0, c4b = ( color4.b * 255 ) | 0;
 
 			_pixelMapData[ 0 ] = c1r < 0 ? 0 : c1r > 255 ? 255 : c1r;
 			_pixelMapData[ 1 ] = c1g < 0 ? 0 : c1g > 255 ? 255 : c1g;

+ 282 - 260
src/renderers/WebGLRenderer.js

@@ -113,6 +113,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 	_currentCamera = null,
 	_geometryGroupCounter = 0,
 
+	_usedTextureUnits = 0,
+
 	// GL state cache
 
 	_oldDoubleSided = -1,
@@ -162,7 +164,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 		ambient: [ 0, 0, 0 ],
 		directional: { length: 0, colors: new Array(), positions: new Array() },
 		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
-		spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), angles: new Array(), exponents: new Array() }
+		spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), angles: new Array(), exponents: new Array() },
+		hemi: { length: 0, skyColors: new Array(), groundColors: new Array(), positions: new Array() }
 
 	};
 
@@ -182,9 +185,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	// GPU capabilities
 
-	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ),
-	_maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ),
-	_maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
+	var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
+	var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
+	var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
+	var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
 
 	var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;
 
@@ -506,8 +510,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 		geometryGroup.__webglUVBuffer = _gl.createBuffer();
 		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
 
-		geometryGroup.__webglSkinVertexABuffer = _gl.createBuffer();
-		geometryGroup.__webglSkinVertexBBuffer = _gl.createBuffer();
 		geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
 		geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
 
@@ -582,8 +584,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 		_gl.deleteBuffer( geometryGroup.__webglUVBuffer );
 		_gl.deleteBuffer( geometryGroup.__webglUV2Buffer );
 
-		_gl.deleteBuffer( geometryGroup.__webglSkinVertexABuffer );
-		_gl.deleteBuffer( geometryGroup.__webglSkinVertexBBuffer );
 		_gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
 		_gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );
 
@@ -772,8 +772,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {
 
-			geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 );
-			geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 );
 			geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
 			geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
 
@@ -1555,8 +1553,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 		tangentArray = geometryGroup.__tangentArray,
 		colorArray = geometryGroup.__colorArray,
 
-		skinVertexAArray = geometryGroup.__skinVertexAArray,
-		skinVertexBArray = geometryGroup.__skinVertexBArray,
 		skinIndexArray = geometryGroup.__skinIndexArray,
 		skinWeightArray = geometryGroup.__skinWeightArray,
 
@@ -1589,8 +1585,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		obj_colors = geometry.colors,
 
-		obj_skinVerticesA = geometry.skinVerticesA,
-		obj_skinVerticesB = geometry.skinVerticesB,
 		obj_skinIndices = geometry.skinIndices,
 		obj_skinWeights = geometry.skinWeights,
 
@@ -1870,48 +1864,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 				skinIndexArray[ offset_skin + 10 ] = si3.z;
 				skinIndexArray[ offset_skin + 11 ] = si3.w;
 
-				// vertices A
-
-				sa1 = obj_skinVerticesA[ face.a ];
-				sa2 = obj_skinVerticesA[ face.b ];
-				sa3 = obj_skinVerticesA[ face.c ];
-
-				skinVertexAArray[ offset_skin ]     = sa1.x;
-				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
-				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
-				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
-
-				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
-				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
-				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
-				skinVertexAArray[ offset_skin + 7 ] = 1;
-
-				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
-				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
-				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
-				skinVertexAArray[ offset_skin + 11 ] = 1;
-
-				// vertices B
-
-				sb1 = obj_skinVerticesB[ face.a ];
-				sb2 = obj_skinVerticesB[ face.b ];
-				sb3 = obj_skinVerticesB[ face.c ];
-
-				skinVertexBArray[ offset_skin ]     = sb1.x;
-				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
-				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
-				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
-
-				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
-				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
-				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
-				skinVertexBArray[ offset_skin + 7 ] = 1;
-
-				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
-				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
-				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
-				skinVertexBArray[ offset_skin + 11 ] = 1;
-
 				offset_skin += 12;
 
 			}
@@ -1974,72 +1926,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 				skinIndexArray[ offset_skin + 14 ] = si4.z;
 				skinIndexArray[ offset_skin + 15 ] = si4.w;
 
-				// vertices A
-
-				sa1 = obj_skinVerticesA[ face.a ];
-				sa2 = obj_skinVerticesA[ face.b ];
-				sa3 = obj_skinVerticesA[ face.c ];
-				sa4 = obj_skinVerticesA[ face.d ];
-
-				skinVertexAArray[ offset_skin ]     = sa1.x;
-				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
-				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
-				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
-
-				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
-				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
-				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
-				skinVertexAArray[ offset_skin + 7 ] = 1;
-
-				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
-				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
-				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
-				skinVertexAArray[ offset_skin + 11 ] = 1;
-
-				skinVertexAArray[ offset_skin + 12 ] = sa4.x;
-				skinVertexAArray[ offset_skin + 13 ] = sa4.y;
-				skinVertexAArray[ offset_skin + 14 ] = sa4.z;
-				skinVertexAArray[ offset_skin + 15 ] = 1;
-
-				// vertices B
-
-				sb1 = obj_skinVerticesB[ face.a ];
-				sb2 = obj_skinVerticesB[ face.b ];
-				sb3 = obj_skinVerticesB[ face.c ];
-				sb4 = obj_skinVerticesB[ face.d ];
-
-				skinVertexBArray[ offset_skin ]     = sb1.x;
-				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
-				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
-				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
-
-				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
-				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
-				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
-				skinVertexBArray[ offset_skin + 7 ] = 1;
-
-				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
-				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
-				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
-				skinVertexBArray[ offset_skin + 11 ] = 1;
-
-				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
-				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
-				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
-				skinVertexBArray[ offset_skin + 15 ] = 1;
-
 				offset_skin += 16;
 
 			}
 
 			if ( offset_skin > 0 ) {
 
-				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
-				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
-
-				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
-				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );
-
 				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
 				_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );
 
@@ -3030,8 +2922,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 			delete geometryGroup.__faceArray;
 			delete geometryGroup.__vertexArray;
 			delete geometryGroup.__lineArray;
-			delete geometryGroup.__skinVertexAArray;
-			delete geometryGroup.__skinVertexBArray;
 			delete geometryGroup.__skinIndexArray;
 			delete geometryGroup.__skinWeightArray;
 
@@ -3326,6 +3216,42 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			}
 
+		// render particles
+
+		} else if ( object instanceof THREE.ParticleSystem ) {
+
+			if ( updateBuffers ) {
+
+				// vertices
+
+				var position = geometry.attributes[ "position" ];
+				var positionSize = position.itemSize;
+
+				_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
+				_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );
+
+				// colors
+
+				var color = geometry.attributes[ "color" ];
+
+				if ( attributes.color >= 0 && color ) {
+
+					var colorSize = color.itemSize;
+
+					_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
+					_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );
+
+				}
+
+				// render particles
+
+				_gl.drawArrays( _gl.POINTS, 0, position.numItems / 3 );
+
+				_this.info.render.calls ++;
+				_this.info.render.points += position.numItems / 3;
+
+			}
+
 		}
 
 	};
@@ -3461,15 +3387,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 			}
 
 			if ( material.skinning &&
-				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
 				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
 
-				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
-				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
-
-				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
-				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
-
 				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
 				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
 
@@ -4314,11 +4233,20 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				if ( ! geometry.__webglVertexBuffer ) {
 
-					createParticleBuffers( geometry );
-					initParticleBuffers( geometry, object );
+					if ( geometry instanceof THREE.Geometry ) {
+
+						createParticleBuffers( geometry );
+						initParticleBuffers( geometry, object );
+
+						geometry.verticesNeedUpdate = true;
+						geometry.colorsNeedUpdate = true;
+
+					} else if ( geometry instanceof THREE.BufferGeometry ) {
+
+						initDirectBuffers( geometry );
+
+					}
 
-					geometry.verticesNeedUpdate = true;
-					geometry.colorsNeedUpdate = true;
 
 				}
 
@@ -4490,20 +4418,35 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		} else if ( object instanceof THREE.ParticleSystem ) {
 
-			material = getBufferMaterial( object, geometryGroup );
+			if ( geometry instanceof THREE.BufferGeometry ) {
 
-			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
+				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
 
-			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
+					setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
 
-				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
+				}
 
-			}
+				geometry.verticesNeedUpdate = false;
+				geometry.colorsNeedUpdate = false;
 
-			geometry.verticesNeedUpdate = false;
-			geometry.colorsNeedUpdate = false;
+			} else {
 
-			material.attributes && clearCustomAttributes( material );
+				material = getBufferMaterial( object, geometryGroup );
+
+				customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
+
+				if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
+
+					setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
+
+				}
+
+				geometry.verticesNeedUpdate = false;
+				geometry.colorsNeedUpdate = false;
+
+				material.attributes && clearCustomAttributes( material );
+
+			}
 
 		}
 
@@ -4671,6 +4614,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			maxDirLights: maxLightCount.directional,
 			maxPointLights: maxLightCount.point,
 			maxSpotLights: maxLightCount.spot,
+			maxHemiLights: maxLightCount.hemi,
 
 			maxShadows: maxShadows,
 			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
@@ -4682,7 +4626,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 			metal: material.metal,
 			perPixel: material.perPixel,
 			wrapAround: material.wrapAround,
-			doubleSided: material.side === THREE.DoubleSide
+			doubleSided: material.side === THREE.DoubleSide,
+			flipSided: material.side === THREE.BackSide
 
 		};
 
@@ -4696,11 +4641,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
 
 		if ( material.skinning &&
-			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
 			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
 
-			_gl.enableVertexAttribArray( attributes.skinVertexA );
-			_gl.enableVertexAttribArray( attributes.skinVertexB );
 			_gl.enableVertexAttribArray( attributes.skinIndex );
 			_gl.enableVertexAttribArray( attributes.skinWeight );
 
@@ -4778,6 +4720,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	function setProgram( camera, lights, fog, material, object ) {
 
+		_usedTextureUnits = 0;
+
 		if ( material.needsUpdate ) {
 
 			if ( material.program ) _this.deallocateMaterial( material );
@@ -4827,6 +4771,35 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		// skinning uniforms must be set even if material didn't change
+		// auto-setting of texture unit for bone texture must go before other textures
+		// not sure why, but otherwise weird things happen
+
+		if ( material.skinning ) {
+
+			if ( _supportsBoneTextures && object.useVertexTexture ) {
+
+				if ( p_uniforms.boneTexture !== null ) {
+
+					var textureUnit = getTextureUnit();
+
+					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
+					_this.setTexture( object.boneTexture, textureUnit );
+
+				}
+
+			} else {
+
+				if ( p_uniforms.boneGlobalMatrices !== null ) {
+
+					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
+
+				}
+
+			}
+
+		}
+
 		if ( refreshMaterial ) {
 
 			// refresh uniforms common to several materials
@@ -4931,34 +4904,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( material.skinning ) {
-
-			if ( _supportsBoneTextures && object.useVertexTexture ) {
-
-				if ( p_uniforms.boneTexture !== null ) {
-
-					// shadowMap texture array starts from 6
-					// texture unit 12 should leave space for 6 shadowmaps
-
-					var textureUnit = 12;
-
-					_gl.uniform1i( p_uniforms.boneTexture, textureUnit );
-					_this.setTexture( object.boneTexture, textureUnit );
-
-				}
-
-			} else {
-
-				if ( p_uniforms.boneGlobalMatrices !== null ) {
-
-					_gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
-
-				}
-
-			}
-
-		}
-
 		loadUniformsMatrices( p_uniforms, object );
 
 		if ( p_uniforms.modelMatrix !== null ) {
@@ -4987,13 +4932,13 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		uniforms.map.texture = material.map;
-		uniforms.lightMap.texture = material.lightMap;
-		uniforms.specularMap.texture = material.specularMap;
+		uniforms.map.value = material.map;
+		uniforms.lightMap.value = material.lightMap;
+		uniforms.specularMap.value = material.specularMap;
 
 		if ( material.bumpMap ) {
 
-			uniforms.bumpMap.texture = material.bumpMap;
+			uniforms.bumpMap.value = material.bumpMap;
 			uniforms.bumpScale.value = material.bumpScale;
 
 		}
@@ -5037,7 +4982,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		uniforms.envMap.texture = material.envMap;
+		uniforms.envMap.value = material.envMap;
 		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
 
 		if ( _this.gammaInput ) {
@@ -5071,7 +5016,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		uniforms.size.value = material.size;
 		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
 
-		uniforms.map.texture = material.map;
+		uniforms.map.value = material.map;
 
 	};
 
@@ -5158,6 +5103,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 		uniforms.spotLightAngle.value = lights.spot.angles;
 		uniforms.spotLightExponent.value = lights.spot.exponents;
 
+		uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
+		uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
+		uniforms.hemisphereLightPosition.value = lights.hemi.positions;
+
 	};
 
 	function refreshUniformsShadow ( uniforms, lights ) {
@@ -5174,7 +5123,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
 
-					uniforms.shadowMap.texture[ j ] = light.shadowMap;
+					uniforms.shadowMap.value[ j ] = light.shadowMap;
 					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
 
 					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
@@ -5206,9 +5155,25 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
+	function getTextureUnit() {
+
+		var textureUnit = _usedTextureUnits;
+
+		if ( textureUnit >= _maxTextures ) {
+
+			console.warn( "Trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures );
+
+		}
+
+		_usedTextureUnits += 1;
+
+		return textureUnit;
+
+	};
+
 	function loadUniformsGeneric ( program, uniforms ) {
 
-		var uniform, value, type, location, texture, i, il, j, jl, offset;
+		var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset;
 
 		for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
 
@@ -5349,23 +5314,24 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			} else if ( type === "t" ) { // single THREE.Texture (2d or cube)
 
-				_gl.uniform1i( location, value );
+				texture = value;
+				textureUnit = getTextureUnit();
 
-				texture = uniform.texture;
+				_gl.uniform1i( location, textureUnit );
 
 				if ( !texture ) continue;
 
 				if ( texture.image instanceof Array && texture.image.length === 6 ) {
 
-					setCubeTexture( texture, value );
+					setCubeTexture( texture, textureUnit );
 
 				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
 
-					setCubeTextureDynamic( texture, value );
+					setCubeTextureDynamic( texture, textureUnit );
 
 				} else {
 
-					_this.setTexture( texture, value );
+					_this.setTexture( texture, textureUnit );
 
 				}
 
@@ -5375,23 +5341,24 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 					uniform._array = [];
 
-					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
+				}
 
-						uniform._array[ i ] = value + i;
+				for( i = 0, il = uniform.value.length; i < il; i ++ ) {
 
-					}
+					uniform._array[ i ] = getTextureUnit();
 
 				}
 
 				_gl.uniform1iv( location, uniform._array );
 
-				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
+				for( i = 0, il = uniform.value.length; i < il; i ++ ) {
 
-					texture = uniform.texture[ i ];
+					texture = uniform.value[ i ];
+					textureUnit = uniform._array[ i ];
 
 					if ( !texture ) continue;
 
-					_this.setTexture( texture, uniform._array[ i ] );
+					_this.setTexture( texture, textureUnit );
 
 				}
 
@@ -5410,35 +5377,62 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
+	//
+
+	function setColorGamma( array, offset, color, intensitySq ) {
+
+		array[ offset ]     = color.r * color.r * intensitySq;
+		array[ offset + 1 ] = color.g * color.g * intensitySq;
+		array[ offset + 2 ] = color.b * color.b * intensitySq;
+
+	};
+
+	function setColorLinear( array, offset, color, intensity ) {
+
+		array[ offset ]     = color.r * intensity;
+		array[ offset + 1 ] = color.g * intensity;
+		array[ offset + 2 ] = color.b * intensity;
+
+	};
+
 	function setupLights ( program, lights ) {
 
 		var l, ll, light, n,
 		r = 0, g = 0, b = 0,
-		color, position, intensity, distance,
+		color, skyColor, groundColor,
+		intensity,  intensitySq,
+		position,
+		distance,
 
 		zlights = _lights,
 
-		dcolors = zlights.directional.colors,
-		dpositions = zlights.directional.positions,
+		dirColors = zlights.directional.colors,
+		dirPositions = zlights.directional.positions,
+
+		pointColors = zlights.point.colors,
+		pointPositions = zlights.point.positions,
+		pointDistances = zlights.point.distances,
 
-		pcolors = zlights.point.colors,
-		ppositions = zlights.point.positions,
-		pdistances = zlights.point.distances,
+		spotColors = zlights.spot.colors,
+		spotPositions = zlights.spot.positions,
+		spotDistances = zlights.spot.distances,
+		spotDirections = zlights.spot.directions,
+		spotAngles = zlights.spot.angles,
+		spotExponents = zlights.spot.exponents,
 
-		scolors = zlights.spot.colors,
-		spositions = zlights.spot.positions,
-		sdistances = zlights.spot.distances,
-		sdirections = zlights.spot.directions,
-		sangles = zlights.spot.angles,
-		sexponents = zlights.spot.exponents,
+		hemiSkyColors = zlights.hemi.skyColors,
+		hemiGroundColors = zlights.hemi.groundColors,
+		hemiPositions = zlights.hemi.positions,
 
-		dlength = 0,
-		plength = 0,
-		slength = 0,
+		dirLength = 0,
+		pointLength = 0,
+		spotLength = 0,
+		hemiLength = 0,
 
-		doffset = 0,
-		poffset = 0,
-		soffset = 0;
+		dirOffset = 0,
+		pointOffset = 0,
+		spotOffset = 0,
+		hemiOffset = 0;
 
 		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
 
@@ -5468,19 +5462,15 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			} else if ( light instanceof THREE.DirectionalLight ) {
 
-				doffset = dlength * 3;
+				dirOffset = dirLength * 3;
 
 				if ( _this.gammaInput ) {
 
-					dcolors[ doffset ]     = color.r * color.r * intensity * intensity;
-					dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity;
-					dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity;
+					setColorGamma( dirColors, dirOffset, color, intensity * intensity );
 
 				} else {
 
-					dcolors[ doffset ]     = color.r * intensity;
-					dcolors[ doffset + 1 ] = color.g * intensity;
-					dcolors[ doffset + 2 ] = color.b * intensity;
+					setColorLinear( dirColors, dirOffset, color, intensity );
 
 				}
 
@@ -5488,78 +5478,99 @@ THREE.WebGLRenderer = function ( parameters ) {
 				_direction.subSelf( light.target.matrixWorld.getPosition() );
 				_direction.normalize();
 
-				dpositions[ doffset ]     = _direction.x;
-				dpositions[ doffset + 1 ] = _direction.y;
-				dpositions[ doffset + 2 ] = _direction.z;
+				dirPositions[ dirOffset ]     = _direction.x;
+				dirPositions[ dirOffset + 1 ] = _direction.y;
+				dirPositions[ dirOffset + 2 ] = _direction.z;
 
-				dlength += 1;
+				dirLength += 1;
 
 			} else if( light instanceof THREE.PointLight ) {
 
-				poffset = plength * 3;
+				pointOffset = pointLength * 3;
 
 				if ( _this.gammaInput ) {
 
-					pcolors[ poffset ]     = color.r * color.r * intensity * intensity;
-					pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity;
-					pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity;
+					setColorGamma( pointColors, pointOffset, color, intensity * intensity );
 
 				} else {
 
-					pcolors[ poffset ]     = color.r * intensity;
-					pcolors[ poffset + 1 ] = color.g * intensity;
-					pcolors[ poffset + 2 ] = color.b * intensity;
+					setColorLinear( pointColors, pointOffset, color, intensity );
 
 				}
 
 				position = light.matrixWorld.getPosition();
 
-				ppositions[ poffset ]     = position.x;
-				ppositions[ poffset + 1 ] = position.y;
-				ppositions[ poffset + 2 ] = position.z;
+				pointPositions[ pointOffset ]     = position.x;
+				pointPositions[ pointOffset + 1 ] = position.y;
+				pointPositions[ pointOffset + 2 ] = position.z;
 
-				pdistances[ plength ] = distance;
+				pointDistances[ pointLength ] = distance;
 
-				plength += 1;
+				pointLength += 1;
 
 			} else if( light instanceof THREE.SpotLight ) {
 
-				soffset = slength * 3;
+				spotOffset = spotLength * 3;
 
 				if ( _this.gammaInput ) {
 
-					scolors[ soffset ]     = color.r * color.r * intensity * intensity;
-					scolors[ soffset + 1 ] = color.g * color.g * intensity * intensity;
-					scolors[ soffset + 2 ] = color.b * color.b * intensity * intensity;
+					setColorGamma( spotColors, spotOffset, color, intensity * intensity );
 
 				} else {
 
-					scolors[ soffset ]     = color.r * intensity;
-					scolors[ soffset + 1 ] = color.g * intensity;
-					scolors[ soffset + 2 ] = color.b * intensity;
+					setColorLinear( spotColors, spotOffset, color, intensity );
 
 				}
 
 				position = light.matrixWorld.getPosition();
 
-				spositions[ soffset ]     = position.x;
-				spositions[ soffset + 1 ] = position.y;
-				spositions[ soffset + 2 ] = position.z;
+				spotPositions[ spotOffset ]     = position.x;
+				spotPositions[ spotOffset + 1 ] = position.y;
+				spotPositions[ spotOffset + 2 ] = position.z;
 
-				sdistances[ slength ] = distance;
+				spotDistances[ spotLength ] = distance;
 
 				_direction.copy( position );
 				_direction.subSelf( light.target.matrixWorld.getPosition() );
 				_direction.normalize();
 
-				sdirections[ soffset ]     = _direction.x;
-				sdirections[ soffset + 1 ] = _direction.y;
-				sdirections[ soffset + 2 ] = _direction.z;
+				spotDirections[ spotOffset ]     = _direction.x;
+				spotDirections[ spotOffset + 1 ] = _direction.y;
+				spotDirections[ spotOffset + 2 ] = _direction.z;
+
+				spotAngles[ spotLength ] = Math.cos( light.angle );
+				spotExponents[ spotLength ] = light.exponent;
+
+				spotLength += 1;
+
+			} else if ( light instanceof THREE.HemisphereLight ) {
 
-				sangles[ slength ] = Math.cos( light.angle );
-				sexponents[ slength ] = light.exponent;
+				skyColor = light.color;
+				groundColor = light.groundColor;
 
-				slength += 1;
+				hemiOffset = hemiLength * 3;
+
+				if ( _this.gammaInput ) {
+
+					intensitySq = intensity * intensity;
+
+					setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq );
+					setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq );
+
+				} else {
+
+					setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
+					setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
+
+				}
+
+				position = light.matrixWorld.getPosition();
+
+				hemiPositions[ hemiOffset ]     = position.x;
+				hemiPositions[ hemiOffset + 1 ] = position.y;
+				hemiPositions[ hemiOffset + 2 ] = position.z;
+
+				hemiLength += 1;
 
 			}
 
@@ -5568,13 +5579,16 @@ THREE.WebGLRenderer = function ( parameters ) {
 		// null eventual remains from removed lights
 		// (this is to avoid if in shader)
 
-		for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0;
-		for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0;
-		for ( l = slength * 3, ll = scolors.length; l < ll; l ++ ) scolors[ l ] = 0.0;
+		for ( l = dirLength * 3, ll = dirColors.length; l < ll; l ++ ) dirColors[ l ] = 0.0;
+		for ( l = pointLength * 3, ll = pointColors.length; l < ll; l ++ ) pointColors[ l ] = 0.0;
+		for ( l = spotLength * 3, ll = spotColors.length; l < ll; l ++ ) spotColors[ l ] = 0.0;
+		for ( l = hemiLength * 3, ll = hemiSkyColors.length; l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
+		for ( l = hemiLength * 3, ll = hemiGroundColors.length; l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
 
-		zlights.directional.length = dlength;
-		zlights.point.length = plength;
-		zlights.spot.length = slength;
+		zlights.directional.length = dirLength;
+		zlights.point.length = pointLength;
+		zlights.spot.length = spotLength;
+		zlights.hemi.length = hemiLength;
 
 		zlights.ambient[ 0 ] = r;
 		zlights.ambient[ 1 ] = g;
@@ -5872,6 +5886,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
 			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
 			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
+			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
 
 			"#define MAX_SHADOWS " + parameters.maxShadows,
 
@@ -5895,6 +5910,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
 			parameters.wrapAround ? "#define WRAP_AROUND" : "",
 			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
+			parameters.flipSided ? "#define FLIP_SIDED" : "",
 
 			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
 			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
@@ -5948,8 +5964,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			"#ifdef USE_SKINNING",
 
-				"attribute vec4 skinVertexA;",
-				"attribute vec4 skinVertexB;",
 				"attribute vec4 skinIndex;",
 				"attribute vec4 skinWeight;",
 
@@ -5968,6 +5982,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
 			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
 			"#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
+			"#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
 
 			"#define MAX_SHADOWS " + parameters.maxShadows,
 
@@ -5992,6 +6007,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
 			parameters.wrapAround ? "#define WRAP_AROUND" : "",
 			parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
+			parameters.flipSided ? "#define FLIP_SIDED" : "",
 
 			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
 			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
@@ -6065,7 +6081,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		identifiers = [
 
 			"position", "normal", "uv", "uv2", "tangent", "color",
-			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"
+			"skinIndex", "skinWeight"
 
 		];
 
@@ -6652,9 +6668,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	function allocateLights ( lights ) {
 
-		var l, ll, light, dirLights, pointLights, spotLights, maxDirLights, maxPointLights, maxSpotLights;
+		var l, ll, light, dirLights, pointLights, spotLights, hemiLights, maxDirLights, maxPointLights, maxSpotLights, maxHemiLights;
 
-		dirLights = pointLights = spotLights = maxDirLights = maxPointLights = maxSpotLights = 0;
+		dirLights = pointLights = spotLights = hemiLights = maxDirLights = maxPointLights = maxSpotLights = maxHemiLights = 0;
 
 		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
 
@@ -6665,24 +6681,30 @@ THREE.WebGLRenderer = function ( parameters ) {
 			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
 			if ( light instanceof THREE.PointLight ) pointLights ++;
 			if ( light instanceof THREE.SpotLight ) spotLights ++;
+			if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
 
 		}
 
-		if ( ( pointLights + spotLights + dirLights ) <= _maxLights ) {
+		if ( ( pointLights + spotLights + dirLights + hemiLights) <= _maxLights ) {
 
 			maxDirLights = dirLights;
 			maxPointLights = pointLights;
 			maxSpotLights = spotLights;
+			maxHemiLights = hemiLights;
 
 		} else {
 
 			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
 			maxPointLights = _maxLights - maxDirLights;
-			maxSpotLights = maxPointLights; // this is not really correct
+
+			// these are not really correct
+
+			maxSpotLights = maxPointLights;
+			maxHemiLights = maxDirLights;
 
 		}
 
-		return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights };
+		return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights, 'hemi': maxHemiLights };
 
 	};
 

+ 224 - 84
src/renderers/WebGLShaders.js

@@ -149,17 +149,37 @@ THREE.ShaderChunk = {
 
 	].join("\n"),
 
-	envmap_vertex : [
+	worldpos_vertex : [
 
-		"#ifdef USE_ENVMAP",
+		"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )",
+
+			"#ifdef USE_SKINNING",
 
-			"vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
+				"vec4 mPosition = modelMatrix * skinned;",
 
-		"#endif",
+			"#endif",
+
+			"#if defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",
+
+				"vec4 mPosition = modelMatrix * vec4( morphed, 1.0 );",
+
+			"#endif",
+
+			"#if ! defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",
+
+				"vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
+
+			"#endif",
+
+		"#endif"
+
+	].join("\n"),
+
+	envmap_vertex : [
 
 		"#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined(USE_NORMALMAP)",
 
-			"vec3 nWorld = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * normal;",
+			"vec3 nWorld = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * objectNormal;",
 
 			"if ( useRefract ) {",
 
@@ -427,6 +447,14 @@ THREE.ShaderChunk = {
 
 		"#endif",
 
+		"#if MAX_HEMI_LIGHTS > 0",
+
+			"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
+			"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
+			"uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
+
+		"#endif",
+
 		"#if MAX_POINT_LIGHTS > 0",
 
 			"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
@@ -627,6 +655,32 @@ THREE.ShaderChunk = {
 
 		"#endif",
 
+		"#if MAX_HEMI_LIGHTS > 0",
+
+			"for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
+
+				"vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
+				"vec3 lVector = lPosition.xyz - mvPosition.xyz;",
+
+				"lVector = normalize( lVector );",
+
+				"float dotProduct = dot( normal, lVector );",
+
+				"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
+				"float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;",
+
+				"vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+				"#ifdef DOUBLE_SIDED",
+
+					"vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );",
+
+				"#endif",
+
+			"}",
+
+		"#endif",
+
 		"vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;",
 
 		"#ifdef DOUBLE_SIDED",
@@ -731,6 +785,14 @@ THREE.ShaderChunk = {
 
 		"#endif",
 
+		"#if MAX_HEMI_LIGHTS > 0",
+
+			"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
+			"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
+			"uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
+
+		"#endif",
+
 		"#if MAX_POINT_LIGHTS > 0",
 
 			"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
@@ -1027,6 +1089,59 @@ THREE.ShaderChunk = {
 
 		"#endif",
 
+		"#if MAX_HEMI_LIGHTS > 0",
+
+			"vec3 hemiDiffuse  = vec3( 0.0 );",
+			"vec3 hemiSpecular = vec3( 0.0 );" ,
+
+			"for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
+
+				"vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
+				"vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
+
+				// diffuse
+
+				"float dotProduct = dot( normal, lVector );",
+				"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
+
+				"hemiDiffuse += diffuse * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+				// specular (sky light)
+
+				"float hemiSpecularWeight = 0.0;",
+
+				"vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
+				"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
+				"hemiSpecularWeight += specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",
+
+				// specular (ground light)
+
+				"vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
+
+				"vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
+				"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
+				"hemiSpecularWeight += specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
+
+				"#ifdef PHYSICALLY_BASED_SHADING",
+
+					// 2.0 => 2.0001 is hack to work around ANGLE bug
+
+					"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
+
+					"vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
+					"vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
+					"hemiSpecular += ( schlickSky + schlickGround ) * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight * specularNormalization;",
+
+				"#else",
+
+					"hemiSpecular += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
+
+				"#endif",
+
+			"}",
+
+		"#endif",
+
 		"vec3 totalDiffuse = vec3( 0.0 );",
 		"vec3 totalSpecular = vec3( 0.0 );",
 
@@ -1037,6 +1152,13 @@ THREE.ShaderChunk = {
 
 		"#endif",
 
+		"#if MAX_HEMI_LIGHTS > 0",
+
+			"totalDiffuse += hemiDiffuse;",
+			"totalSpecular += hemiSpecular;",
+
+		"#endif",
+
 		"#if MAX_POINT_LIGHTS > 0",
 
 			"totalDiffuse += pointDiffuse;",
@@ -1179,10 +1301,18 @@ THREE.ShaderChunk = {
 
 		"#ifdef USE_SKINNING",
 
-			"vec4 skinned  = boneMatX * skinVertexA * skinWeight.x;",
-			"skinned 	  += boneMatY * skinVertexB * skinWeight.y;",
+			"#ifdef USE_MORPHTARGETS",
+
+			"vec4 skinVertex = vec4( morphed, 1.0 );",
+
+			"#else",
+
+			"vec4 skinVertex = vec4( position, 1.0 );",
 
-			"gl_Position  = projectionMatrix * modelViewMatrix * skinned;",
+			"#endif",
+
+			"vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
+			"skinned 	  += boneMatY * skinVertex * skinWeight.y;",
 
 		"#endif"
 
@@ -1229,21 +1359,33 @@ THREE.ShaderChunk = {
 
 			"morphed += position;",
 
-			"gl_Position = projectionMatrix * modelViewMatrix * vec4( morphed, 1.0 );",
-
 		"#endif"
 
 	].join("\n"),
 
 	default_vertex : [
 
-		"#ifndef USE_MORPHTARGETS",
-		"#ifndef USE_SKINNING",
+		"vec4 mvPosition;",
 
-			"gl_Position = projectionMatrix * mvPosition;",
+		"#ifdef USE_SKINNING",
+
+			"mvPosition = modelViewMatrix * skinned;",
 
 		"#endif",
-		"#endif"
+
+		"#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )",
+
+			"mvPosition = modelViewMatrix * vec4( morphed, 1.0 );",
+
+		"#endif",
+
+		"#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )",
+
+			"mvPosition = modelViewMatrix * vec4( position, 1.0 );",
+
+		"#endif",
+
+		"gl_Position = projectionMatrix * mvPosition;",
 
 	].join("\n"),
 
@@ -1271,37 +1413,49 @@ THREE.ShaderChunk = {
 			"mat4 skinMatrix = skinWeight.x * boneMatX;",
 			"skinMatrix 	+= skinWeight.y * boneMatY;",
 
+			"#ifdef USE_MORPHNORMALS",
+
+			"vec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );",
+
+			"#else",
+
 			"vec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );",
 
+			"#endif",
+
 		"#endif"
 
 	].join("\n"),
 
 	defaultnormal_vertex: [
 
-		"vec3 transformedNormal;",
+		"vec3 objectNormal;",
 
 		"#ifdef USE_SKINNING",
 
-			"transformedNormal = skinnedNormal.xyz;",
+			"objectNormal = skinnedNormal.xyz;",
 
 		"#endif",
 
-		"#ifdef USE_MORPHNORMALS",
+		"#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )",
 
-			"transformedNormal = morphedNormal;",
+			"objectNormal = morphedNormal;",
 
 		"#endif",
 
-		"#ifndef USE_MORPHNORMALS",
-		"#ifndef USE_SKINNING",
+		"#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )",
 
-			"transformedNormal = normal;",
+			"objectNormal = normal;",
 
 		"#endif",
+
+		"#ifdef FLIP_SIDED",
+
+			"objectNormal = -objectNormal;",
+
 		"#endif",
 
-		"transformedNormal = normalMatrix * transformedNormal;",
+		"vec3 transformedNormal = normalMatrix * objectNormal;",
 
 	].join("\n"),
 
@@ -1521,27 +1675,9 @@ THREE.ShaderChunk = {
 
 		"#ifdef USE_SHADOWMAP",
 
-			"vec4 transformedPosition;",
-
-			"#ifdef USE_MORPHTARGETS",
-
-				"transformedPosition = modelMatrix * vec4( morphed, 1.0 );",
-
-			"#else",
-			"#ifdef USE_SKINNING",
-
-				"transformedPosition = modelMatrix * skinned;",
-
-			"#else",
-
-				"transformedPosition = modelMatrix * vec4( position, 1.0 );",
-
-			"#endif",
-			"#endif",
-
 			"for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
 
-				"vShadowCoord[ i ] = shadowMatrix[ i ] * transformedPosition;",
+				"vShadowCoord[ i ] = shadowMatrix[ i ] * mPosition;",
 
 			"}",
 
@@ -1582,7 +1718,7 @@ THREE.UniformsUtils = {
 
 		var u, p, tmp, merged = {};
 
-		for ( u = 0; u < uniforms.length; u++ ) {
+		for ( u = 0; u < uniforms.length; u ++ ) {
 
 			tmp = this.clone( uniforms[ u ] );
 
@@ -1646,13 +1782,13 @@ THREE.UniformsLib = {
 		"diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
 		"opacity" : { type: "f", value: 1.0 },
 
-		"map" : { type: "t", value: 0, texture: null },
+		"map" : { type: "t", value: null },
 		"offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
 
-		"lightMap" : { type: "t", value: 2, texture: null },
-		"specularMap" : { type: "t", value: 3, texture: null },
+		"lightMap" : { type: "t", value: null },
+		"specularMap" : { type: "t", value: null },
 
-		"envMap" : { type: "t", value: 1, texture: null },
+		"envMap" : { type: "t", value: null },
 		"flipEnvMap" : { type: "f", value: -1 },
 		"useRefract" : { type: "i", value: 0 },
 		"reflectivity" : { type: "f", value: 1.0 },
@@ -1665,7 +1801,7 @@ THREE.UniformsLib = {
 
 	bump: {
 
-		"bumpMap" : { type: "t", value: 4, texture: null },
+		"bumpMap" : { type: "t", value: null },
 		"bumpScale" : { type: "f", value: 1 }
 
 	},
@@ -1692,6 +1828,10 @@ THREE.UniformsLib = {
 		"directionalLightDirection" : { type: "fv", value: [] },
 		"directionalLightColor" : { type: "fv", value: [] },
 
+		"hemisphereLightPosition" : { type: "fv", value: [] },
+		"hemisphereLightSkyColor" : { type: "fv", value: [] },
+		"hemisphereLightGroundColor" : { type: "fv", value: [] },
+
 		"pointLightColor" : { type: "fv", value: [] },
 		"pointLightPosition" : { type: "fv", value: [] },
 		"pointLightDistance" : { type: "fv1", value: [] },
@@ -1711,7 +1851,7 @@ THREE.UniformsLib = {
 		"opacity" : { type: "f", value: 1.0 },
 		"size" : { type: "f", value: 1.0 },
 		"scale" : { type: "f", value: 1.0 },
-		"map" : { type: "t", value: 0, texture: null },
+		"map" : { type: "t", value: null },
 
 		"fogDensity" : { type: "f", value: 0.00025 },
 		"fogNear" : { type: "f", value: 1 },
@@ -1722,7 +1862,7 @@ THREE.UniformsLib = {
 
 	shadowmap: {
 
-		"shadowMap": { type: "tv", value: 6, texture: [] },
+		"shadowMap": { type: "tv", value: [] },
 		"shadowMapSize": { type: "v2v", value: [] },
 
 		"shadowBias" : { type: "fv1", value: [] },
@@ -1828,22 +1968,31 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "lightmap_pars_vertex" ],
 			THREE.ShaderChunk[ "envmap_pars_vertex" ],
 			THREE.ShaderChunk[ "color_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
+			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 
 			"void main() {",
 
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-
 				THREE.ShaderChunk[ "map_vertex" ],
 				THREE.ShaderChunk[ "lightmap_vertex" ],
-				THREE.ShaderChunk[ "envmap_vertex" ],
 				THREE.ShaderChunk[ "color_vertex" ],
+
+				"#ifdef USE_ENVMAP",
+
+				THREE.ShaderChunk[ "morphnormal_vertex" ],
 				THREE.ShaderChunk[ "skinbase_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
+				THREE.ShaderChunk[ "skinnormal_vertex" ],
+				THREE.ShaderChunk[ "defaultnormal_vertex" ],
+
+				"#endif",
+
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
+				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "default_vertex" ],
+
+				THREE.ShaderChunk[ "worldpos_vertex" ],
+				THREE.ShaderChunk[ "envmap_vertex" ],
 				THREE.ShaderChunk[ "shadowmap_vertex" ],
 
 			"}"
@@ -1904,6 +2053,8 @@ THREE.ShaderLib = {
 
 		vertexShader: [
 
+			"#define LAMBERT",
+
 			"varying vec3 vLightFront;",
 
 			"#ifdef DOUBLE_SIDED",
@@ -1917,17 +2068,14 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "envmap_pars_vertex" ],
 			THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
 			THREE.ShaderChunk[ "color_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
+			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 
 			"void main() {",
 
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-
 				THREE.ShaderChunk[ "map_vertex" ],
 				THREE.ShaderChunk[ "lightmap_vertex" ],
-				THREE.ShaderChunk[ "envmap_vertex" ],
 				THREE.ShaderChunk[ "color_vertex" ],
 
 				THREE.ShaderChunk[ "morphnormal_vertex" ],
@@ -1935,16 +2083,13 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "skinnormal_vertex" ],
 				THREE.ShaderChunk[ "defaultnormal_vertex" ],
 
-				"#ifndef USE_ENVMAP",
-
-					"vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
-
-				"#endif",
-
-				THREE.ShaderChunk[ "lights_lambert_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
+				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "default_vertex" ],
+
+				THREE.ShaderChunk[ "worldpos_vertex" ],
+				THREE.ShaderChunk[ "envmap_vertex" ],
+				THREE.ShaderChunk[ "lights_lambert_vertex" ],
 				THREE.ShaderChunk[ "shadowmap_vertex" ],
 
 			"}"
@@ -2033,6 +2178,8 @@ THREE.ShaderLib = {
 
 		vertexShader: [
 
+			"#define PHONG",
+
 			"varying vec3 vViewPosition;",
 			"varying vec3 vNormal;",
 
@@ -2041,27 +2188,16 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "envmap_pars_vertex" ],
 			THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
 			THREE.ShaderChunk[ "color_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
+			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 
 			"void main() {",
 
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-
 				THREE.ShaderChunk[ "map_vertex" ],
 				THREE.ShaderChunk[ "lightmap_vertex" ],
-				THREE.ShaderChunk[ "envmap_vertex" ],
 				THREE.ShaderChunk[ "color_vertex" ],
 
-				"#ifndef USE_ENVMAP",
-
-					"vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
-
-				"#endif",
-
-				"vViewPosition = -mvPosition.xyz;",
-
 				THREE.ShaderChunk[ "morphnormal_vertex" ],
 				THREE.ShaderChunk[ "skinbase_vertex" ],
 				THREE.ShaderChunk[ "skinnormal_vertex" ],
@@ -2069,10 +2205,15 @@ THREE.ShaderLib = {
 
 				"vNormal = transformedNormal;",
 
-				THREE.ShaderChunk[ "lights_phong_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
+				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "default_vertex" ],
+
+				"vViewPosition = -mvPosition.xyz;",
+
+				THREE.ShaderChunk[ "worldpos_vertex" ],
+				THREE.ShaderChunk[ "envmap_vertex" ],
+				THREE.ShaderChunk[ "lights_phong_vertex" ],
 				THREE.ShaderChunk[ "shadowmap_vertex" ],
 
 			"}"
@@ -2156,6 +2297,7 @@ THREE.ShaderLib = {
 
 				"gl_Position = projectionMatrix * mvPosition;",
 
+				THREE.ShaderChunk[ "worldpos_vertex" ],
 				THREE.ShaderChunk[ "shadowmap_vertex" ],
 
 			"}"
@@ -2202,16 +2344,14 @@ THREE.ShaderLib = {
 
 		vertexShader: [
 
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
+			THREE.ShaderChunk[ "skinning_pars_vertex" ],
 
 			"void main() {",
 
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-
 				THREE.ShaderChunk[ "skinbase_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
+				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "default_vertex" ],
 
 			"}"

+ 1 - 0
src/renderers/renderables/RenderableFace3.js

@@ -13,6 +13,7 @@ THREE.RenderableFace3 = function () {
 
 	this.normalWorld = new THREE.Vector3();
 	this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
+	this.vertexNormalsLength = 0;
 
 	this.material = null;
 	this.uvs = [[]];

+ 1 - 0
src/renderers/renderables/RenderableFace4.js

@@ -14,6 +14,7 @@ THREE.RenderableFace4 = function () {
 
 	this.normalWorld = new THREE.Vector3();
 	this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
+	this.vertexNormalsLength = 0;
 
 	this.material = null;
 	this.uvs = [[]];

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