Sfoglia il codice sorgente

Merge remote-tracking branch 'mrdoob/dev' into dev

Conflicts:
	editor/js/Sidebar.Geometry.Modifiers.js
	editor/js/Sidebar.Material.js
Daniel 9 anni fa
parent
commit
193587faf0
100 ha cambiato i file con 7112 aggiunte e 6201 eliminazioni
  1. 172 436
      build/three.js
  2. 275 228
      build/three.min.js
  3. 0 1
      docs/api/cameras/OrthographicCamera.html
  4. 1 2
      docs/api/constants/Materials.html
  5. 7 24
      docs/api/core/BufferGeometry.html
  6. 2 7
      docs/api/core/Face3.html
  7. 16 33
      docs/api/core/Geometry.html
  8. 2 2
      docs/api/core/Object3D.html
  9. 3 3
      docs/api/core/Raycaster.html
  10. 0 59
      docs/api/extras/helpers/VertexTangentsHelper.html
  11. 0 93
      docs/api/lights/AreaLight.html
  12. 1 1
      docs/api/loaders/ColladaLoader.html
  13. 0 8
      docs/api/loaders/Loader.html
  14. 1 1
      docs/api/loaders/MTLLoader.html
  15. 8 14
      docs/api/materials/MeshLambertMaterial.html
  16. 15 15
      docs/api/materials/MeshPhongMaterial.html
  17. 2 2
      docs/api/materials/PointsMaterial.html
  18. 21 46
      docs/api/materials/ShaderMaterial.html
  19. 19 36
      docs/api/math/Matrix3.html
  20. 11 11
      docs/api/math/Matrix4.html
  21. 6 6
      docs/api/objects/Points.html
  22. 0 1
      docs/index.html
  23. 3 6
      docs/list.js
  24. 99 100
      docs/scenes/js/geometry.js
  25. 0 2
      docs/scenes/js/material.js
  26. 4 1
      editor/index.html
  27. 22 0
      editor/js/Loader.js
  28. 30 0
      editor/js/Menubar.Add.js
  29. 4 0
      editor/js/Sidebar.Animation.js
  30. 11 0
      editor/js/Sidebar.Geometry.BufferGeometry.js
  31. 0 18
      editor/js/Sidebar.Geometry.Modifiers.js
  32. 103 0
      editor/js/Sidebar.Geometry.TeapotBufferGeometry.js
  33. 13 0
      editor/js/Sidebar.Geometry.js
  34. 49 2
      editor/js/Sidebar.Material.js
  35. 5 5
      editor/js/Viewport.Info.js
  36. 5 1
      editor/js/Viewport.js
  37. 4 92
      editor/js/libs/tern-threejs/threejs.js
  38. 7 5
      examples/canvas_morphtargets_horse.html
  39. 4 6
      examples/css3d_youtube.html
  40. 17 18
      examples/index.html
  41. 139 0
      examples/js/AnimationClipCreator.js
  42. 0 170
      examples/js/AudioObject.js
  43. 27 146
      examples/js/BlendCharacter.js
  44. 15 6
      examples/js/BlendCharacterGui.js
  45. 187 0
      examples/js/BufferGeometryUtils.js
  46. 1 1
      examples/js/GPUParticleSystem.js
  47. 54 35
      examples/js/MD2Character.js
  48. 2 2
      examples/js/MD2CharacterComplex.js
  49. 1 3
      examples/js/MarchingCubes.js
  50. 70 0
      examples/js/MorphAnimMesh.js
  51. 0 0
      examples/js/MorphAnimation.js
  52. 0 1104
      examples/js/ShaderDeferred.js
  53. 48 59
      examples/js/ShaderSkin.js
  54. 5 5
      examples/js/UCSCharacter.js
  55. 28 15
      examples/js/WaterShader.js
  56. 1 1
      examples/js/controls/OrthographicTrackballControls.js
  57. 59 16
      examples/js/controls/TransformControls.js
  58. 22 23
      examples/js/geometries/DecalGeometry.js
  59. 751 0
      examples/js/geometries/TeapotBufferGeometry.js
  60. 0 0
      examples/js/libs/jszip.min.js
  61. 491 0
      examples/js/loaders/AMFLoader.js
  62. 1 1
      examples/js/loaders/AWDLoader.js
  63. 0 2
      examples/js/loaders/AssimpJSONLoader.js
  64. 1 1
      examples/js/loaders/BabylonLoader.js
  65. 22 2
      examples/js/loaders/BinaryLoader.js
  66. 23 15
      examples/js/loaders/DDSLoader.js
  67. 6 1
      examples/js/loaders/MD2Loader.js
  68. 1 7
      examples/js/loaders/MTLLoader.js
  69. 1 1
      examples/js/loaders/SVGLoader.js
  70. 1 1
      examples/js/loaders/UTF8Loader.js
  71. 1 1
      examples/js/loaders/VTKLoader.js
  72. 0 0
      examples/js/loaders/collada/Animation.js
  73. 0 0
      examples/js/loaders/collada/AnimationHandler.js
  74. 0 0
      examples/js/loaders/collada/KeyFrameAnimation.js
  75. 20 1
      examples/js/loaders/ctm/CTMLoader.js
  76. 1 27
      examples/js/loaders/deprecated/SceneLoader.js
  77. 506 329
      examples/js/loaders/sea3d/SEA3D.js
  78. 11 12
      examples/js/loaders/sea3d/SEA3DDeflate.js
  79. 25 19
      examples/js/loaders/sea3d/SEA3DLZMA.js
  80. 0 13
      examples/js/loaders/sea3d/SEA3DLZMA_LZIP.js
  81. 760 1087
      examples/js/loaders/sea3d/SEA3DLoader.js
  82. 2 2
      examples/js/math/Lut.js
  83. 2 2
      examples/js/renderers/Projector.js
  84. 0 1209
      examples/js/renderers/WebGLDeferredRenderer.js
  85. 0 515
      examples/js/shaders/NormalDisplacementShader.js
  86. 3 0
      examples/misc_animation_keys.html
  87. 13 14
      examples/misc_controls_fly.html
  88. 51 25
      examples/misc_controls_transform.html
  89. 1 0
      examples/models/amf/rook.amf
  90. 0 43
      examples/models/animated/elderlyWalk.js
  91. 121 0
      examples/models/json/blend-animation.json
  92. 2696 0
      examples/models/json/scene-animation.json
  93. BIN
      examples/models/sea3d/flag.sea
  94. BIN
      examples/models/sea3d/flag.tjs.sea
  95. BIN
      examples/models/sea3d/keyframe.tjs.sea
  96. BIN
      examples/models/sea3d/mascot.tjs.sea
  97. BIN
      examples/models/sea3d/morph.tjs.sea
  98. BIN
      examples/models/sea3d/robot.tjs.sea
  99. BIN
      examples/models/sea3d/skin.tjs.sea
  100. BIN
      examples/models/sea3d/sound.tjs.sea

File diff suppressed because it is too large
+ 172 - 436
build/three.js


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


+ 0 - 1
docs/api/cameras/OrthographicCamera.html

@@ -22,7 +22,6 @@
 		<div>[example:webgl_camera camera ]</div>
 		<div>[example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]</div>
 		<div>[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]</div>
-		<div>[example:webgl_materials_normaldisplacementmap materials / normaldisplacementmap ]</div>
 		<div>[example:webgl_postprocessing_advanced postprocessing / advanced ]</div>
 		<div>[example:webgl_postprocessing_dof2 postprocessing / dof2 ]</div>
 		<div>[example:webgl_postprocessing_godrays postprocessing / godrays ]</div>

+ 1 - 2
docs/api/constants/Materials.html

@@ -19,7 +19,6 @@
 
 		<h2>Shading</h2>
 		<div>
-		THREE.NoShading<br />
 		THREE.FlatShading<br />
 		THREE.SmoothShading
 		</div>
@@ -40,7 +39,7 @@
 		THREE.MultiplyBlending<br />
 		THREE.CustomBlending
 		</div>
-	
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/Three.js src/Three.js]

+ 7 - 24
docs/api/core/BufferGeometry.html

@@ -86,11 +86,6 @@
 		Set by [page:.fromGeometry]().
 		</div>
 
-		<h4>[page:BufferAttribute tangent] (itemSize: 3)</h4>
-		<div>
-		Stores the x, y, and z components of the tangent vector of each vertex in this geometry. Set by [page:.computeTangents]().
-		</div>
-
 		<h4>[page:BufferAttribute index] (itemSize: 3)</h4>
 		Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles," and works much the same as it does in [page:Geometry]: each triangle is associated with the index of three vertices. This attribute therefore stores the index of each vertex for each triangular face.
 
@@ -158,11 +153,6 @@
 		Morph vertices match number and order of primary vertices.
 		</div>
 
-		<h3>[property:boolean hasTangents]</h3>
-		<div>
-		True if BufferGeometry has tangents. Set in [page:.computeTangents].
-		</div>
-
 		<h2>Methods</h2>
 
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
@@ -178,7 +168,7 @@
 		<div>
 		Adds a draw call to this geometry; see the [page:BufferGeometry.drawcalls drawcalls] property for details.
 		</div>
-    
+
 		<h3>[method:null clearDrawCalls]( )</h3>
 		<div>
 		Clears all draw calls.
@@ -188,12 +178,12 @@
 		<div>
 		Bakes matrix transform directly into vertex coordinates.
 		</div>
-    
+
 		<h3>[method:null center] ()</h3>
 		<div>
 		Center the geometry based on the bounding box.
 		</div>
-    
+
 		<h3>[method:BufferGeometry rotateX] ( [page:Float radians] )</h3>
 		<div>
 		Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop
@@ -243,13 +233,6 @@
 		Computes vertex normals by averaging face normals.<br />
 		</div>
 
-		<h3>[method:null computeTangents]()</h3>
-		<div>
-		Computes vertex tangents.<br />
-		Based on [link:http://www.terathon.com/code/tangent.html]<br />
-		Geometry must have vertex [page:UV UVs] (layer 0 will be used).
-		</div>
-
 		<h3>[method:null computeBoundingBox]()</h3>
 		<div>
 		Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.<br />
@@ -306,18 +289,18 @@
 		<div>
 		Returns a raw object representation of the BufferGeometry.
 		</div>
-		
+
 		<h3>[method:BufferGeometry clone]()</h3>
 		<div>
 		Creates a clone of this BufferGeometry.
 		</div>
-		
+
 		<h3>[method:BufferGeometry copy]( [page:BufferGeometry bufferGeometry] )</h3>
 		<div>
 		Copies another BufferGeometry to this BufferGeometry.
 		</div>
-		
-		
+
+
 
 		<h2>Source</h2>
 

+ 2 - 7
docs/api/core/Face3.html

@@ -71,11 +71,6 @@
 		Array of 3 vertex colors.
 		</div>
 
-		<h3>[property:Array vertexTangents]</h3>
-		<div>
-		Array of 3 vertex tangents.
-		</div>
-
 
 		<h3>[property:Integer materialIndex]</h3>
 		<div>
@@ -88,8 +83,8 @@
 		<div>
 		Creates a new clone of the Face3 object.
 		</div>
-		
-		
+
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 16 - 33
docs/api/core/Geometry.html

@@ -62,7 +62,7 @@
 		<h3>[property:Array colors]</h3>
 		<div>
 		Array of vertex [page:Color colors], matching number and order of vertices.<br />
-		Used in [page:PointCloud] and [page:Line].<br />
+		Used in [page:Points] and [page:Line].<br />
 		[page:Mesh Meshes] use per-face-use-of-vertex colors embedded directly in faces.<br />
 		To signal an update in this array, [page:Geometry Geometry.colorsNeedUpdate] needs to be set to true.
 		</div>
@@ -117,10 +117,10 @@
 		// e.g.
 		geometry.skinIndices[15] = new THREE.Vector4(   0,   5,   9, 0 );
 		geometry.skinWeights[15] = new THREE.Vector4( 0.2, 0.5, 0.3, 0 );
-		
+
 		// corresponds with the following vertex
 		geometry.vertices[15];
-		
+
 		// these bones will be used like so:
 		skeleton.bones[0]; // weight of 0.2
 		skeleton.bones[5]; // weight of 0.5
@@ -141,48 +141,38 @@
 		<code>{ radius: float }</code>
 		</div>
 
-		<h3>[property:Boolean hasTangents]</h3>
-		<div>
-		True if geometry has tangents. Set in [page:Geometry Geometry.computeTangents].
-		</div>
-
 		<h3>[property:Boolean dynamic]</h3>
 		<div>
 		Set to *true* if attribute buffers will need to change in runtime (using "dirty" flags).<br/>
 		Unless set to true internal typed arrays corresponding to buffers will be deleted once sent to GPU.<br/>
 		Defaults to true.
 		</div>
-		
+
 		<h3>[property:Boolean verticesNeedUpdate]</h3>
 		<div>
 		Set to *true* if the vertices array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean elementsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the faces array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean uvsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the uvs array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean normalsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the normals array has been updated.
 		</div>
-		
-		<h3>[property:Boolean tangentsNeedUpdate]</h3>
-		<div>
-		Set to *true* if the tangents in the faces has been updated.
-		</div>
-		
+
 		<h3>[property:Boolean colorsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the colors array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean lineDistancesNeedUpdate]</h3>
 		<div>
 		Set to *true* if the linedistances array has been updated.
@@ -193,10 +183,10 @@
 		An array containing distances between vertices for Line geometries.
 		This is required for LinePieces/LineDashedMaterial to render correctly.
 		Line distances can also be generated with computeLineDistances.
-		</div> 
+		</div>
 
 		<h2>Methods</h2>
-		
+
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
 
 		<h3>[method:null applyMatrix]( [page:Matrix4 matrix] )</h3>
@@ -208,7 +198,7 @@
 		<div>
 		Center the geometry based on the bounding box.
 		</div>
-    
+
 		<h3>[method:Geometry rotateX] ( [page:Float radians] )</h3>
 		<div>
 		Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop
@@ -264,13 +254,6 @@
 		Computes morph normals.
 		</div>
 
-		<h3>[method:null computeTangents]()</h3>
-		<div>
-		Computes vertex tangents.<br />
-		Based on [link:http://www.terathon.com/code/tangent.html]<br />
-		Geometry must have vertex [page:UV UVs] (layer 0 will be used).
-		</div>
-
 		<h3>[method:null computeBoundingBox]()</h3>
 		<div>
 		Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.
@@ -280,7 +263,7 @@
 		<div>
 		Computes bounding sphere of the geometry, updating [page:Geometry Geometry.boundingSphere] attribute.
 		</div>
-		
+
 		<div>Neither bounding boxes or bounding spheres are computed by default. They need to be explicitly computed, otherwise they are *null*.</div>
 
 		<h3>[method:null merge]( [page:Geometry geometry], [page:Matrix4 matrix], [page:Integer materialIndexOffset] )</h3>
@@ -297,16 +280,16 @@
 		Normalize the geometry. <br />
 		Make the geometry centered and has a bounding sphere whose raidus equals to 1.0.
 		</div>
-		
+
 		<h3>[method:Geometry clone]()</h3>
 		<div>
 		Creates a new clone of the Geometry.
 		</div>
-		
+
 		<h3>[method:null dispose]()</h3>
 		<div>
 		Removes The object from memory. <br />
-		Don't forget to call this method when you remove a geometry because it can cause memory leaks. 
+		Don't forget to call this method when you remove a geometry because it can cause memory leaks.
 		</div>
 
 		<h3>[method:null computeLineDistances]()</h3>

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

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -300,7 +300,7 @@
 
 		<h3>[method:Array raycast]([page:Raycaster raycaster], [page:Array intersects])</h3>
 		<div>
-		Abstract method to get intersections between a casted ray and this object. Subclasses such as [page:Mesh], [page:Line], and [page:PointCloud] implement this method in order to participate in raycasting.
+		Abstract method to get intersections between a casted ray and this object. Subclasses such as [page:Mesh], [page:Line], and [page:Points] implement this method in order to participate in raycasting.
 		</div>
 
 		<h2>Source</h2>

+ 3 - 3
docs/api/core/Raycaster.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -56,7 +56,7 @@
 			[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera], 
 			[example:webgl_interactive_buffergeometry Raycasting to a Mesh with BufferGeometry], 
 			[example:webgl_interactive_lines Raycasting to a Line], 
-			[example:webgl_interactive_raycasting_pointcloud Raycasting to a PointCloud], 
+			[example:webgl_interactive_raycasting_pointcloud Raycasting to a Points], 
 			[example:webgl_geometry_terrain_raycast Terrain raycasting], 
 			[example:webgl_octree_raycasting Raycasting using an octree],
 			[example:webgl_interactive_voxelpainter Raycasting to paint voxels]</div>
@@ -149,7 +149,7 @@
         When intersecting a [page:Mesh] with a [page:BufferGeometry], the *faceIndex* will be *undefined*, and *indices* will be set; when intersecting a [page:Mesh] with a [page:Geometry], *indices* will be *undefined*. 
         </p>
 		<p>
-		*Raycaster* delegates to the [page:Object3D.raycast raycast] method of the passed object, when evaluating whether the ray intersects the object or not. This allows [page:Mesh meshes] to respond differently to ray casting than [page:Line lines] and [page:PointCloud pointclouds].
+		*Raycaster* delegates to the [page:Object3D.raycast raycast] method of the passed object, when evaluating whether the ray intersects the object or not. This allows [page:Mesh meshes] to respond differently to ray casting than [page:Line lines] and [page:Points pointclouds].
 		</p>
 		<p>
 		*Note* that for meshes, faces must be pointed towards the origin of the [page:.ray ray] in order to be detected; intersections of the ray passing through the back of a face will not be detected. To raycast against both faces of an object, you'll want to set the [page:Mesh.material material]'s [page:Material.side side] property to *THREE.DoubleSide*.  

+ 0 - 59
docs/api/extras/helpers/VertexTangentsHelper.html

@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:Line] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">Renders [page:ArrowHelper arrows] to visualize an object's vertex tangent vectors. Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or have been computed using [page:Geometry.computeTangents computeTangents]. </div>
-
-		<h2>Example</h2>
-
-		<code>
-		geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 );
-		material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
-		object = new THREE.Mesh( geometry, material );
-
-		edges = new THREE.VertexTangentsHelper( object, 2, 0x00ff00, 1 );
-
-		scene.add( object );
-		scene.add( edges );
-		</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Object3D object], [page:Number size], [page:Color color], [page:Number linewidth] )</h3>
-		<div>object -- object for which to render vertex tangents
-		size -- size (length) of the arrows
-		color -- color of the arrows
-		linewidth -- width of the arrow lines
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>[property:Object3D object]</h3>
-		<div>
-		The attached object
-		</div>
-
-
-		<h2>Methods</h2>
-
-
-		<h3>[method:null update]()</h3>
-		<div>Updates the vertex tangent preview arrows based on the new position and tangents of the object.</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 93
docs/api/lights/AreaLight.html

@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-        [page:Object3D] &rarr; [page:Light] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">This illuminates the scene from a complete surface. This light only works in the [page:WebGLDeferredRenderer deferredrenderer]. </div>
-
-
-		<h2>Example</h2>
-		<h2>Example</h2>
-
-		<div>[example:webgldeferred_arealights arealights ]</div>
-
-		<code>areaLight1 = new THREE.AreaLight( 0xffffff, 1 );
-areaLight1.position.set( 0.0001, 10.0001, -18.5001 );
-areaLight1.rotation.set( -0.74719, 0.0001, 0.0001 );
-areaLight1.width = 10;
-areaLight1.height = 1;
-
-scene.add( areaLight1 );</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Integer hex], [page:Float intensity])</h3>
-		<div>
-		[page:Integer hex] — Numeric value of the RGB component of the color.<br />
-		[page:Float intensity] — Numeric value of the light's strength/intensity.
-		</div>
-		<div>
-		This creates a arealight with color.
-		</div>
-
-
-		<h2>Properties</h2>
-
-
-
-		<h3>[property:Vector3 right]</h3>
-		<div>
-		Sets or gets an unit vector that indicates the right side of the light. This is calculated in local space.
-		</div>
-
-		<h3>[property:Vector3 normal]</h3>
-		<div>
-		Sets or gets an unit vectorSets or gets an unit vector that indicates the right side of the light. This is calculated in local space.
-		</div>
-
-		<h3>[property:number height]</h3>
-		<div>
-		Sets or gets the height of the illuminating plane.
-		</div>
-
-		<h3>[property:number width]</h3>
-		<div>
-		Sets or gets the width of the illuminating plane.
-		</div>
-
-		<h3>[property:Float intensity]</h3>
-		<div>
-		Light's intensity.<br />
-		Default — *1.0*.
-		</div>
-
-		<h3>[property:number constantAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in constant space. This is independant of the distance of the light.
-		</div>
-
-		<h3>[property:number linearAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in linear space. This increases the attenuation linearly with the distance from the light.
-		</div>
-
-		<h3>[property:number quadraticAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in quadratic space. This increases the attenuation quadraticly with the distance from the light.
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 1 - 1
docs/api/loaders/ColladaLoader.html

@@ -67,7 +67,7 @@
 		</div>
 		<div>
 		Set the .[page:Integer shading] property on the resource's materials.<br />
-		Options are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading].
+		Options are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading].
 		</div>
 
 		<h3>[method:null applySkin]( [page:Geometry geometry], [page:Object instanceCtrl], [page:Integer frame] )</h3>

+ 0 - 8
docs/api/loaders/Loader.html

@@ -43,14 +43,6 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Boolean needsTangents]( [page:Array materials] )</h3>
-		<div>
-		[page:Array materials] — an array of [page:Material]
-		</div>
-		<div>
-		Checks if the loaded object needs tangents based on its materials.
-		</div>
-
 		<h3>[method:Material createMaterial]( [page:object m], [page:string texturePath] )</h3>
 		<div>
 		[page:Object m] — The parameters to create the material. <br />

+ 1 - 1
docs/api/loaders/MTLLoader.html

@@ -1,4 +1,4 @@
-<!D]OCTYPE html>
+<!DOCTYPE html>
 <html lang="en">
 	<head>
 		<meta charset="utf-8" />

+ 8 - 14
docs/api/materials/MeshLambertMaterial.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A material for non-shiny (Lambertian) surfaces, evaluated per vertex.</div>
-		
+
 		<iframe src='scenes/material-browser.html#MeshLambertMaterial'></iframe>
 
 		<h2>Constructor</h2>
@@ -30,7 +30,6 @@
 		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is false.<br />
-		shading — How the triangles of a curved surface are rendered. Default is [page:Materials THREE.SmoothShading].<br/>
 		wireframe — Render geometry as wireframe. Default is false (i.e. render as smooth shaded).<br/>
 		wireframeLinewidth — Controls wireframe thickness. Default is 1.<br/>
 		wireframeLinecap — Define appearance of line ends. Default is 'round'.<br />
@@ -68,12 +67,12 @@
 		<div>Set env map. Default is null.</div>
 
 		<h3>[property:Integer combine]</h3>
-		<div>How to combine the result of the surface's color with the environment map, if any.</div> 
-		 
+		<div>How to combine the result of the surface's color with the environment map, if any.</div>
+
 		<div>Options are [page:Textures THREE.Multiply] (default), [page:Textures THREE.MixOperation], [page:Textures THREE.AddOperation]. If mix is chosen, the reflectivity is used to blend between the two colors.</div>
-		 
+
 		<h3>[property:Float reflectivity]</h3>
-		<div>How much the environment map affects the surface; also see "combine".</div> 
+		<div>How much the environment map affects the surface; also see "combine".</div>
 
 		<h3>[property:Float refractionRatio]</h3>
 		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
@@ -82,14 +81,9 @@
 		<div>Define whether the material color is affected by global fog settings. Default is *true*.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
 
-		<h3>[property:Integer shading]</h3>
-		<div>How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.</div>
-
-		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading].</div>
-		
 		<h3>[property:Boolean wireframe]</h3>
 		<div>Whether the triangles' edges are displayed instead of surfaces. Default is *false*.</div>
-		
+
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<div>Line thickness for wireframe mode. Default is *1.0*.</div>
 		<div>Due to limitations in the <a href="https://code.google.com/p/angleproject/" target="_blank">ANGLE layer</a>, on Windows platforms linewidth will always be 1 regardless of the set value.</div>
@@ -108,9 +102,9 @@
 
 		<h3>[property:Boolean skinning]</h3>
 		<div>Define whether the material uses skinning. Default is *false*.</div>
-	
+
 		<h3>[property:Boolean morphTargets]</h3>
-		<div>Define whether the material uses morphTargets. Default is *false*.</div>	
+		<div>Define whether the material uses morphTargets. Default is *false*.</div>
 
 		<h3>[property:boolean morphNormals]</h3>
 		<div>

+ 15 - 15
docs/api/materials/MeshPhongMaterial.html

@@ -45,7 +45,7 @@
 		<div>
 		Example:<br>
 		materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) );
-	
+
 		</div>
 
 
@@ -75,7 +75,7 @@
 			If set to true the shader multiplies the specular highlight by the underlying color of the object, making
 			it appear to be more metal-like and darker. If set to false the specular highlight is added ontop of the
 			underlying colors.
-		</div> 
+		</div>
 
 		<h3>[property:Texture map]</h3>
 		<div>Set color texture map. Default is null. The texture map color is modulated by the diffuse color.</div>
@@ -95,7 +95,7 @@
 			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
 			be ignored.
 		</div>
-		
+
 		<h3>[property:Float bumpScale]</h3>
 		<div>
 			How much the bump map affects the material. Typical ranges are 0-1. Default is 1.
@@ -106,11 +106,11 @@
 			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
 			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
 		</div>
-		
+
 		<h3>[property:Vector2 normalScale]</h3>
 		<div>
 			How much the normal map affects the material. Typical ranges are 0-1. Default is (1,1).
-		</div> 
+		</div>
 
 		<h3>[property:Texture specularMap]</h3>
 		<div>The specular map value affects both how much the specular surface highlight contributes and how much of the environment map affects the surface. Default is null.</div>
@@ -121,14 +121,14 @@
 
 		<h3>[property:TextureCube envMap]</h3>
 		<div>Set env map. Default is null.</div>
-		
+
 		<h3>[property:Integer combine]</h3>
-		<div>How to combine the result of the surface's color with the environment map, if any.</div> 
-		 
+		<div>How to combine the result of the surface's color with the environment map, if any.</div>
+
 		<div>Options are [page:Textures THREE.MultiplyOperation] (default), [page:Textures THREE.MixOperation], [page:Textures THREE.AddOperation]. If mix is chosen, the reflectivity is used to blend between the two colors.</div>
-		 
+
 		<h3>[property:Float reflectivity]</h3>
-		<div>How much the environment map affects the surface; also see "combine".</div> 
+		<div>How much the environment map affects the surface; also see "combine".</div>
 
 		<h3>[property:Float refractionRatio]</h3>
 		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
@@ -140,11 +140,11 @@
 		<h3>[property:Integer shading]</h3>
 		<div>How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.</div>
 
-		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading].</div>
-		
+		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading].</div>
+
 		<h3>[property:Boolean wireframe]</h3>
 		<div>Whether the triangles' edges are displayed instead of surfaces. Default is *false*.</div>
-		
+
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<div>Line thickness for wireframe mode. Default is *1.0*.</div>
 		<div>Due to limitations in the <a href="https://code.google.com/p/angleproject/" target="_blank">ANGLE layer</a>, on Windows platforms linewidth will always be 1 regardless of the set value.</div>
@@ -163,9 +163,9 @@
 
 		<h3>[property:Boolean skinning]</h3>
 		<div>Define whether the material uses skinning. Default is *false*.</div>
-	
+
 		<h3>[property:Boolean morphTargets]</h3>
-		<div>Define whether the material uses morphTargets. Default is *false*.</div>	
+		<div>Define whether the material uses morphTargets. Default is *false*.</div>
 
 		<h3>[property:boolean morphNormals]</h3>
 		<div>

+ 2 - 2
docs/api/materials/PointCloudMaterial.html → docs/api/materials/PointsMaterial.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -12,7 +12,7 @@
 
 		<h1>[name]</h1>
 
-		<div class="desc">The default material used by [page:PointCloud particle] systems.</div>
+		<div class="desc">The default material used by [page:Points particle] systems.</div>
 
 
 		<h2>Constructor</h2>

+ 21 - 46
docs/api/materials/ShaderMaterial.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -16,9 +16,13 @@
 		<ul>
 			<li>implement an effect not included with any of the built-in [page:Material materials]</li>
 			<li>combine many objects into a single [page:Geometry] or [page:BufferGeometry] in order to improve performance</li>
-			<li>associate custom data with individual vertices ("custom attributes")</li>
 		</ul>
-		Note that a ShaderMaterial will only be rendered properly by [page:WebGLRenderer], since the GLSL code in the vertexShader and fragmentShader properties must be compiled and run on the GPU using WebGL.
+		There are the following notes to bear in mind when using a *ShaderMaterial*:
+
+		<ul>
+			<li>A *ShaderMaterial* will only be rendered properly by [page:WebGLRenderer], since the GLSL code in the *vertexShader* and *fragmentShader* properties must be compiled and run on the GPU using WebGL.</li>
+			<li>As of THREE r72, directly assigning attributes in a *ShaderMaterial* is no longer supported. A [page:BufferGeometry] instance (instead of a [page:Geometry] instance) must be used instead, using [page:BufferAttribute] instances to define custom attributes.</li>
+		</ul>
 		</div>
 
 		<h3>Example</h3>
@@ -67,66 +71,51 @@
 		</p>
 
 		<h3>Custom attributes and uniforms</h3>
-		Custom attributes and uniforms must be declared both in your GLSL shader code (within *vertexShader* and/or *fragmentShader*), <emph>and</emph> in the *attributes* and *uniforms* properties of your ShaderMaterial. The declaration in the material is necessary to ensure [page:WebGLRenderer] passes your attribute/uniform data in a buffer to the GPU when the shader is run. Note that *varying*s only need to be declared within the shader code (not within the material).
+		<p>Both custom attributes and uniforms must be declared in your GLSL shader code (within *vertexShader* and/or *fragmentShader*). Custom uniforms must be defined in <emph>both</emph> the *uniforms* property of your *ShaderMaterial*, whereas any custom attributes must be defined via [page:BufferAttribute] instances. Note that *varying*s only need to be declared within the shader code (not within the material).
 		</p>
-		<p>
-		To declare a custom attribute, use the *attributes* property of the material:
-		<code>
-		attributes: {
-			vertexOpacity: { type: 'f', value: [] }
-		}
-		</code>
-		Each attribute must have a *type* property and a *value* property.
+
+		<p>To declare a custom attribute, please reference the [page:BufferGeometry] page for an overview, and the [page:BufferAttribute] page for a detailed look at the *BufferAttribute* API.</p>
+		<p>When creating your attributes, each typed array that you create to hold your attribute's data must be a multiple of your data type's size. For example, if your attribute is a [page:Vector3 THREE.Vector3] type, and you have 3000 vertices in your [page:BufferGeometry], your typed array value must be created with a length of 3000 * 3, or 9000 (one value per-component). A table of each data type's size is shown below for reference:</p>
+
 		<table>
-			<caption><a id="attribute-types">Attribute types</a></caption>
+			<caption><a id="attribute-sizes">Attribute sizes</a></caption>
 			<thead>
 				<tr>
-					<th>Attribute *type* string</th>
 					<th>GLSL type</th>
 					<th>JavaScript type</th>
+					<th>Size</th>
 				</tr>
 			</thead>
 			<tbody>
 				<tr>
-					<td><code>'f'</code></td>
 					<td>float</td>
 					<td>[page:Number]</td>
+					<td>1</td>
 				</tr>
 				<tr>
-					<td><code>'v2'</code></td>
 					<td>vec2</td>
 					<td>[page:Vector2 THREE.Vector2]</td>
+					<td>2</td>
 				</tr>
 				<tr>
-					<td><code>'v3'</code></td>
 					<td>vec3</td>
 					<td>[page:Vector3 THREE.Vector3]</td>
+					<td>3</td>
 				</tr>
 				<tr>
-					<td><code>'c'</code></td>
 					<td>vec3</td>
 					<td>[page:Color THREE.Color]</td>
+					<td>3</td>
 				</tr>
 				<tr>
-					<td><code>'v4'</code></td>
 					<td>vec4</td>
 					<td>[page:Vector4 THREE.Vector4]</td>
+					<td>4</td>
 				</tr>
 			</tbody>
 		</table>
-		The way attribute data is stored depends on whether you're using [page:BufferGeometry] or [page:Geometry]:
-		<ul>
-			<li>When using [page:Geometry], attribute data is stored directly on the <emph>material</emph>, using the attribute's *value* array; each element of *value* should correspond to one vertex. To update an attribute, set the *needsUpdate* flag to true on the material attribute:
-			<code>
-			material.attributes.vertexOpacity.needsUpdate = true;
-			</code>
-			</li>
-			<li>When using [page:BufferGeometry], attribute data is stored within a [page:BufferAttribute] on the geometry itself, and the *value* within the material is ignored. To update an attribute, set the *needsUpdate* flag to true on the [page:BufferAttribute] of the geometry:
-			<code>
-			geometry.attributes.vertexOpacity.needsUpdate = true;
-			</code>
-			See [page:BufferGeometry] for details.</li>
-		</ul>
+
+		Note that attribute buffers are <emph>not</emph> refreshed automatically when their values change. To update custom attributes, set the *needsUpdate* flag to true on the [page:BufferAttribute] of the geometry (see [page:BufferGeometry] for further details).
 		</p>
 
 		<p>
@@ -232,20 +221,6 @@
 		where *type* is a <a href="#uniform-types">uniform type string</a>, and *value* is the value of the uniform. Names must match the name of the uniform, as defined in the GLSL code. Note that uniforms are refreshed on every frame, so updating the value of the uniform will immediately update the value available to the GLSL code.
 		</div>
 
-		<h3>[property:Object attributes]</h3>
-		<div>
-		<p>
-		Object specifying the custom attributes to be passed to the shader code; keys are attribute names, values are definitions of the form
-		<code>
-		{ type: 'f', value: [1.0, 0.5, 2.0, ...] }
-		</code>
-		where *type* is an <a href="#attribute-types">attribute type string</a>, and *value* is an array containing an attribute value for each vertex in the geometry (or *undefined* if using [page:BufferGeometry]). Names must match the name of the attribute, as defined in the GLSL code.
-		</p>
-		<p>
-		Note that attribute buffers are <emph>not</emph> refreshed automatically when their values change; if using [page:Geometry], set <code>needsUpdate = true</code> on the attribute definition. If using [page:BufferGeometry], set <code>needsUpdate = true</code> on the [page:BufferAttribute].
-		</p>
-		</div>
-
 		<h3>[property:Object defines]</h3>
 		<div>
 		Defines custom constants using *#define* directives within the GLSL code for both the vertex shader and the fragment shader; each key/value pair yields another directive:

+ 19 - 36
docs/api/math/Matrix3.html

@@ -16,26 +16,9 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33])</h3>
+		<h3>[name]()</h3>
 		<div>
-		n11 -- [page:Float] <br />
-		n12 -- [page:Float] <br />
-		n13 -- [page:Float] <br />
-		n21 -- [page:Float] <br />
-		n22 -- [page:Float] <br />
-		n23 -- [page:Float] <br />
-		n31 -- [page:Float] <br />
-		n32 -- [page:Float] <br />
-		n33 -- [page:Float]
-		</div>
-		<div>
-		Initialize the 3x3 matrix with a row-major sequence of values.<br/><br/>
-		
-		n11, n12, n13,<br/>
-		n21, n22, n23,<br/>
-		n31, n32, n33<br/><br/>
-		
-		If no values are sent the matrix will be initialized as an identity matrix.
+		Creates and initializes the 3x3 matrix to the identity matrix.
 		</div>
 
 
@@ -44,7 +27,7 @@
 
 		<h3>[property:Float32Array elements]</h3>
 		<div>
-		Float32Array with column-major matrix values.
+		A column-major list of matrix values.
 		</div>
 
 
@@ -60,13 +43,13 @@
 		array -- [page:Array] <br />
 		</div>
 		<div>
-		Transposes this matrix into the supplied array, and returns itself.
+		Transposes this matrix into the supplied array, and returns itself unchanged.
 		</div>
 
 
 		<h3>[method:Float determinant]()</h3>
 		<div>
-		Returns the matrix's determinant.
+		Computes and returns the determinant of this matrix.
 		</div>
 
 		<h3>[method:Matrix3 set]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33]) [page:Matrix3 this]</h3>
@@ -82,15 +65,15 @@
 		n33 -- [page:Float]
 		</div>
 		<div>
-		Set the 3x3 matrix values to the given row-major sequence of values.
+		Sets the 3x3 matrix values to the given row-major sequence of values.
 		</div>
 
-		<h3>[method:Matrix3 multiplyScalar]([page:Float scalar]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 multiplyScalar]([page:Float s]) [page:Matrix3 this]</h3>
 		<div>
 		scalar -- [page:Float]
 		</div>
 		<div>
-		Multiply every component of the matrix by a scalar value.
+		Multiplies every component of the matrix by the scalar value *s*.
 		</div>
 
 		<h3>[method:Array applyToVector3Array]([page:Array array])</h3>
@@ -98,42 +81,42 @@
 		array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
 		</div>
 		<div>
-		Multiply (apply) this matrix to every vector3 in the array.
+		Multiplies (applies) this matrix to every vector3 in the array.
 		</div>
 
-		<h3>[method:Matrix3 getNormalMatrix]([page:Matrix4 matrix4]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 getNormalMatrix]([page:Matrix4 m]) [page:Matrix3 this]</h3>
 		<div>
-		matrix4 -- [page:Matrix4]
+		m -- [page:Matrix4]
 		</div>
 		<div>
-		Set this matrix as the normal matrix of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix.
+		Sets this matrix as the normal matrix (upper left 3x3)of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix *m*.
 		</div>
 
-		<h3>[method:Matrix3 getInverse]([page:Matrix4 matrix4], [page:Boolean throwOnInvertible]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 getInverse]([page:Matrix4 m], [page:Boolean throwOnInvertible]) [page:Matrix3 this]</h3>
 		<div>
-		matrix4 -- [page:Matrix4] <br />
+		m -- [page:Matrix4]<br />
 		throwOnInvertible -- [Page:Boolean] If true, throw an error if the matrix is invertible.
 		</div>
 		<div>
 		Set this matrix to the inverse of the passed matrix.
 		</div>
 
-		<h3>[method:Matrix3 copy]([page:Matrix3 matrix]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 copy]([page:Matrix3 m]) [page:Matrix3 this]</h3>
 		<div>
-		matrix -- [page:Matrix3]
+		m -- [page:Matrix4]
 		</div>
 		<div>
-		Copy the values of the passed matrix.
+		Copies the values of matrix *m* into this matrix.
 		</div>
 
 		<h3>[method:Matrix3 clone]()</h3>
 		<div>
-		Create a copy of the matrix.
+		Creates a copy of this matrix.
 		</div>
 
 		<h3>[method:Matrix3 identity]() [page:Matrix3 this]</h3>
 		<div>
-		Set as an identity matrix.<br/><br/>
+		Resets this matrix to identity.<br/><br/>
 		
 		1, 0, 0<br/>
 		0, 1, 0<br/>

+ 11 - 11
docs/api/math/Matrix4.html

@@ -39,10 +39,10 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]( [page:Float n11], [page:Float n12], [page:Float n13], [page:Float n14], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n24], [page:Float n31], [page:Float n32], [page:Float n33], [page:Float n34], [page:Float n41], [page:Float n42], [page:Float n43], [page:Float n44] )</h3>
+		<h3>[name]()</h3>
 
 		<div>
-		Initialises the matrix with the supplied row-major values n11..n44, or just creates an identity matrix if no values are passed.
+		Creates and initializes the matrix to the identity matrix.
 		</div>
 
 		<h2>Properties</h2>
@@ -64,7 +64,7 @@
 
 		<h3>[method:Matrix4 copy]( [page:Matrix4 m] ) [page:Matrix4 this]</h3>
 		<div>
-		Copies a matrix *m* into this matrix.
+		Copies the values of matrix *m* into this matrix.
 		</div>
 
 		<h3>[method:Matrix4 copyPosition]( [page:Matrix4 m] ) [page:Matrix4 this]</h3>
@@ -72,12 +72,12 @@
 		Copies the translation component of the supplied matrix *m* into this matrix translation component.
 		</div>
 
-		<h3>[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
+		<h3>[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
 		<div>
 		Creates the basis matrix consisting of the three provided axis vectors.  Returns the current matrix.
 		</div>
 
-		<h3>[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
+		<h3>[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
 		<div>
 		Extracts basis of into the three axis vectors provided.  Returns the current matrix.
 		</div>
@@ -110,12 +110,12 @@
 
 		<h3>[method:Matrix4 multiplyScalar]( [page:Float s] ) [page:Matrix4 this]</h3>
 		<div>
-		Multiplies this matrix by *s*.
+		Multiplies every component of the matrix by a scalar value *s*.
 		</div>
 
 		<h3>[method:Float determinant]()</h3>
 		<div>
-		Computes determinant of this matrix.<br />
+		Computes and returns the determinant of this matrix.<br />
 		Based on [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm]
 		</div>
 
@@ -142,7 +142,7 @@
 
 		<h3>[method:Matrix4 makeRotationFromEuler]( [page:Euler euler] ) [page:Matrix4 this]</h3>
 		<div>
-		euler — Rotation vector followed by order of rotations. Eg. "XYZ".
+		euler — Rotation vector followed by order of rotations, e.g., "XYZ".
 		</div>
 		<div>
 		Sets the rotation submatrix of this matrix to the rotation specified by Euler angles, the rest of the matrix is identity.<br />
@@ -230,7 +230,7 @@
 
 		<h3>[method:Matrix4 clone]()</h3>
 		<div>
-		Clones this matrix.
+		Creates a copy of this matrix.
 		</div>
 
 		<h3>[method:Array applyToVector3Array]([page:Array a])</h3>
@@ -238,12 +238,12 @@
 		array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
 		</div>
 		<div>
-		Multiply (apply) this matrix to every vector3 in the array.
+		Multiplies (applies) this matrix to every vector3 in the array.
 		</div>
 
 		<h3>[method:Float getMaxScaleOnAxis]()</h3>
 		<div>
-		Gets the max scale value of the 3 axes.
+		Gets the maximum scale value of the 3 axes.
 		</div>
 
 		<h2>Source</h2>

+ 6 - 6
docs/api/objects/PointCloud.html → docs/api/objects/Points.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -33,27 +33,27 @@
 
 		<h3>[property:Material material]</h3>
 
-		<div>An instance of [page:Material], defining the object's appearance. Default is a [page:PointCloudMaterial] with randomised colour.</div>
+		<div>An instance of [page:Material], defining the object's appearance. Default is a [page:PointsMaterial] with randomised colour.</div>
 
 
 		<h2>Methods</h2>
 
-		<h3>[method:PointCloud clone]()</h3>
+		<h3>[method:Points clone]()</h3>
 		<div>
 		This creates a clone of the particle system.
 		</div>
 
 		<h3>[method:Array raycast]([page:Raycaster raycaster], [page:Array intersects])</h3>
 		<div>
-		Get intersections between a casted ray and this PointCloud. [page:Raycaster.intersectObject] will call this method.
+		Get intersections between a casted ray and this Points. [page:Raycaster.intersectObject] will call this method.
 		</div>
 
 		<h3>[method:Object3D clone]([page:Object3D object])</h3>
 		<div>
-		object -- (optional) Object3D which needs to be cloned. If undefined, clone method will create a new cloned PointCloud Object.
+		object -- (optional) Object3D which needs to be cloned. If undefined, clone method will create a new cloned Points Object.
 		</div>
 		<div>
-		Clone a PointCloud Object.
+		Clone a Points Object.
 		</div>
 
 		<h2>Source</h2>

+ 0 - 1
docs/index.html

@@ -417,6 +417,5 @@
 			].join('\n'));
 
 		</script>
-		<script src="../build/three.min.js"></script>
 	</body>
 </html>

+ 3 - 6
docs/list.js

@@ -4,7 +4,6 @@ var list = {
 		"Introduction": [
 			[ "Creating a scene", "manual/introduction/Creating-a-scene" ],
 			[ "Matrix transformations", "manual/introduction/Matrix-transformations" ]
-
 		]
 	},
 
@@ -32,12 +31,11 @@ var list = {
 			[ "Face3", "api/core/Face3" ],
 			[ "Geometry", "api/core/Geometry" ],
 			[ "Object3D", "api/core/Object3D" ],
-			[ "Raycaster", "api/core/Raycaster" ],
+			[ "Raycaster", "api/core/Raycaster" ]
 		],
 
 		"Lights": [
 			[ "AmbientLight", "api/lights/AmbientLight" ],
-			[ "AreaLight", "api/lights/AreaLight" ],
 			[ "DirectionalLight", "api/lights/DirectionalLight" ],
 			[ "HemisphereLight", "api/lights/HemisphereLight" ],
 			[ "Light", "api/lights/Light" ],
@@ -78,7 +76,7 @@ var list = {
 			[ "MeshLambertMaterial", "api/materials/MeshLambertMaterial" ],
 			[ "MeshNormalMaterial", "api/materials/MeshNormalMaterial" ],
 			[ "MeshPhongMaterial", "api/materials/MeshPhongMaterial" ],
-			[ "PointCloudMaterial", "api/materials/PointCloudMaterial" ],
+			[ "PointsMaterial", "api/materials/PointsMaterial" ],
 			[ "RawShaderMaterial", "api/materials/RawShaderMaterial" ],
 			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],
 			[ "SpriteCanvasMaterial", "api/materials/SpriteCanvasMaterial" ],
@@ -114,7 +112,7 @@ var list = {
 			[ "LOD", "api/objects/LOD" ],
 			[ "Mesh", "api/objects/Mesh" ],
 			[ "MorphAnimMesh", "api/objects/MorphAnimMesh" ],
-			[ "PointCloud", "api/objects/PointCloud" ],
+			[ "Points", "api/objects/Points" ],
 			[ "SkinnedMesh", "api/objects/SkinnedMesh" ],
 			[ "Skeleton", "api/objects/Skeleton" ],
 			[ "Sprite", "api/objects/Sprite" ]
@@ -231,7 +229,6 @@ var list = {
 			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
 			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ],
 			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ],
-			[ "VertexTangentsHelper", "api/extras/helpers/VertexTangentsHelper" ],
 			[ "WireframeHelper", "api/extras/helpers/WireframeHelper" ]
 		],
 

+ 99 - 100
docs/scenes/js/geometry.js

@@ -24,7 +24,6 @@ var constants = {
 
 	shading : {
 
-		"THREE.NoShading" : THREE.NoShading,
 		"THREE.FlatShading" : THREE.FlatShading,
 		"THREE.SmoothShading" : THREE.SmoothShading
 
@@ -81,13 +80,13 @@ var constants = {
 }
 
 function updateGroupGeometry( mesh, geometry ) {
-	
+
 	mesh.children[0].geometry.dispose();
 	mesh.children[1].geometry.dispose();
-	
+
 	mesh.children[0].geometry = new THREE.WireframeGeometry( geometry );
 	mesh.children[1].geometry = geometry;
-	
+
 	//these do not update nicely together if shared
 }
 
@@ -103,26 +102,26 @@ var guis = {
 			heightSegments : 1,
 			depthSegments : 1
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.BoxGeometry(
 					data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.BoxGeometry');
-		
+
 		folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'depth', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'widthSegments', 1, 10 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'heightSegments', 1, 10 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'depthSegments', 1, 10 ).step(1).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
 
@@ -138,10 +137,10 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : twoPi,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.CylinderGeometry(
 					data.radiusTop,
 					data.radiusBottom,
@@ -153,11 +152,11 @@ var guis = {
 					data.thetaLength
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.CylinderGeometry');
-		
+
 		folder.add( data, 'radiusTop', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'radiusBottom', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 50 ).onChange( generateGeometry );
@@ -166,8 +165,8 @@ var guis = {
 		folder.add( data, 'openEnded' ).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
-		
+
+
 		generateGeometry();
 	},
 
@@ -179,103 +178,103 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : twoPi,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.CircleGeometry(
 					data.radius, data.segments, data.thetaStart, data.thetaLength
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.CircleGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
 		folder.add( data, 'segments', 0, 128 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	DodecahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.DodecahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.DodecahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
-	
+
 	IcosahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.IcosahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.IcosahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
-	
+
 	OctahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.OctahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.OctahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
 
 	PlaneGeometry : function( mesh ) {
@@ -286,24 +285,24 @@ var guis = {
 			widthSegments : 1,
 			heightSegments : 1
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.PlaneGeometry(
 					data.width, data.height, data.widthSegments, data.heightSegments
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.PlaneGeometry');
-		
+
 		folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'widthSegments', 1, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'heightSegments', 1, 30 ).step(1).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
 
@@ -317,29 +316,29 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : twoPi,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.RingGeometry(
 					data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.RingGeometry');
-		
+
 		folder.add( data, 'innerRadius', 0, 30 ).onChange( generateGeometry );
 		folder.add( data, 'outerRadius', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'thetaSegments', 1, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'phiSegments', 1, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	SphereGeometry : function( mesh ) {
 
 		var data = {
@@ -351,19 +350,19 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : Math.PI,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.SphereGeometry(
 					data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.SphereGeometry');
-		
+
 		folder.add( data, 'radius', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'widthSegments', 3, 32 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'heightSegments', 2, 32 ).step(1).onChange( generateGeometry );
@@ -371,36 +370,36 @@ var guis = {
 		folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	TetrahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.TetrahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.TetrahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
-	
+
 	TextGeometry : function( mesh ) {
 
 		var data = {
@@ -415,33 +414,33 @@ var guis = {
 			bevelThickness : 1,
 			bevelSize : 0.5
 		};
-		
+
 		var fonts = [
 			"helvetiker",
 			"optimer",
 			"gentilis",
 			"droid serif"
 		]
-		
+
 		var weights = [
 			"normal", "bold"
 		]
-		
+
 		function generateGeometry() {
-			
+
 			var geometry = new THREE.TextGeometry( data.text, data )
-			
+
 			geometry.center()
-			
+
 			updateGroupGeometry( mesh, geometry );
-			
+
 		}
-		
+
 		//Hide the wireframe
 		mesh.children[0].visible = false;
 
 		var folder = gui.addFolder('THREE.TextGeometry');
-		
+
 		folder.add( data, 'text' ).onChange( generateGeometry );
 		folder.add( data, 'size', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 20 ).onChange( generateGeometry );
@@ -452,10 +451,10 @@ var guis = {
 		folder.add( data, 'bevelEnabled' ).onChange( generateGeometry );
 		folder.add( data, 'bevelThickness', 0.1, 3 ).onChange( generateGeometry );
 		folder.add( data, 'bevelSize', 0.1, 3 ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	TorusGeometry : function( mesh ) {
 
 		var data = {
@@ -465,29 +464,29 @@ var guis = {
 			tubularSegments : 100,
 			arc : twoPi
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.TorusGeometry(
 					data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.TorusGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
 		folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry );
 		folder.add( data, 'radialSegments', 2, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'tubularSegments', 3, 200 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'arc', 0.1, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 
 	},
-	
+
 	TorusKnotGeometry : function( mesh ) {
 
 		var data = {
@@ -499,20 +498,20 @@ var guis = {
 			q : 3,
 			heightScale : 1
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.TorusKnotGeometry(
 					data.radius, data.tube, data.radialSegments, data.tubularSegments,
 					data.p, data.q, data.heightScale
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.TorusGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry )
 		folder.add( data, 'radialSegments', 3, 300 ).step(1).onChange( generateGeometry )
@@ -520,11 +519,11 @@ var guis = {
 		folder.add( data, 'p', 1, 20 ).step(1).onChange( generateGeometry )
 		folder.add( data, 'q', 1, 20 ).step(1).onChange( generateGeometry )
 		folder.add( data, 'heightScale', 1, 20 ).onChange( generateGeometry )
-		
+
 		generateGeometry()
 
 	}
-	
+
 }
 
 function chooseFromHash ( mesh ) {

+ 0 - 2
docs/scenes/js/material.js

@@ -22,7 +22,6 @@ var constants = {
 
 	shading : {
 
-		"THREE.NoShading" : THREE.NoShading,
 		"THREE.FlatShading" : THREE.FlatShading,
 		"THREE.SmoothShading" : THREE.SmoothShading
 
@@ -404,7 +403,6 @@ function guiMeshLambertMaterial ( gui, mesh, material, geometry ) {
 	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
 	folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) );
 
-	folder.add( material, 'shading', constants.shading ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );
 	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );

+ 4 - 1
editor/index.html

@@ -14,6 +14,7 @@
 
 		<script src="../examples/js/controls/EditorControls.js"></script>
 		<script src="../examples/js/controls/TransformControls.js"></script>
+		<script src="../examples/js/loaders/AMFLoader.js"></script>
 		<script src="../examples/js/loaders/AWDLoader.js"></script>
 		<script src="../examples/js/loaders/BabylonLoader.js"></script>
 		<script src="../examples/js/loaders/ColladaLoader.js"></script>
@@ -67,7 +68,7 @@
 		<script src="js/libs/ternjs/doc_comment.js"></script>
 		<script src="js/libs/tern-threejs/threejs.js"></script>
 
-		<script src="js/libs/jszip.min.js"></script>
+		<script src="../examples/js/libs/jszip.min.js"></script>
 		<script src="js/libs/sortable.min.js"></script>
 		<script src="js/libs/signals.min.js"></script>
 		<script src="js/libs/ui.js"></script>
@@ -112,6 +113,8 @@
 		<script src="js/Sidebar.Geometry.SphereGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusKnotGeometry.js"></script>
+		<script src="../examples/js/geometries/TeapotBufferGeometry.js"></script>
+		<script src="js/Sidebar.Geometry.TeapotBufferGeometry.js"></script>
 		<script src="js/Sidebar.Material.js"></script>
 		<script src="js/Sidebar.Script.js"></script>
 		<script src="js/Sidebar.History.js"></script>

+ 22 - 0
editor/js/Loader.js

@@ -7,6 +7,8 @@ var Loader = function ( editor ) {
 	var scope = this;
 	var signals = editor.signals;
 
+	this.texturePath = '';
+
 	this.loadFile = function ( file ) {
 
 		var filename = file.name;
@@ -14,6 +16,22 @@ var Loader = function ( editor ) {
 
 		switch ( extension ) {
 
+			case 'amf':
+
+				var reader = new FileReader();
+				reader.addEventListener( 'load', function ( event ) {
+
+					var loader = new THREE.AMFLoader();
+					var amfobject = loader.parse( event.target.result );
+
+					editor.addObject( amfobject );
+					editor.select( amfobject );
+
+				}, false );
+				reader.readAsArrayBuffer( file );
+
+				break;
+
 			case 'awd':
 
 				var reader = new FileReader();
@@ -386,6 +404,8 @@ var Loader = function ( editor ) {
 		} else if ( data.metadata.type.toLowerCase() === 'geometry' ) {
 
 			var loader = new THREE.JSONLoader();
+			loader.setTexturePath( scope.texturePath );
+
 			var result = loader.parse( data );
 
 			var geometry = result.geometry;
@@ -432,6 +452,8 @@ var Loader = function ( editor ) {
 		} else if ( data.metadata.type.toLowerCase() === 'object' ) {
 
 			var loader = new THREE.ObjectLoader();
+			loader.setTexturePath( scope.texturePath );
+
 			var result = loader.parse( data );
 
 			if ( result instanceof THREE.Scene ) {

+ 30 - 0
editor/js/Menubar.Add.js

@@ -236,6 +236,36 @@ Menubar.Add = function ( editor ) {
 	} );
 	options.add( option );
 
+	/*
+	// Teapot
+
+	var option = new UI.Panel();
+	option.setClass( 'option' );
+	option.setTextContent( 'Teapot' );
+	option.onClick( function () {
+
+		var size = 50;
+		var segments = 10;
+		var bottom = true;
+		var lid = true;
+		var body = true;
+		var fitLid = false;
+		var blinnScale = true;
+
+		var material = new THREE.MeshPhongMaterial();
+		material.side = 2;
+
+		var geometry = new THREE.TeapotBufferGeometry( size, segments, bottom, lid, body, fitLid, blinnScale );
+		var mesh = new THREE.Mesh( geometry, material );
+		mesh.name = 'Teapot ' + ( ++ meshCount );
+
+		editor.addObject( mesh );
+		editor.select( mesh );
+
+	} );
+	options.add( option );
+	*/
+
 	// Sprite
 
 	var option = new UI.Panel();

+ 4 - 0
editor/js/Sidebar.Animation.js

@@ -24,6 +24,8 @@ Sidebar.Animation = function ( editor ) {
 	var animationsRow = new UI.Panel();
 	container.add( animationsRow );
 
+	/*
+
 	var animations = {};
 
 	signals.objectAdded.add( function ( object ) {
@@ -105,6 +107,8 @@ Sidebar.Animation = function ( editor ) {
 
 	} );
 
+	*/
+
 	return container;
 
 }

+ 11 - 0
editor/js/Sidebar.Geometry.BufferGeometry.js

@@ -19,6 +19,17 @@ Sidebar.Geometry.BufferGeometry = function ( editor ) {
 			container.clear();
 			container.setDisplay( 'block' );
 
+			var index = geometry.index;
+
+			if ( index !== null ) {
+
+				var panel = new UI.Panel();
+				panel.add( new UI.Text( 'index' ).setWidth( '90px' ) );
+				panel.add( new UI.Text( ( index.count ).format() ).setFontSize( '12px' ) );
+				container.add( panel );
+
+			}
+
 			var attributes = geometry.attributes;
 
 			for ( var name in attributes ) {

+ 0 - 18
editor/js/Sidebar.Geometry.Modifiers.js

@@ -33,24 +33,6 @@ Sidebar.Geometry.Modifiers = function ( editor, object ) {
 
 	container.add( button );
 
-	// Convert to Geometry/BufferGeometry
-
-	var isBufferGeometry = geometry instanceof THREE.BufferGeometry;
-
-	if ( geometry instanceof THREE.Geometry ) {
-
-		var button = new UI.Button( 'Convert to BufferGeometry' );
-		button.onClick( function () {
-
-			if ( confirm( 'Are you sure?' ) === false ) return;
-
-			editor.execute( new CmdSetGeometry( object, new THREE.BufferGeometry().fromGeometry( object.geometry ) ) );
-
-		} );
-		container.add( button );
-
-	}
-
 	//
 
 	return container;

+ 103 - 0
editor/js/Sidebar.Geometry.TeapotBufferGeometry.js

@@ -0,0 +1,103 @@
+/**
+ * @author tschw
+ */
+
+Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) {
+
+	var container = new UI.Panel();
+
+	var parameters = object.geometry.parameters;
+
+	// size
+
+	var sizeRow = new UI.Panel();
+	var size = new UI.Number( parameters.size ).onChange( update );
+
+	sizeRow.add( new UI.Text( 'Size' ).setWidth( '90px' ) );
+	sizeRow.add( size );
+
+	container.add( sizeRow );
+
+	// segments
+
+	var segmentsRow = new UI.Panel();
+	var segments = new UI.Integer( parameters.segments ).setRange( 1, Infinity ).onChange( update );
+
+	segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) );
+	segmentsRow.add( segments );
+
+	container.add( segmentsRow );
+
+	// bottom
+
+	var bottomRow = new UI.Panel();
+	var bottom = new UI.Checkbox( parameters.bottom ).onChange( update );
+
+	bottomRow.add( new UI.Text( 'Bottom' ).setWidth( '90px' ) );
+	bottomRow.add( bottom );
+
+	container.add( bottomRow );
+
+	// lid
+
+	var lidRow = new UI.Panel();
+	var lid = new UI.Checkbox( parameters.lid ).onChange( update );
+
+	lidRow.add( new UI.Text( 'Lid' ).setWidth( '90px' ) );
+	lidRow.add( lid );
+
+	container.add( lidRow );
+
+	// body
+
+	var bodyRow = new UI.Panel();
+	var body = new UI.Checkbox( parameters.body ).onChange( update );
+
+	bodyRow.add( new UI.Text( 'Body' ).setWidth( '90px' ) );
+	bodyRow.add( body );
+
+	container.add( bodyRow );
+
+	// fitted lid
+
+	var fitLidRow = new UI.Panel();
+	var fitLid = new UI.Checkbox( parameters.fitLid ).onChange( update );
+
+	fitLidRow.add( new UI.Text( 'Fitted Lid' ).setWidth( '90px' ) );
+	fitLidRow.add( fitLid );
+
+	container.add( fitLidRow );
+
+	// blinn-sized
+
+	var blinnRow = new UI.Panel();
+	var blinn = new UI.Checkbox( parameters.blinn ).onChange( update );
+
+	blinnRow.add( new UI.Text( 'Blinn-scaled' ).setWidth( '90px' ) );
+	blinnRow.add( blinn );
+
+	container.add( blinnRow );
+
+	function update() {
+
+		object.geometry.dispose();
+
+		object.geometry = new THREE.TeapotBufferGeometry(
+			size.getValue(),
+			segments.getValue(),
+			bottom.getValue(),
+			lid.getValue(),
+			body.getValue(),
+			fitLid.getValue(),
+			blinn.getValue()
+		);
+
+		object.geometry.computeBoundingSphere();
+
+		signals.geometryChanged.dispatch( object );
+
+	}
+
+	return container;
+
+}

+ 13 - 0
editor/js/Sidebar.Geometry.js

@@ -25,6 +25,7 @@ Sidebar.Geometry = function ( editor ) {
 
 		'Actions': 'Actions',
 		'Center': 'Center',
+		'Convert': 'Convert',
 		'Flatten': 'Flatten'
 
 	} );
@@ -57,6 +58,18 @@ Sidebar.Geometry = function ( editor ) {
 
 				break;
 
+			case 'Convert':
+
+				if ( geometry instanceof THREE.Geometry ) {
+
+					object.geometry = new THREE.BufferGeometry().fromGeometry( geometry );
+
+					signals.geometryChanged.dispatch( object );
+
+				}
+
+				break;
+
 			case 'Flatten':
 
 				var newGeometry = geometry.clone();

+ 49 - 2
editor/js/Sidebar.Material.js

@@ -223,6 +223,20 @@ Sidebar.Material = function ( editor ) {
 
 	container.add( materialNormalMapRow );
 
+	// displacement map
+
+	var materialDisplacementMapRow = new UI.Panel();
+	var materialDisplacementMapEnabled = new UI.Checkbox( false ).onChange( update );
+	var materialDisplacementMap = new UI.Texture().onChange( update );
+	var materialDisplacementScale = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
+
+	materialDisplacementMapRow.add( new UI.Text( 'Displace Map' ).setWidth( '90px' ) );
+	materialDisplacementMapRow.add( materialDisplacementMapEnabled );
+	materialDisplacementMapRow.add( materialDisplacementMap );
+	materialDisplacementMapRow.add( materialDisplacementScale );
+
+	container.add( materialDisplacementMapRow );
+
 	// specular map
 
 	var materialSpecularMapRow = new UI.Panel();
@@ -537,6 +551,24 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			if ( material.displacementMap !== undefined ) {
+
+				var displacementMapEnabled = materialDisplacementMapEnabled.getValue() === true;
+
+				if ( objectHasUvs ) {
+
+					material.displacementMap = displacementMapEnabled ? materialDisplacementMap.getValue() : null;
+					material.displacementScale = materialDisplacementScale.getValue();
+					material.needsUpdate = true;
+
+				} else {
+
+					if ( displacementMapEnabled ) textureWarning = true;
+
+				}
+
+			}
+
 			if ( material.specularMap !== undefined ) {
 
 				var specularMapEnabled = materialSpecularMapEnabled.getValue() === true;
@@ -584,7 +616,7 @@ Sidebar.Material = function ( editor ) {
 
 				if ( objectHasUvs ) {
 
-					var lightMap = specularMapEnabled ? materialLightMap.getValue() : null;
+					var lightMap = lightMapEnabled ? materialLightMap.getValue() : null;
 					if ( material.lightMap !== lightMap ) {
 
 						editor.execute( new CmdSetMaterialMap( currentObject, 'lightMap', lightMap ) );
@@ -721,6 +753,7 @@ Sidebar.Material = function ( editor ) {
 			'alphaMap': materialAlphaMapRow,
 			'bumpMap': materialBumpMapRow,
 			'normalMap': materialNormalMapRow,
+			'displacementMap': materialDisplacementMapRow,
 			'specularMap': materialSpecularMapRow,
 			'envMap': materialEnvMapRow,
 			'lightMap': materialLightMapRow,
@@ -745,7 +778,7 @@ Sidebar.Material = function ( editor ) {
 	};
 
 
-	function refreshUi(resetTextureSelectors) {
+	function refreshUi( resetTextureSelectors ) {
 
 		if ( !currentObject ) return;
 
@@ -851,6 +884,20 @@ Sidebar.Material = function ( editor ) {
 
 		}
 
+		if ( material.displacementMap !== undefined ) {
+
+			materialDisplacementMapEnabled.setValue( material.displacementMap !== null );
+
+			if ( material.displacementMap !== null || resetTextureSelectors ) {
+
+				materialDisplacementMap.setValue( material.displacementMap );
+
+			}
+
+			materialDisplacementScale.setValue( material.displacementScale );
+
+		}
+
 		if ( material.specularMap !== undefined ) {
 
 			materialSpecularMapEnabled.setValue( material.specularMap !== null );

+ 5 - 5
editor/js/Viewport.Info.js

@@ -53,15 +53,15 @@ Viewport.Info = function ( editor ) {
 
 					} else if ( geometry instanceof THREE.BufferGeometry ) {
 
-						vertices += geometry.attributes.position.array.length / 3;
+						if ( geometry.index !== null ) {
 
-						if ( geometry.attributes.index !== undefined ) {
-
-							triangles += geometry.attributes.index.array.length / 3;
+							vertices += geometry.index.count * 3;
+							triangles += geometry.index.count;
 
 						} else {
 
-							triangles += geometry.attributes.position.array.length / 9;
+							vertices += geometry.attributes.position.count;
+							triangles += geometry.attributes.position.count / 3;
 
 						}
 

+ 5 - 1
editor/js/Viewport.js

@@ -300,7 +300,7 @@ var Viewport = function ( editor ) {
 
 	signals.snapChanged.add( function ( dist ) {
 
-		transformControls.setSnap( dist );
+		transformControls.setTranslationSnap( dist );
 
 	} );
 
@@ -580,6 +580,8 @@ var Viewport = function ( editor ) {
 
 		requestAnimationFrame( animate );
 
+		/*
+
 		// animations
 
 		if ( THREE.AnimationHandler.animations.length > 0 ) {
@@ -602,6 +604,8 @@ var Viewport = function ( editor ) {
 
 		}
 
+		*/
+
 	}
 
 	function render() {

+ 4 - 92
editor/js/libs/tern-threejs/threejs.js

@@ -225,10 +225,6 @@
           "!type": "[]",
           "!doc": "Array of morph targets. Each morph target is a Javascript object:\n\t\t<code>{ name: \"targetName\", vertices: [ new THREE.Vertex(), ... ] }</code>\n\t\tMorph vertices match number and order of primary vertices."
         },
-        "hasTangents": {
-          "!type": "boolean",
-          "!doc": "True if BufferGeometry has tangents. Set in [page:.computeTangents]."
-        },
         "addAttribute": {
           "!type": "null",
           "!doc": "Adds an attribute to this geometry. Use this rather than the attributes property, \n\t\tbecause an internal array of attributes is maintained to speed up iterating over\n\t\tattributes."
@@ -245,10 +241,6 @@
           "!type": "fn()",
           "!doc": "Computes vertex normals by averaging face normals.<br>"
         },
-        "computeTangents": {
-          "!type": "fn()",
-          "!doc": "Computes vertex tangents.<br>\n\t\tBased on [link:http://www.terathon.com/code/tangent.html]<br>\n\t\tGeometry must have vertex [page:UV UVs] (layer 0 will be used)."
-        },
         "computeBoundingBox": {
           "!type": "fn()",
           "!doc": "Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.<br>\n\t\tBounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are *null*."
@@ -374,10 +366,6 @@
           "!type": "[]",
           "!doc": "Array of 3 vertex colors."
         },
-        "vertexTangents": {
-          "!type": "[]",
-          "!doc": "Array of 3 vertex tangents."
-        },
         "materialIndex": {
           "!type": "number",
           "!doc": "Material index (points to [page:MeshFaceMaterial MeshFaceMaterial.materials])."
@@ -445,10 +433,6 @@
           "!type": "object",
           "!doc": "Bounding sphere.\n\t\t<code>{ radius: float }</code>"
         },
-        "hasTangents": {
-          "!type": "bool",
-          "!doc": "True if geometry has tangents. Set in [page:Geometry Geometry.computeTangents]."
-        },
         "dynamic": {
           "!type": "bool",
           "!doc": "Set to *true* if attribute buffers will need to change in runtime (using \"dirty\" flags).<br>\n\t\tUnless set to true internal typed arrays corresponding to buffers will be deleted once sent to GPU.<br>\n\t\tDefaults to true."
@@ -469,10 +453,6 @@
           "!type": "bool",
           "!doc": "Set to *true* if the normals array has been updated."
         },
-        "tangentsNeedUpdate": {
-          "!type": "bool",
-          "!doc": "Set to *true* if the tangents in the faces has been updated."
-        },
         "colorsNeedUpdate": {
           "!type": "bool",
           "!doc": "Set to *true* if the colors array has been updated."
@@ -501,10 +481,6 @@
           "!type": "fn()",
           "!doc": "Computes morph normals."
         },
-        "computeTangents": {
-          "!type": "fn()",
-          "!doc": "Computes vertex tangents.<br>\n\t\tBased on [link:http://www.terathon.com/code/tangent.html]<br>\n\t\tGeometry must have vertex [page:UV UVs] (layer 0 will be used)."
-        },
         "computeBoundingBox": {
           "!type": "fn()",
           "!doc": "Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute."
@@ -2005,22 +1981,6 @@
       "!doc": "Renders [page:ArrowHelper arrows] to visualize an object's vertex normal vectors. Requires that normals have been specified in a [page:BufferAttribute custom attribute] or have been calculated using [page:Geometry.computeVertexNormals computeVertexNormals].",
       "!type": "fn(object: +THREE.Object3D, size: number, color: +THREE.Color, linewidth: number)"
     },
-    "VertexTangentsHelper": {
-      "!url": "http://threejs.org/docs/#Reference/extras/helpers/VertexTangentsHelper",
-      "prototype": {
-        "!proto": "THREE.Line.prototype",
-        "object": {
-          "!type": "+THREE.Object3D",
-          "!doc": "The attached object"
-        },
-        "update": {
-          "!type": "fn()",
-          "!doc": "Updates the vertex tangent preview arrows based on the new position and tangents of the object."
-        }
-      },
-      "!doc": "Renders [page:ArrowHelper arrows] to visualize an object's vertex tangent vectors. Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or have been computed using [page:Geometry.computeTangents computeTangents].",
-      "!type": "fn(object: +THREE.Object3D, size: number, color: +THREE.Color, linewidth: number)"
-    },
     "WireframeHelper": {
       "!url": "http://threejs.org/docs/#Reference/extras/helpers/WireframeHelper",
       "prototype": {
@@ -2117,46 +2077,6 @@
       "!doc": "This light's color gets applied to all the objects in the scene globally.",
       "!type": "fn(hex: number)"
     },
-    "AreaLight": {
-      "!url": "http://threejs.org/docs/#Reference/lights/AreaLight",
-      "prototype": {
-        "!proto": "THREE.Light.prototype",
-        "right": {
-          "!type": "+THREE.Vector3",
-          "!doc": "Sets or gets an unit vector that indicates the right side of the light. This is calculated in local space."
-        },
-        "normal": {
-          "!type": "+THREE.Vector3",
-          "!doc": "Sets or gets an unit vectorSets or gets an unit vector that indicates the right side of the light. This is calculated in local space."
-        },
-        "height": {
-          "!type": "number",
-          "!doc": "Sets or gets the height of the illuminating plane."
-        },
-        "width": {
-          "!type": "number",
-          "!doc": "Sets or gets the width of the illuminating plane."
-        },
-        "intensity": {
-          "!type": "number",
-          "!doc": "Light's intensity.<br>\n\t\tDefault — *1.0*."
-        },
-        "constantAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in constant space. This is independant of the distance of the light."
-        },
-        "linearAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in linear space. This increases the attenuation linearly with the distance from the light."
-        },
-        "quadraticAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in linear space. This increases the attenuation quadratic with the distance from the light."
-        }
-      },
-      "!doc": "This illuminates the scene from a complete surface. This light only works in the [page:WebGLDeferredRenderer deferredrenderer].",
-      "!type": "fn(hex: number, intensity: number)"
-    },
     "DirectionalLight": {
       "!url": "http://threejs.org/docs/#Reference/lights/DirectionalLight",
       "prototype": {
@@ -2479,7 +2399,7 @@
         },
         "setPreferredShading": {
           "!type": "fn(shading: number)",
-          "!doc": "Set the .[page:Integer shading] property on the resource's materials.<br>\n\t\tOptions are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading]."
+          "!doc": "Set the .[page:Integer shading] property on the resource's materials.<br>\n\t\tOptions are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading]."
         },
         "applySkin": {
           "!type": "fn(geometry: +THREE.Geometry, instanceCtrl: object, frame: number)",
@@ -2544,10 +2464,6 @@
           "!type": "fn(json: object, texturePath: string) -> +THREE.Object3D",
           "!doc": "Parse a <em>JSON</em> structure and return an [page:Object] containing the parsed .[page:Geometry] and .[page:Array materials]."
         },
-        "needsTangents": {
-          "!type": "fn(materials: []) -> bool",
-          "!doc": "Checks if the loaded object needs tangents based on its materials."
-        },
         "updateProgress": {
           "!type": "fn(progress: object)",
           "!doc": "Updates the DOM object with the progress made."
@@ -2599,10 +2515,6 @@
           "!type": "string",
           "!doc": "The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS."
         },
-        "needsTangents": {
-          "!type": "fn(materials: []) -> bool",
-          "!doc": "Checks if the loaded object needs tangents based on its materials."
-        },
         "updateProgress": {
           "!type": "fn(progress: object)",
           "!doc": "Updates the DOM object with the progress made."
@@ -3156,7 +3068,7 @@
         },
         "shading": {
           "!type": "number",
-          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading]."
+          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading]."
         },
         "wireframe": {
           "!type": "bool",
@@ -3300,7 +3212,7 @@
         },
         "shading": {
           "!type": "number",
-          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading]."
+          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading]."
         },
         "wireframe": {
           "!type": "bool",
@@ -6025,4 +5937,4 @@
 }
     };
   });
-});
+});

+ 7 - 5
examples/canvas_morphtargets_horse.html

@@ -26,7 +26,7 @@
 
 			var container, stats;
 			var camera, scene, projector, renderer;
-			var mesh, animation;
+			var mesh, mixer;
 
 			init();
 			animate();
@@ -69,8 +69,10 @@
 					mesh.scale.set( 1.5, 1.5, 1.5 );
 					scene.add( mesh );
 
-					animation = new THREE.MorphAnimation( mesh );
-					animation.play();
+					mixer = new THREE.AnimationMixer( mesh );
+
+					var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
+					mixer.addAction( new THREE.AnimationAction( clip ).warpToDuration( 1.5 ) );
 
 				} );
 
@@ -129,11 +131,11 @@
 
 				camera.lookAt( camera.target );
 
-				if ( animation ) {
+				if ( mixer ) {
 
 					var time = Date.now();
 
-					animation.update( time - prevTime );
+					mixer.update( ( time - prevTime ) * 0.001 );
 
 					prevTime = time;
 

+ 4 - 6
examples/css3d_youtube.html

@@ -69,7 +69,7 @@
 				image.style.position = 'absolute';
 				image.style.width = '480px';
 				image.style.height = '360px';
-				image.src = entry.media$group.media$thumbnail[ 2 ].url;
+				image.src = entry.snippet.thumbnails.default.url;
 				dom.appendChild( image );
 
 				var button = document.createElement( 'img' );
@@ -140,7 +140,7 @@
 					player.style.width = '480px';
 					player.style.height = '360px';
 					player.style.border = '0px';
-					player.src = 'http://www.youtube.com/embed/' + entry.id.$t.split( ':' ).pop() + '?rel=0&autoplay=1&controls=1&showinfo=0';
+					player.src = 'http://www.youtube.com/embed/' + entry.id.videoId + '?rel=0&autoplay=1&controls=1&showinfo=0';
 					this.appendChild( player );
 
 					//
@@ -265,7 +265,7 @@
 
 				var request = new XMLHttpRequest();
 				request.addEventListener( 'load', onData, false );
-				request.open( 'GET', 'https://gdata.youtube.com/feeds/api/videos?v=2&alt=json&max-results=50&q=' + query, true );
+				request.open( 'GET', 'https://www.googleapis.com/youtube/v3/search?key={YOUR_API_KEY}&part=snippet&q=' + query, true );
 				request.send( null );
 
 			}
@@ -273,9 +273,7 @@
 			function onData( event ) {
 
 				var data = JSON.parse( event.target.responseText );
-				var entries = data.feed.entry;
-
-				// console.log( entries );
+				var entries = data.items;
 
 				for ( var i = 0; i < entries.length; i ++ ) {
 

+ 17 - 18
examples/index.html

@@ -13,7 +13,7 @@
 				font-style: normal;
 			}
 
-			*{
+			* {
 				box-sizing: border-box;
 			}
 
@@ -219,6 +219,7 @@
 				"webgl_geometry_nurbs",
 				"webgl_geometry_shapes",
 				"webgl_geometry_spline_editor",
+				"webgl_geometry_teapot",
 				"webgl_geometry_terrain",
 				"webgl_geometry_terrain_fog",
 				"webgl_geometry_terrain_raycast",
@@ -234,8 +235,8 @@
 				"webgl_interactive_cubes_ortho",
 				"webgl_interactive_draggablecubes",
 				"webgl_interactive_lines",
-				"webgl_interactive_particles",
-				"webgl_interactive_raycasting_pointcloud",
+				"webgl_interactive_points",
+				"webgl_interactive_raycasting_points",
 				"webgl_interactive_voxelpainter",
 				"webgl_kinect",
 				"webgl_lensflares",
@@ -247,6 +248,7 @@
 				"webgl_lines_dashed",
 				"webgl_lines_sphere",
 				"webgl_lines_splines",
+				"webgl_loader_amf",
 				"webgl_loader_assimp2json",
 				"webgl_loader_awd",
 				"webgl_loader_babylon",
@@ -294,10 +296,10 @@
 				"webgl_materials_cubemap_dynamic2",
 				"webgl_materials_cubemap_escher",
 				"webgl_materials_cubemap_refraction",
+				"webgl_materials_displacementmap",
 				"webgl_materials_envmaps",
 				"webgl_materials_grass",
 				"webgl_materials_lightmap",
-				"webgl_materials_normaldisplacementmap",
 				"webgl_materials_normalmap",
 				"webgl_materials_parallaxmap",
 				"webgl_materials_shaders_fresnel",
@@ -329,14 +331,14 @@
 				"webgl_octree",
 				"webgl_octree_raycasting",
 				"webgl_panorama_equirectangular",
-				"webgl_particles_billboards",
-				"webgl_particles_billboards_colors",
-				"webgl_particles_dynamic",
-				"webgl_particles_random",
-				"webgl_particles_sprites",
 				"webgl_performance",
 				"webgl_performance_doublesided",
 				"webgl_performance_static",
+				"webgl_points_billboards",
+				"webgl_points_billboards_colors",
+				"webgl_points_dynamic",
+				"webgl_points_random",
+				"webgl_points_sprites",
 				"webgl_postprocessing",
 				"webgl_postprocessing_advanced",
 				"webgl_postprocessing_crossfade",
@@ -345,6 +347,7 @@
 				"webgl_postprocessing_glitch",
 				"webgl_postprocessing_godrays",
 				"webgl_postprocessing_ssao",
+				"webgl_raycast_texture",
 				"webgl_rtt",
 				"webgl_sandbox",
 				"webgl_shader",
@@ -358,6 +361,7 @@
 				"webgl_shading_physical",
 				"webgl_shadowmap",
 				"webgl_shadowmap_performance",
+				"webgl_shadowmap_pointlight",
 				"webgl_shadowmap_viewer",
 				"webgl_shadowmesh",
 				"webgl_skinning_simple",
@@ -379,19 +383,14 @@
 				"webgl_buffergeometry_instancing_interleaved_dynamic",
 				"webgl_buffergeometry_lines",
 				"webgl_buffergeometry_lines_indexed",
-				"webgl_buffergeometry_particles",
+				"webgl_buffergeometry_points",
 				"webgl_buffergeometry_rawshader",
 				"webgl_buffergeometry_uint",
 				"webgl_custom_attributes",
 				"webgl_custom_attributes_lines",
-				"webgl_custom_attributes_particles",
-				"webgl_custom_attributes_particles2",
-				"webgl_custom_attributes_particles3"
-			],
-			"webgldeferred": [
-				"webgldeferred_animation",
-				"webgldeferred_arealights",
-				"webgldeferred_pointlights"
+				"webgl_custom_attributes_points",
+				"webgl_custom_attributes_points2",
+				"webgl_custom_attributes_points3"
 			],
 			"vr": [
 				"vr_cubes",

+ 139 - 0
examples/js/AnimationClipCreator.js

@@ -0,0 +1,139 @@
+/**
+ *
+ * Creator of typical test AnimationClips / KeyframeTracks
+ * 
+ * @author Ben Houston / http://clara.io/
+ * @author David Sarno / http://lighthaus.us/
+ */
+
+THREE.AnimationClipCreator = function() {
+};
+
+THREE.AnimationClipCreator.CreateRotationAnimation = function( period, axis ) {
+
+	var keys = [];
+	keys.push( { time: 0, value: 0 } );
+	keys.push( { time: period, value: 360 } );
+
+	axis = axis || 'x';
+	var trackName = '.rotation[' + axis + ']';
+
+	var track = new THREE.NumberKeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'rotate.x', 10, [ track ] );
+	//console.log( 'rotateClip', clip );
+
+	return clip;
+};
+
+THREE.AnimationClipCreator.CreateScaleAxisAnimation = function( period, axis ) {
+
+	var keys = [];
+	keys.push( { time: 0, value: 0 } );
+	keys.push( { time: period, value: 360 } );
+
+	axis = axis || 'x';
+	var trackName = '.scale[' + axis + ']';
+
+	var track = new THREE.NumberKeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'scale.x', 10, [ track ] );
+	//console.log( 'scaleClip', clip );
+
+	return clip;
+};
+
+THREE.AnimationClipCreator.CreateShakeAnimation = function( duration, shakeScale ) {
+
+	var keys = [];
+
+	for( var i = 0; i < duration * 10; i ++ ) {
+
+		keys.push( { 
+			time: ( i / 10.0 ),
+			value: new THREE.Vector3( Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0 ).multiply( shakeScale )
+		} );
+
+	}
+
+	var trackName = '.position';
+
+	var track = new THREE.VectorKeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'shake' + duration, duration, [ track ] );
+	//console.log( 'shakeClip', clip );
+
+	return clip;
+};
+
+
+THREE.AnimationClipCreator.CreatePulsationAnimation = function( duration, pulseScale ) {
+
+	var keys = [];
+
+	for( var i = 0; i < duration * 10; i ++ ) {
+
+		var scaleFactor = Math.random() * pulseScale;
+		keys.push( {
+			time: ( i / 10.0 ),
+			value: new THREE.Vector3( scaleFactor, scaleFactor, scaleFactor )
+		} );
+
+	}
+
+	var trackName = '.scale';
+
+	var track = new THREE.VectorKeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'scale' + duration, duration, [ track ] );
+	//console.log( 'scaleClip', clip );
+
+	return clip;
+};
+
+
+THREE.AnimationClipCreator.CreateVisibilityAnimation = function( duration ) {
+
+	var keys = [];
+	keys.push( {
+		time: 0,
+		value: true
+	} );
+	keys.push( {
+		time: duration - 1,
+		value: false
+	} );
+	keys.push( {
+		time: duration,
+		value: true
+	} );
+
+	var trackName = '.visible';
+
+	var track = new THREE.BooleanKeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'visible' + duration, duration, [ track ] );
+	//console.log( 'scaleClip', clip );
+
+	return clip;
+};
+
+
+THREE.AnimationClipCreator.CreateMaterialColorAnimation = function( duration, colors, loop ) {
+
+	var timeStep = duration / colors.length;
+	var keys = [];
+	for( var i = 0; i <= colors.length; i ++ ) {
+		keys.push( { time: i * timeStep, value: colors[ i % colors.length ] } );
+	}
+
+	var trackName = '.material[0].color';
+
+	var track = new THREE.ColorKeyframeTrack( trackName, keys );
+
+	var clip = new THREE.AnimationClip( 'colorDiffuse', 10, [ track ] );
+	//console.log( 'diffuseClip', clip );
+
+	return clip;
+};
+

+ 0 - 170
examples/js/AudioObject.js

@@ -1,170 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- *
- * AudioObject
- *
- *	- 3d spatialized sound with Doppler-shift effect
- *
- *	- uses Audio API (currently supported in WebKit-based browsers)
- *		https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
- *
- *	- based on Doppler effect demo from Chromium
- * 		http://chromium.googlecode.com/svn/trunk/samples/audio/doppler.html
- *
- * - parameters
- *
- *		- listener
- *			dopplerFactor	// A constant used to determine the amount of pitch shift to use when rendering a doppler effect.
- *			speedOfSound	// The speed of sound used for calculating doppler shift. The default value is 343.3 meters / second.
- *
- *		- panner
- *			refDistance		// A reference distance for reducing volume as source move further from the listener.
- *			maxDistance		// The maximum distance between source and listener, after which the volume will not be reduced any further.
- *			rolloffFactor	// Describes how quickly the volume is reduced as source moves away from listener.
- * 			coneInnerAngle	// An angle inside of which there will be no volume reduction.
- *			coneOuterAngle 	// An angle outside of which the volume will be reduced to a constant value of coneOuterGain.
- *			coneOuterGain	// Amount of volume reduction outside of the coneOuterAngle.
- */
-
-THREE.AudioObject = function ( url, volume, playbackRate, loop ) {
-
-	THREE.Object3D.call( this );
-
-	if ( playbackRate === undefined ) playbackRate = 1;
-	if ( volume === undefined ) volume = 1;
-	if ( loop === undefined ) loop = true;
-
-	if ( ! this.context ) {
-
-		try {
-
-			THREE.AudioObject.prototype.context = new webkitAudioContext();
-
-		} catch ( error ) {
-
-			console.warn( "THREE.AudioObject: webkitAudioContext not found" );
-			return this;
-
-		}
-
-	}
-
-	this.directionalSource = false;
-
-	this.listener = this.context.listener;
-	this.panner = this.context.createPanner();
-	this.source = this.context.createBufferSource();
-
-	this.masterGainNode = this.context.createGainNode();
-	this.dryGainNode = this.context.createGainNode();
-
-	// Setup initial gains
-
-	this.masterGainNode.gain.value = volume;
-	this.dryGainNode.gain.value = 3.0;
-
-	// Connect dry mix
-
-	this.source.connect( this.panner );
-	this.panner.connect( this.dryGainNode );
-	this.dryGainNode.connect( this.masterGainNode );
-
-	// Connect master gain
-
-	this.masterGainNode.connect( this.context.destination );
-
-	// Set source parameters and load sound
-
-	this.source.playbackRate.value = playbackRate;
-	this.source.loop = loop;
-
-	loadBufferAndPlay( url );
-
-	// private properties
-
-	var soundPosition = new THREE.Vector3(),
-	cameraPosition = new THREE.Vector3(),
-	oldSoundPosition = new THREE.Vector3(),
-	oldCameraPosition = new THREE.Vector3(),
-
-	soundDelta = new THREE.Vector3(),
-	cameraDelta = new THREE.Vector3(),
-
-	soundFront = new THREE.Vector3(),
-	cameraFront = new THREE.Vector3(),
-	soundUp = new THREE.Vector3(),
-	cameraUp = new THREE.Vector3();
-
-	var _this = this;
-
-	// API
-
-	this.setVolume = function ( volume ) {
-
-		this.masterGainNode.gain.value = volume;
-
-	};
-
-	this.update = function ( camera ) {
-
-		oldSoundPosition.copy( soundPosition );
-		oldCameraPosition.copy( cameraPosition );
-
-		soundPosition.setFromMatrixPosition( this.matrixWorld );
-		cameraPosition.setFromMatrixPosition( camera.matrixWorld );
-
-		soundDelta.subVectors( soundPosition, oldSoundPosition );
-		cameraDelta.subVectors( cameraPosition, oldCameraPosition );
-
-		cameraUp.copy( camera.up );
-
-		cameraFront.set( 0, 0, - 1 );
-		cameraFront.transformDirection( camera.matrixWorld );
-
-		this.listener.setPosition( cameraPosition.x, cameraPosition.y, cameraPosition.z );
-		this.listener.setVelocity( cameraDelta.x, cameraDelta.y, cameraDelta.z );
-		this.listener.setOrientation( cameraFront.x, cameraFront.y, cameraFront.z, cameraUp.x, cameraUp.y, cameraUp.z );
-
-		this.panner.setPosition( soundPosition.x, soundPosition.y, soundPosition.z );
-		this.panner.setVelocity( soundDelta.x, soundDelta.y, soundDelta.z );
-
-		if ( this.directionalSource ) {
-
-			soundFront.set( 0, 0, - 1 );
-			soundFront.transformDirection( this.matrixWorld );
-
-			soundUp.copy( this.up );
-			this.panner.setOrientation( soundFront.x, soundFront.y, soundFront.z, soundUp.x, soundUp.y, soundUp.z );
-
-		}
-
-
-	};
-
-	function loadBufferAndPlay( url ) {
-
-		// Load asynchronously
-
-		var request = new XMLHttpRequest();
-		request.open( "GET", url, true );
-		request.responseType = "arraybuffer";
-
-		request.onload = function() {
-
-			_this.source.buffer = _this.context.createBuffer( request.response, true );
-			_this.source.noteOn( 0 );
-
-		};
-
-		request.send();
-
-	}
-
-};
-
-THREE.AudioObject.prototype = Object.create( THREE.Object3D.prototype );
-THREE.AudioObject.prototype.constructor = THREE.AudioObject;
-
-THREE.AudioObject.prototype.context = null;
-THREE.AudioObject.prototype.type = null;
-

+ 27 - 146
examples/js/BlendCharacter.js

@@ -20,12 +20,13 @@ THREE.BlendCharacter = function () {
 
 			THREE.SkinnedMesh.call( scope, geometry, originalMaterial );
 
-			// Create the animations
+			scope.mixer = new THREE.AnimationMixer( scope );
 
+			// Create the animations		
 			for ( var i = 0; i < geometry.animations.length; ++ i ) {
 
 				var animName = geometry.animations[ i ].name;
-				scope.animations[ animName ] = new THREE.Animation( scope, geometry.animations[ i ] );
+				scope.animations[ animName ] = geometry.animations[ i ];
 
 			}
 
@@ -38,191 +39,71 @@ THREE.BlendCharacter = function () {
 
 	this.update = function( dt ) {
 
-		for ( var i = this.weightSchedule.length - 1; i >= 0; -- i ) {
-
-			var data = this.weightSchedule[ i ];
-			data.timeElapsed += dt;
-
-			// If the transition is complete, remove it from the schedule
-
-			if ( data.timeElapsed > data.duration ) {
-
-				data.anim.weight = data.endWeight;
-				this.weightSchedule.splice( i, 1 );
-
-				// If we've faded out completely, stop the animation
-
-				if ( data.anim.weight == 0 ) {
-
-					data.anim.stop( 0 );
-
-				}
-
-			} else {
-
-				// interpolate the weight for the current time
-
-				data.anim.weight = data.startWeight + ( data.endWeight - data.startWeight ) * data.timeElapsed / data.duration;
-
-			}
-
-		}
-
-		this.updateWarps( dt );
-
-	};
-
-	this.updateWarps = function( dt ) {
-
-		// Warping modifies the time scale over time to make 2 animations of different
-		// lengths match. This is useful for smoothing out transitions that get out of
-		// phase such as between a walk and run cycle
-
-		for ( var i = this.warpSchedule.length - 1; i >= 0; -- i ) {
-
-			var data = this.warpSchedule[ i ];
-			data.timeElapsed += dt;
-
-			if ( data.timeElapsed > data.duration ) {
-
-				data.to.weight = 1;
-				data.to.timeScale = 1;
-				data.from.weight = 0;
-				data.from.timeScale = 1;
-				data.from.stop( 0 );
-
-				this.warpSchedule.splice( i, 1 );
-
-			} else {
-
-				var alpha = data.timeElapsed / data.duration;
-
-				var fromLength = data.from.data.length;
-				var toLength = data.to.data.length;
-
-				var fromToRatio = fromLength / toLength;
-				var toFromRatio = toLength / fromLength;
-
-				// scale from each time proportionally to the other animation
-
-				data.from.timeScale = ( 1 - alpha ) + fromToRatio * alpha;
-				data.to.timeScale = alpha + toFromRatio * ( 1 - alpha );
-
-				data.from.weight = 1 - alpha;
-				data.to.weight = alpha;
-
-			}
-
-		}
+		this.mixer.update( dt );
 
 	};
 
 	this.play = function( animName, weight ) {
 
-		this.animations[ animName ].play( 0, weight );
+		this.mixer.removeAllActions();
+		
+		this.mixer.play( new THREE.AnimationAction( this.animations[ animName ] ) );
 
 	};
 
 	this.crossfade = function( fromAnimName, toAnimName, duration ) {
 
-		var fromAnim = this.animations[ fromAnimName ];
-		var toAnim = this.animations[ toAnimName ];
+		this.mixer.removeAllActions();
+ 
+		var fromAction = new THREE.AnimationAction( this.animations[ fromAnimName ] );
+		var toAction = new THREE.AnimationAction( this.animations[ toAnimName ] );
 
-		fromAnim.play( 0, 1 );
-		toAnim.play( 0, 0 );
+		this.mixer.play( fromAction );
+		this.mixer.play( toAction );
 
-		this.weightSchedule.push( {
-
-			anim: fromAnim,
-			startWeight: 1,
-			endWeight: 0,
-			timeElapsed: 0,
-			duration: duration
-
-		} );
-
-		this.weightSchedule.push( {
-
-			anim: toAnim,
-			startWeight: 0,
-			endWeight: 1,
-			timeElapsed: 0,
-			duration: duration
-
-		} );
+		this.mixer.crossFade( fromAction, toAction, duration, false );
 
 	};
 
 	this.warp = function( fromAnimName, toAnimName, duration ) {
 
-		var fromAnim = this.animations[ fromAnimName ];
-		var toAnim = this.animations[ toAnimName ];
-
-		fromAnim.play( 0, 1 );
-		toAnim.play( 0, 0 );
+		this.mixer.removeAllActions();
 
-		this.warpSchedule.push( {
+		var fromAction = new THREE.AnimationAction( this.animations[ fromAnimName ] );
+		var toAction = new THREE.AnimationAction( this.animations[ toAnimName ] );
 
-			from: fromAnim,
-			to: toAnim,
-			timeElapsed: 0,
-			duration: duration
+		this.mixer.play( fromAction );
+		this.mixer.play( toAction );
 
-		} );
+		this.mixer.crossFade( fromAction, toAction, duration, true );
 
 	};
 
 	this.applyWeight = function( animName, weight ) {
 
-		this.animations[ animName ].weight = weight;
+		var action = this.mixer.findActionByName( animName );
+		if( action ) {
+			action.weight = weight;
+		}
 
 	};
 
 	this.pauseAll = function() {
 
-		for ( var a in this.animations ) {
-
-			if ( this.animations[ a ].isPlaying ) {
-
-				this.animations[ a ].stop();
-
-			}
-
-		}
+		this.mixer.timeScale = 0;
 
 	};
 
 	this.unPauseAll = function() {
 
-		for ( var a in this.animations ) {
-
-			if ( this.animations[ a ].isPlaying && this.animations[ a ].isPaused ) {
-
-				this.animations[ a ].pause();
-
-			}
-
-		}
+		this.mixer.timeScale = 1;
 
 	};
 
 
 	this.stopAll = function() {
 
-		for ( a in this.animations ) {
-
-			if ( this.animations[ a ].isPlaying ) {
-
-				this.animations[ a ].stop( 0 );
-
-			}
-
-			this.animations[ a ].weight = 0;
-
-		}
-
-		this.weightSchedule.length = 0;
-		this.warpSchedule.length = 0;
+		this.mixer.removeAllActions();
 
 	};
 

+ 15 - 6
examples/js/BlendCharacterGui.js

@@ -2,7 +2,7 @@
  * @author Michael Guerrero / http://realitymeltdown.com
  */
 
-function BlendCharacterGui( animations ) {
+function BlendCharacterGui( blendMesh ) {
 
 	var controls = {
 
@@ -18,7 +18,7 @@ function BlendCharacterGui( animations ) {
 
 	};
 
-	var animations = animations;
+	var blendMesh = blendMesh;
 
 	this.showModel = function() {
 
@@ -38,11 +38,20 @@ function BlendCharacterGui( animations ) {
 
 	};
 
-	this.update = function() {
+	this.update = function( time ) {
 
-		controls[ 'idle' ] = animations[ 'idle' ].weight;
-		controls[ 'walk' ] = animations[ 'walk' ].weight;
-		controls[ 'run' ] = animations[ 'run' ].weight;
+		var getWeight = function( actionName ) {
+			for( var i = 0; i < blendMesh.mixer.actions.length; i ++ ) {
+				var action = blendMesh.mixer.actions[i];
+				if( action.clip.name === actionName ) {
+					return action.getWeightAt( time );	
+				}
+			}
+			return 0;
+		}
+		controls[ 'idle' ] = getWeight( 'idle' );
+		controls[ 'walk' ] = getWeight( 'walk' );
+		controls[ 'run' ] = getWeight( 'run' );
 
 	};
 

+ 187 - 0
examples/js/BufferGeometryUtils.js

@@ -0,0 +1,187 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.BufferGeometryUtils = {
+
+	computeTangents: function ( geometry ) {
+
+		var index = geometry.index;
+		var attributes = geometry.attributes;
+
+		// based on http://www.terathon.com/code/tangent.html
+		// (per vertex tangents)
+
+		if ( index === null ||
+			 attributes.position === undefined ||
+			 attributes.normal === undefined ||
+			 attributes.uv === undefined ) {
+
+			console.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' );
+			return;
+
+		}
+
+		var indices = index.array;
+		var positions = attributes.position.array;
+		var normals = attributes.normal.array;
+		var uvs = attributes.uv.array;
+
+		var nVertices = positions.length / 3;
+
+		if ( attributes.tangent === undefined ) {
+
+			geometry.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );
+
+		}
+
+		var tangents = attributes.tangent.array;
+
+		var tan1 = [], tan2 = [];
+
+		for ( var k = 0; k < nVertices; k ++ ) {
+
+			tan1[ k ] = new THREE.Vector3();
+			tan2[ k ] = new THREE.Vector3();
+
+		}
+
+		var vA = new THREE.Vector3(),
+			vB = new THREE.Vector3(),
+			vC = new THREE.Vector3(),
+
+			uvA = new THREE.Vector2(),
+			uvB = new THREE.Vector2(),
+			uvC = new THREE.Vector2(),
+
+			sdir = new THREE.Vector3(),
+			tdir = new THREE.Vector3();
+
+		function handleTriangle( a, b, c ) {
+
+			vA.fromArray( positions, a * 3 );
+			vB.fromArray( positions, b * 3 );
+			vC.fromArray( positions, c * 3 );
+
+			uvA.fromArray( uvs, a * 2 );
+			uvB.fromArray( uvs, b * 2 );
+			uvC.fromArray( uvs, c * 2 );
+
+			var x1 = vB.x - vA.x;
+			var x2 = vC.x - vA.x;
+
+			var y1 = vB.y - vA.y;
+			var y2 = vC.y - vA.y;
+
+			var z1 = vB.z - vA.z;
+			var z2 = vC.z - vA.z;
+
+			var s1 = uvB.x - uvA.x;
+			var s2 = uvC.x - uvA.x;
+
+			var t1 = uvB.y - uvA.y;
+			var t2 = uvC.y - uvA.y;
+
+			var r = 1.0 / ( s1 * t2 - s2 * t1 );
+
+			sdir.set(
+				( t2 * x1 - t1 * x2 ) * r,
+				( t2 * y1 - t1 * y2 ) * r,
+				( t2 * z1 - t1 * z2 ) * r
+			);
+
+			tdir.set(
+				( s1 * x2 - s2 * x1 ) * r,
+				( s1 * y2 - s2 * y1 ) * r,
+				( s1 * z2 - s2 * z1 ) * r
+			);
+
+			tan1[ a ].add( sdir );
+			tan1[ b ].add( sdir );
+			tan1[ c ].add( sdir );
+
+			tan2[ a ].add( tdir );
+			tan2[ b ].add( tdir );
+			tan2[ c ].add( tdir );
+
+		}
+
+		var groups = geometry.groups;
+
+		if ( groups.length === 0 ) {
+
+			groups = [ {
+				start: 0,
+				count: indices.length
+			} ];
+
+		}
+
+		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+
+			var group = groups[ j ];
+
+			var start = group.start;
+			var count = group.count;
+
+			for ( var i = start, il = start + count; i < il; i += 3 ) {
+
+				handleTriangle(
+					indices[ i + 0 ],
+					indices[ i + 1 ],
+					indices[ i + 2 ]
+				);
+
+			}
+
+		}
+
+		var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
+		var n = new THREE.Vector3(), n2 = new THREE.Vector3();
+		var w, t, test;
+
+		function handleVertex( v ) {
+
+			n.fromArray( normals, v * 3 );
+			n2.copy( n );
+
+			t = tan1[ v ];
+
+			// Gram-Schmidt orthogonalize
+
+			tmp.copy( t );
+			tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
+
+			// Calculate handedness
+
+			tmp2.crossVectors( n2, t );
+			test = tmp2.dot( tan2[ v ] );
+			w = ( test < 0.0 ) ? - 1.0 : 1.0;
+
+			tangents[ v * 4 ] = tmp.x;
+			tangents[ v * 4 + 1 ] = tmp.y;
+			tangents[ v * 4 + 2 ] = tmp.z;
+			tangents[ v * 4 + 3 ] = w;
+
+		}
+
+		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+
+			var group = groups[ j ];
+
+			var start = group.start;
+			var count = group.count;
+
+			for ( var i = start, il = start + count; i < il; i += 3 ) {
+
+				handleVertex( indices[ i + 0 ] );
+				handleVertex( indices[ i + 1 ] );
+				handleVertex( indices[ i + 2 ] );
+
+			}
+
+		}
+
+	}
+
+};

+ 1 - 1
examples/js/GPUParticleSystem.js

@@ -370,7 +370,7 @@ THREE.GPUParticleContainer = function(maxParticles, particleSystem) {
   self.particleShaderMat = self.GPUParticleSystem.particleShaderMat;
 
   this.init = function() {
-    self.particleSystem = new THREE.PointCloud(self.particleShaderGeo, self.particleShaderMat);
+    self.particleSystem = new THREE.Points(self.particleShaderGeo, self.particleShaderMat);
     self.particleSystem.frustumCulled = false;
     this.add(self.particleSystem);
   };

+ 54 - 35
examples/js/MD2Character.js

@@ -21,6 +21,8 @@ THREE.MD2Character = function () {
 
 	this.activeAnimation = null;
 
+	this.mixer = null;
+
 	this.onLoadComplete = function () {};
 
 	this.loadCounter = 0;
@@ -52,7 +54,11 @@ THREE.MD2Character = function () {
 			scope.root.add( mesh );
 
 			scope.meshBody = mesh;
-			scope.activeAnimation = geo.firstAnimation;
+
+			scope.meshBody.clipOffset = 0;
+			scope.activeAnimationClipName = mesh.geometry.animations[0].name;
+
+			scope.mixer = new THREE.AnimationMixer( mesh );
 
 			checkLoadingComplete();
 
@@ -91,8 +97,12 @@ THREE.MD2Character = function () {
 
 	this.setPlaybackRate = function ( rate ) {
 
-		if ( this.meshBody ) this.meshBody.duration = this.meshBody.baseDuration / rate;
-		if ( this.meshWeapon ) this.meshWeapon.duration = this.meshWeapon.baseDuration / rate;
+		if( rate !== 0 ) {
+			this.mixer.timeScale = 1 / rate;
+		}
+		else {
+			this.mixer.timeScale = 0;
+		}
 
 	};
 
@@ -133,51 +143,67 @@ THREE.MD2Character = function () {
 			activeWeapon.visible = true;
 			this.meshWeapon = activeWeapon;
 
-			activeWeapon.playAnimation( this.activeAnimation, this.animationFPS );
-
-			this.meshWeapon.baseDuration = this.meshWeapon.duration;
-
-			this.meshWeapon.time = this.meshBody.time;
-			this.meshWeapon.duration = this.meshBody.duration;
+			scope.syncWeaponAnimation();
 
 		}
 
 	};
 
-	this.setAnimation = function ( animationName ) {
+	this.setAnimation = function ( clipName ) {
 
 		if ( this.meshBody ) {
 
-			this.meshBody.playAnimation( animationName, this.animationFPS );
-			this.meshBody.baseDuration = this.meshBody.duration;
+			if( this.meshBody.activeAction ) {
+				scope.mixer.removeAction( this.meshBody.activeAction );
+				this.meshBody.activeAction = null;
+			}
 
-		}
+			var clip = THREE.AnimationClip.findByName( this.meshBody.geometry.animations, clipName );
+			if( clip ) {
 
-		if ( this.meshWeapon ) {
+				var action = new THREE.AnimationAction( clip, this.mixer.time ).setLocalRoot( this.meshBody );
+				scope.mixer.addAction( action );
 
-			this.meshWeapon.playAnimation( animationName, this.animationFPS );
-			this.meshWeapon.baseDuration = this.meshWeapon.duration;
-			this.meshWeapon.time = this.meshBody.time;
+				this.meshBody.activeAction = action;
+
+			}
 
 		}
 
-		this.activeAnimation = animationName;
+		scope.activeClipName = clipName;
+
+		scope.syncWeaponAnimation();
 
 	};
 
-	this.update = function ( delta ) {
+	this.syncWeaponAnimation = function() {
 
-		if ( this.meshBody ) {
+		var clipName = scope.activeClipName;
 
-			this.meshBody.updateAnimation( 1000 * delta );
+		if ( scope.meshWeapon ) {
 
-		}
+			if( this.meshWeapon.activeAction ) {
+				scope.mixer.removeAction( this.meshWeapon.activeAction );
+				this.meshWeapon.activeAction = null;
+			}
 
-		if ( this.meshWeapon ) {
+			var clip = THREE.AnimationClip.findByName( this.meshWeapon.geometry.animations, clipName );
+			if( clip ) {
 
-			this.meshWeapon.updateAnimation( 1000 * delta );
+				var action = new THREE.AnimationAction( clip ).syncWith( this.meshBody.activeAction ).setLocalRoot( this.meshWeapon );
+				scope.mixer.addAction( action );
+
+				this.meshWeapon.activeAction = action;
+
+			}
 
 		}
+			
+	}
+
+	this.update = function ( delta ) {
+
+		if( this.mixer ) this.mixer.update( delta );
 
 	};
 
@@ -199,12 +225,12 @@ THREE.MD2Character = function () {
 
 	function createPart( geometry, skinMap ) {
 
-		var materialWireframe = new THREE.MeshLambertMaterial( { color: 0xffaa00, wireframe: true, shading: THREE.SmoothShading, morphTargets: true, morphNormals: true } );
-		var materialTexture = new THREE.MeshLambertMaterial( { color: 0xffffff, wireframe: false, shading: THREE.SmoothShading, map: skinMap, morphTargets: true, morphNormals: true } );
+		var materialWireframe = new THREE.MeshLambertMaterial( { color: 0xffaa00, wireframe: true, morphTargets: true, morphNormals: true } );
+		var materialTexture = new THREE.MeshLambertMaterial( { color: 0xffffff, wireframe: false, map: skinMap, morphTargets: true, morphNormals: true } );
 
 		//
 
-		var mesh = new THREE.MorphAnimMesh( geometry, materialTexture );
+		var mesh = new THREE.Mesh( geometry, materialTexture );
 		mesh.rotation.y = - Math.PI / 2;
 
 		mesh.castShadow = true;
@@ -214,14 +240,7 @@ THREE.MD2Character = function () {
 
 		mesh.materialTexture = materialTexture;
 		mesh.materialWireframe = materialWireframe;
-
-		//
-
-		mesh.parseAnimations();
-
-		mesh.playAnimation( geometry.firstAnimation, scope.animationFPS );
-		mesh.baseDuration = mesh.duration;
-
+	
 		return mesh;
 
 	}

+ 2 - 2
examples/js/MD2CharacterComplex.js

@@ -522,8 +522,8 @@ THREE.MD2CharacterComplex = function () {
 
 	function createPart( geometry, skinMap ) {
 
-		var materialWireframe = new THREE.MeshLambertMaterial( { color: 0xffaa00, wireframe: true, shading: THREE.SmoothShading, morphTargets: true, morphNormals: true } );
-		var materialTexture = new THREE.MeshLambertMaterial( { color: 0xffffff, wireframe: false, shading: THREE.SmoothShading, map: skinMap, morphTargets: true, morphNormals: true } );
+		var materialWireframe = new THREE.MeshLambertMaterial( { color: 0xffaa00, wireframe: true, morphTargets: true, morphNormals: true } );
+		var materialTexture = new THREE.MeshLambertMaterial( { color: 0xffffff, wireframe: false, map: skinMap, morphTargets: true, morphNormals: true } );
 
 		//
 

+ 1 - 3
examples/js/MarchingCubes.js

@@ -7,9 +7,7 @@
 
 THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors ) {
 
-	THREE.ImmediateRenderObject.call( this );
-
-	this.material = material;
+	THREE.ImmediateRenderObject.call( this, material );
 
 	this.enableUvs = enableUvs !== undefined ? enableUvs : false;
 	this.enableColors = enableColors !== undefined ? enableColors : false;

+ 70 - 0
examples/js/MorphAnimMesh.js

@@ -0,0 +1,70 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ */
+
+THREE.MorphAnimMesh = function ( geometry, material ) {
+
+	THREE.Mesh.call( this, geometry, material );
+
+	this.type = 'MorphAnimMesh';
+
+	this.mixer = new THREE.AnimationMixer( this );
+	this.activeAction = null;
+};
+
+THREE.MorphAnimMesh.prototype = Object.create( THREE.Mesh.prototype );
+THREE.MorphAnimMesh.prototype.constructor = THREE.MorphAnimMesh;
+
+THREE.MorphAnimMesh.prototype.setDirectionForward = function () {
+
+	this.mixer.timeScale = 1.0;
+
+};
+
+THREE.MorphAnimMesh.prototype.setDirectionBackward = function () {
+
+	this.mixer.timeScale = -1.0;
+
+};
+
+THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
+
+	if( this.activeAction ) {
+
+		this.mixer.removeAction( this.activeAction );
+		this.activeAction = null;
+		
+	}
+
+	var clip = THREE.AnimationClip.findByName( this.geometry.animations, label );
+
+	if ( clip ) {
+
+		var action = new THREE.AnimationAction( clip );
+		action.timeScale = ( clip.tracks.length * fps ) / clip.duration;
+		this.mixer.addAction( action );
+		this.activeAction = action;
+
+	} else {
+
+		throw new Error( 'THREE.MorphAnimMesh: animations[' + label + '] undefined in .playAnimation()' );
+
+	}
+
+};
+
+THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) {
+
+	this.mixer.update( delta );
+
+};
+
+THREE.MorphAnimMesh.prototype.copy = function ( source ) {
+
+	THREE.Mesh.prototype.copy.call( this, source );
+
+	this.mixer = new THREE.AnimationMixer( this );
+
+	return this;
+
+};

+ 0 - 0
src/extras/animation/MorphAnimation.js → examples/js/MorphAnimation.js


+ 0 - 1104
examples/js/ShaderDeferred.js

@@ -1,1104 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author MPanknin / http://www.redplant.de/
- * @author benaadams / http://blog.illyriad.co.uk/
- *
- */
-
-
-THREE.DeferredShaderChunk = {
-
-	// decode float to vec3
-
-	unpackFloat: [
-
-		"vec3 float_to_vec3( float data ) {",
-
-			"vec3 uncompressed;",
-			"uncompressed.x = fract( data );",
-			"float zInt = floor( data / 255.0 );",
-			"uncompressed.z = fract( zInt / 255.0 );",
-			"uncompressed.y = fract( floor( data - ( zInt * 255.0 ) ) / 255.0 );",
-			"return uncompressed;",
-
-		"}"
-
-	].join( "\n" ),
-
-	computeVertexPositionVS: [
-
-		"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-		"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-		"float z = normalDepth.w;",
-
-		"if ( z == 0.0 ) discard;",
-
-		"vec2 xy = texCoord * 2.0 - 1.0;",
-
-		"vec4 vertexPositionProjected = vec4( xy, z, 1.0 );",
-		"vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;",
-		"vertexPositionVS.xyz /= vertexPositionVS.w;",
-		"vertexPositionVS.w = 1.0;"
-
-	].join( "\n" ),
-
-	computeNormal: [
-
-		"vec3 normal = normalDepth.xyz * 2.0 - 1.0;"
-
-	].join( "\n" ),
-
-	unpackColorMap: [
-
-		"vec4 colorMap = texture2D( samplerColor, texCoord );",
-
-		"vec3 albedo = float_to_vec3( abs( colorMap.x ) );",
-		"vec3 specularColor = float_to_vec3( abs( colorMap.y ) );",
-		"float shininess = abs( colorMap.z );",
-		"float wrapAround = sign( colorMap.z );",
-		"float additiveSpecular = sign( colorMap.y );"
-
-	].join( "\n" ),
-
-	computeDiffuse: [
-
-		"float dotProduct = dot( normal, lightVector );",
-		"float diffuseFull = max( dotProduct, 0.0 );",
-
-		"vec3 diffuse;",
-
-		"if ( wrapAround < 0.0 ) {",
-
-			// wrap around lighting
-
-			"float diffuseHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
-
-			"const vec3 wrapRGB = vec3( 1.0, 1.0, 1.0 );",
-			"diffuse = mix( vec3( diffuseFull ), vec3( diffuseHalf ), wrapRGB );",
-
-		"} else {",
-
-			// simple lighting
-
-			"diffuse = vec3( diffuseFull );",
-
-		"}"
-
-	].join( "\n" ),
-
-	computeSpecular: [
-
-		"vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );",
-		"float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
-
-		// simple specular
-
-		//"vec3 specular = specularColor * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse;",
-
-		// physically based specular
-
-		"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
-
-		"vec3 schlick = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, halfVector ), 5.0 );",
-		"vec3 specular = schlick * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse * specularNormalization;"
-
-	].join( "\n" ),
-
-	combine: [
-
-		"vec3 light = lightIntensity * lightColor;",
-		"gl_FragColor = vec4( light * ( albedo * diffuse + specular ), attenuation );"
-
-	].join( "\n" )
-
-};
-
-THREE.ShaderDeferred = {
-
-	"color" : {
-
-		uniforms: THREE.UniformsUtils.merge( [
-
-			THREE.UniformsLib[ "common" ],
-			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "shadowmap" ],
-
-			{
-				"emissive" :  { type: "c", value: new THREE.Color( 0x000000 ) },
-				"specular" :  { type: "c", value: new THREE.Color( 0x111111 ) },
-				"shininess":  { type: "f", value: 30 },
-				"wrapAround": 		{ type: "f", value: 1 },
-				"additiveSpecular": { type: "f", value: 1 },
-
-				"samplerNormalDepth": { type: "t", value: null },
-				"viewWidth": 		{ type: "f", value: 800 },
-				"viewHeight": 		{ type: "f", value: 600 }
-			}
-
-		] ),
-
-		fragmentShader : [
-
-			"uniform vec3 diffuse;",
-			"uniform vec3 specular;",
-			"uniform vec3 emissive;",
-			"uniform float shininess;",
-			"uniform float wrapAround;",
-			"uniform float additiveSpecular;",
-
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "color_pars_fragment" ],
-			THREE.ShaderChunk[ "uv_pars_fragment" ],
-			THREE.ShaderChunk[ "uv2_pars_fragment" ],
-			THREE.ShaderChunk[ "map_pars_fragment" ],
-
-			"#ifdef USE_ENVMAP",
-
-				"varying vec3 vWorldPosition;",
-
-				"uniform float reflectivity;",
-				"uniform samplerCube envMap;",
-				"uniform float flipEnvMap;",
-				"uniform int combine;",
-
-				"uniform bool useRefract;",
-				"uniform float refractionRatio;",
-
-				"uniform sampler2D samplerNormalDepth;",
-				"uniform float viewHeight;",
-				"uniform float viewWidth;",
-
-			"#endif",
-
-			THREE.ShaderChunk[ "fog_pars_fragment" ],
-			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-			THREE.ShaderChunk[ "specularmap_pars_fragment" ],
-
-			"const float unit = 255.0/256.0;",
-
-			"float vec3_to_float( vec3 data ) {",
-
-				"highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;",
-				"return compressed;",
-
-			"}",
-
-			"void main() {",
-
-				"const float opacity = 1.0;",
-
-				"vec3 outgoingLight = vec3( 0.0 );",	// outgoing light does not have an alpha, the surface does
-				"vec4 diffuseColor = vec4( diffuse, opacity );",
-
-				THREE.ShaderChunk[ "map_fragment" ],
-				THREE.ShaderChunk[ "alphatest_fragment" ],
-				THREE.ShaderChunk[ "specularmap_fragment" ],
-				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "color_fragment" ],
-
-				"outgoingLight = diffuseColor.rgb;",
-
-				"#ifdef USE_ENVMAP",
-
-					"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-					"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-					"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
-
-					"vec3 reflectVec;",
-
-					"vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
-
-					"if ( useRefract ) {",
-
-						"reflectVec = refract( cameraToVertex, normal, refractionRatio );",
-
-					"} else { ",
-
-						"reflectVec = reflect( cameraToVertex, normal );",
-
-					"}",
-
-					"#ifdef DOUBLE_SIDED",
-
-						"float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
-						"vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
-
-					"#else",
-
-						"vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
-
-					"#endif",
-
-					"cubeColor.xyz = inputToLinear( cubeColor.xyz );",
-
-					"if ( combine == 1 ) {",
-
-						"outgoingLight = mix( outgoingLight, cubeColor.xyz, specularStrength * reflectivity );",
-
-					"} else if ( combine == 2 ) {",
-
-						"outgoingLight += cubeColor.xyz * specularStrength * reflectivity;",
-
-					"} else {",
-
-						"outgoingLight = mix( outgoingLight, diffuseColor.xyz * cubeColor.xyz, specularStrength * reflectivity );",
-
-					"}",
-
-				"#endif",
-
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
-				THREE.ShaderChunk[ "fog_fragment" ],
-
-				//
-
-				"const float compressionScale = 0.999;",
-
-				//
-
-				"vec3 diffuseMapColor;",
-
-				"#ifdef USE_MAP",
-
-					"diffuseMapColor = texelColor.xyz;",
-
-				"#else",
-
-					"diffuseMapColor = vec3( 1.0 );",
-
-				"#endif",
-
-				// diffuse color
-
-				"gl_FragColor.x = vec3_to_float( compressionScale * outgoingLight );",
-
-				// specular color
-
-				"if ( additiveSpecular < 0.0 ) {",
-
-					"gl_FragColor.y = vec3_to_float( compressionScale * specular );",
-
-				"} else {",
-
-					"gl_FragColor.y = vec3_to_float( compressionScale * specular * diffuseMapColor );",
-
-				"}",
-
-				"gl_FragColor.y *= additiveSpecular;",
-
-				// shininess
-
-				"gl_FragColor.z = wrapAround * shininess;",
-
-				// emissive color
-
-				"#ifdef USE_COLOR",
-
-					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor * vColor );",
-
-				"#else",
-
-					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor );",
-
-				"#endif",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "uv_pars_vertex" ],
-			THREE.ShaderChunk[ "uv2_pars_vertex" ],
-			THREE.ShaderChunk[ "color_pars_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-
-			"#ifdef USE_ENVMAP",
-
-				"varying vec3 vWorldPosition;",
-
-			"#endif",
-
-			"void main() {",
-
-				THREE.ShaderChunk[ "uv_vertex" ],
-				THREE.ShaderChunk[ "uv2_vertex" ],
-				THREE.ShaderChunk[ "color_vertex" ],
-
-				THREE.ShaderChunk[ "skinbase_vertex" ],
-
-				THREE.ShaderChunk[ "morphtarget_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
-				THREE.ShaderChunk[ "default_vertex" ],
-
-				THREE.ShaderChunk[ "worldpos_vertex" ],
-				THREE.ShaderChunk[ "shadowmap_vertex" ],
-
-				"#ifdef USE_ENVMAP",
-
-					"vWorldPosition = worldPosition.xyz;",
-
-				"#endif",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"normalDepth" : {
-
-		uniforms: {
-
-			bumpMap: 	  { type: "t", value: null },
-			bumpScale:	  { type: "f", value: 1 },
-			offsetRepeat: { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }
-
-		},
-
-		fragmentShader : [
-
-			"#ifdef USE_BUMPMAP",
-
-				"varying vec2 vUv;",
-				"varying vec3 vViewPosition;",
-
-				THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
-
-			"#endif",
-
-			"varying vec3 normalView;",
-			"varying vec4 clipPos;",
-
-			"void main() {",
-
-				"vec3 normal = normalize( normalView );",
-
-				"#ifdef USE_BUMPMAP",
-
-					"normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
-
-				"#endif",
-
-				"gl_FragColor.xyz = normal * 0.5 + 0.5;",
-				"gl_FragColor.w = clipPos.z / clipPos.w;",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"varying vec3 normalView;",
-			"varying vec4 clipPos;",
-
-			"#ifdef USE_BUMPMAP",
-
-				"varying vec2 vUv;",
-				"varying vec3 vViewPosition;",
-
-				"uniform vec4 offsetRepeat;",
-
-			"#endif",
-
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-
-			"void main() {",
-
-				THREE.ShaderChunk[ "morphnormal_vertex" ],
-				THREE.ShaderChunk[ "skinbase_vertex" ],
-				THREE.ShaderChunk[ "skinnormal_vertex" ],
-				THREE.ShaderChunk[ "defaultnormal_vertex" ],
-
-				THREE.ShaderChunk[ "morphtarget_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
-				THREE.ShaderChunk[ "default_vertex" ],
-
-				"normalView = normalize( normalMatrix * objectNormal );",
-
-				"#ifdef USE_BUMPMAP",
-
-					"vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
-					"vViewPosition = -mvPosition.xyz;",
-
-				"#endif",
-
-				"clipPos = gl_Position;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"composite" : {
-
-		uniforms: {
-
-			samplerLight: 	{ type: "t", value: null },
-			brightness:		{ type: "f", value: 1 }
-
-		},
-
-		fragmentShader : [
-
-			"varying vec2 texCoord;",
-			"uniform sampler2D samplerLight;",
-			"uniform float brightness;",
-
-			// tonemapping operators
-			// based on John Hable's HLSL snippets
-			// from http://filmicgames.com/archives/75
-
-			"#ifdef TONEMAP_UNCHARTED",
-
-				"const float A = 0.15;",
-				"const float B = 0.50;",
-				"const float C = 0.10;",
-				"const float D = 0.20;",
-				"const float E = 0.02;",
-				"const float F = 0.30;",
-				"const float W = 11.2;",
-
-				"vec3 Uncharted2Tonemap( vec3 x ) {",
-
-				   "return ( ( x * ( A * x + C * B ) + D * E ) / ( x * ( A * x + B ) + D * F ) ) - E / F;",
-
-				"}",
-
-			"#endif",
-
-			"void main() {",
-
-				"vec3 inColor = texture2D( samplerLight, texCoord ).xyz;",
-				"inColor *= brightness;",
-
-				"vec3 outColor;",
-
-				"#if defined( TONEMAP_SIMPLE )",
-
-					"outColor = sqrt( inColor );",
-
-				"#elif defined( TONEMAP_LINEAR )",
-
-					// simple linear to gamma conversion
-
-					"outColor = pow( inColor, vec3( 1.0 / 2.2 ) );",
-
-				"#elif defined( TONEMAP_REINHARD )",
-
-					// Reinhard operator
-
-					"inColor = inColor / ( 1.0 + inColor );",
-					"outColor = pow( inColor, vec3( 1.0 / 2.2 ) );",
-
-				"#elif defined( TONEMAP_FILMIC )",
-
-					// filmic operator by Jim Hejl and Richard Burgess-Dawson
-
-					"vec3 x = max( vec3( 0.0 ), inColor - 0.004 );",
-					"outColor = ( x * ( 6.2 * x + 0.5 ) ) / ( x * ( 6.2 * x + 1.7 ) + 0.06 );",
-
-				"#elif defined( TONEMAP_UNCHARTED )",
-
-					// tonemapping operator from Uncharted 2 by John Hable
-
-					"float ExposureBias = 2.0;",
-					"vec3 curr = Uncharted2Tonemap( ExposureBias * inColor );",
-
-					"vec3 whiteScale = vec3( 1.0 ) / Uncharted2Tonemap( vec3( W ) );",
-					"vec3 color = curr * whiteScale;",
-
-					"outColor = pow( color, vec3( 1.0 / 2.2 ) );",
-
-				"#else",
-
-					"outColor = inColor;",
-
-				"#endif",
-
-				"gl_FragColor = vec4( outColor, 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"varying vec2 texCoord;",
-
-			"void main() {",
-
-				"vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
-				"texCoord = pos.xy * vec2( 0.5 ) + 0.5;",
-				"gl_Position = pos;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"pointLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-			lightRadius: 	{ type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColor;",
-			"uniform vec3 lightPositionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-
-				// bail out early when pixel outside of light sphere
-
-				"vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
-				"float distance = length( lightVector );",
-
-				"if ( distance > lightRadius ) discard;",
-
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"lightVector = normalize( lightVector );",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"float cutoff = 0.3;",
-				"float denom = distance / lightRadius + 1.0;",
-				"float attenuation = 1.0 / ( denom * denom );",
-				"attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
-				"attenuation = max( attenuation, 0.0 );",
-				"attenuation *= attenuation;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// sphere proxy needs real position
-
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-				"gl_Position = projectionMatrix * mvPosition;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"spotLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS : { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-			lightDistance: 	{ type: "f", value: 1.0 },
-			lightAngle: 	{ type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform vec3 lightPositionVS;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform float lightAngle;",
-			"uniform float lightIntensity;",
-			"uniform vec3 lightColor;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
-
-				"float rho = dot( lightDirectionVS, lightVector );",
-				"float rhoMax = cos( lightAngle * 0.5 );",
-
-				"if ( rho <= rhoMax ) discard;",
-
-				"float theta = rhoMax + 0.0001;",
-				"float phi = rhoMax + 0.05;",
-				"float falloff = 4.0;",
-
-				"float spot = 0.0;",
-
-				"if ( rho >= phi ) {",
-
-					"spot = 1.0;",
-
-				"} else if ( rho <= theta ) {",
-
-					"spot = 0.0;",
-
-				"} else { ",
-
-					"spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
-
-				"}",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-
-				"diffuse *= spot;",
-
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"const float attenuation = 1.0;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"directionalLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColor;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = lightDirectionVS;",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"const float attenuation = 1.0;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"hemisphereLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColorSky: 	  { type: "c", value: new THREE.Color( 0x000000 ) },
-			lightColorGround: { type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity:   { type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColorSky;",
-			"uniform vec3 lightColorGround;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = lightDirectionVS;",
-
-				// diffuse
-
-				"float dotProduct = dot( normal, lightVector );",
-				"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
-
-				"vec3 hemiColor = mix( lightColorGround, lightColorSky, hemiDiffuseWeight );",
-
-				"vec3 diffuse = hemiColor;",
-
-				// specular (sky light)
-
-				"vec3 hemiHalfVectorSky = normalize( lightVector - vertexPositionVS.xyz );",
-				"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
-				"float hemiSpecularWeightSky = max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",
-
-				// specular (ground light)
-
-				"vec3 lVectorGround = -lightVector;",
-
-				"vec3 hemiHalfVectorGround = normalize( lVectorGround - vertexPositionVS.xyz );",
-				"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
-				"float hemiSpecularWeightGround = max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
-
-				"float dotProductGround = dot( normal, lVectorGround );",
-
-				"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
-
-				"vec3 schlickSky = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, hemiHalfVectorSky ), 5.0 );",
-				"vec3 schlickGround = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
-				"vec3 specular = hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
-
-				// combine
-
-				"gl_FragColor = vec4( lightIntensity * ( albedo * diffuse + specular ), 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"areaLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightNormalVS: 	 { type: "v3", value: new THREE.Vector3( 0, - 1, 0 ) },
-			lightRightVS:  	 { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
-			lightUpVS:  	 { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
-
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-
-			lightWidth:  { type: "f", value: 1.0 },
-			lightHeight: { type: "f", value: 1.0 },
-
-			constantAttenuation:  { type: "f", value: 1.5 },
-			linearAttenuation:    { type: "f", value: 0.5 },
-			quadraticAttenuation: { type: "f", value: 0.1 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform vec3 lightPositionVS;",
-			"uniform vec3 lightNormalVS;",
-			"uniform vec3 lightRightVS;",
-			"uniform vec3 lightUpVS;",
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightWidth;",
-			"uniform float lightHeight;",
-
-			"uniform float constantAttenuation;",
-			"uniform float linearAttenuation;",
-			"uniform float quadraticAttenuation;",
-
-			"uniform float lightIntensity;",
-			"uniform vec3 lightColor;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"vec3 projectOnPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
-
-				"return point - dot( point - planeCenter, planeNorm ) * planeNorm;",
-
-			"}",
-
-			"bool sideOfPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
-
-				"return ( dot( point - planeCenter, planeNorm ) >= 0.0 );",
-
-			"}",
-
-			"vec3 linePlaneIntersect( vec3 lp, vec3 lv, vec3 pc, vec3 pn ) {",
-
-				"return lp + lv * ( dot( pn, pc - lp ) / dot( pn, lv ) );",
-
-			"}",
-
-			"float calculateAttenuation( float dist ) {",
-
-				"return ( 1.0 / ( constantAttenuation + linearAttenuation * dist + quadraticAttenuation * dist * dist ) );",
-
-			"}",
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				"float w = lightWidth;",
-				"float h = lightHeight;",
-
-				"vec3 proj = projectOnPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS );",
-				"vec3 dir = proj - lightPositionVS;",
-
-				"vec2 diagonal = vec2( dot( dir, lightRightVS ), dot( dir, lightUpVS ) );",
-				"vec2 nearest2D = vec2( clamp( diagonal.x, -w, w ), clamp( diagonal.y, -h, h ) );",
-				"vec3 nearestPointInside = vec3( lightPositionVS ) + ( lightRightVS * nearest2D.x + lightUpVS * nearest2D.y );",
-
-				"vec3 lightDir = normalize( nearestPointInside - vertexPositionVS.xyz );",
-				"float NdotL = max( dot( lightNormalVS, -lightDir ), 0.0 );",
-				"float NdotL2 = max( dot( normal, lightDir ), 0.0 );",
-
-				//"if ( NdotL2 * NdotL > 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS ) ) {",
-				"if ( NdotL2 * NdotL > 0.0 ) {",
-
-					// diffuse
-
-					"vec3 diffuse = vec3( sqrt( NdotL * NdotL2 ) );",
-
-					// specular
-
-					"vec3 specular = vec3( 0.0 );",
-
-					"vec3 R = reflect( normalize( -vertexPositionVS.xyz ), normal );",
-					"vec3 E = linePlaneIntersect( vertexPositionVS.xyz, R, vec3( lightPositionVS ), lightNormalVS );",
-
-					"float specAngle = dot( R, lightNormalVS );",
-
-					"if ( specAngle > 0.0 ) {",
-
-						"vec3 dirSpec = E - vec3( lightPositionVS );",
-						"vec2 dirSpec2D = vec2( dot( dirSpec, lightRightVS ), dot( dirSpec, lightUpVS ) );",
-						"vec2 nearestSpec2D = vec2( clamp( dirSpec2D.x, -w, w ), clamp( dirSpec2D.y, -h, h ) );",
-						"float specFactor = 1.0 - clamp( length( nearestSpec2D - dirSpec2D ) * 0.05 * shininess, 0.0, 1.0 );",
-						"specular = specularColor * specFactor * specAngle * diffuse;",
-
-					"}",
-
-					// combine
-
-					"float dist = distance( vertexPositionVS.xyz, nearestPointInside );",
-					"float attenuation = calculateAttenuation( dist );",
-
-					THREE.DeferredShaderChunk[ "combine" ],
-
-				"} else {",
-
-					"discard;",
-
-				"}",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() {",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"emissiveLight" : {
-
-		uniforms: {
-
-			samplerColor: 	{ type: "t", value: null },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-				"vec4 colorMap = texture2D( samplerColor, texCoord );",
-				"vec3 emissiveColor = float_to_vec3( abs( colorMap.w ) );",
-
-				"gl_FragColor = vec4( emissiveColor, 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	}
-
-};

+ 48 - 59
examples/js/ShaderSkin.js

@@ -167,7 +167,7 @@ THREE.ShaderSkin = {
 				"diffuseColor = diffuseColor * colDiffuse;",
 
 				"vec3 normal = normalize( vNormal );",
-				"vec3 viewPosition = normalize( vViewPosition );",
+				"vec3 viewerDirection = normalize( vViewPosition );",
 
 				"float specularStrength;",
 
@@ -207,10 +207,10 @@ THREE.ShaderSkin = {
 						"float pointDiffuseWeightHalf = max( 0.5 * dot( normal, lVector ) + 0.5, 0.0 );",
 						"vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), uWrapRGB );",
 
-						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalDiffuseLight += attenuation * pointLightColor[ i ] * pointDiffuseWeight;",
-						"totalSpecularLight += attenuation * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
+						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
+						"totalSpecularLight += pointLightColor[ i ] * specular * ( pointSpecularWeight * specularStrength * attenuation );",
 
 					"}",
 
@@ -222,16 +222,16 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
-						"vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );",
+						"vec3 dirVector = directionalLightDirection[ i ];",
 
 						"float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );",
 						"float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
 						"vec3 dirDiffuseWeight = mix( vec3 ( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), uWrapRGB );",
 
-						"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
 						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-						"totalSpecularLight += specular * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
+						"totalSpecularLight += directionalLightColor[ i ] * ( dirSpecularWeight * specularStrength );",
 
 					"}",
 
@@ -243,7 +243,7 @@ THREE.ShaderSkin = {
 
 					"for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
 
-						"vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );",
+						"vec3 lVector = hemisphereLightDirection[ i ];",
 
 						"float dotProduct = dot( normal, lVector );",
 						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
@@ -253,14 +253,16 @@ THREE.ShaderSkin = {
 						// specular (sky light)
 
 						"float hemiSpecularWeight = 0.0;",
-						"hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
 						// specular (ground light)
 
 						"vec3 lVectorGround = -lVector;",
-						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
+						"vec3 hemiSpecularColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+						"totalSpecularLight += hemiSpecularColor * specular * ( hemiSpecularWeight * specularStrength );",
 
 					"}",
 
@@ -384,8 +386,6 @@ THREE.ShaderSkin = {
 
 			"uniform float uNormalScale;",
 
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -453,20 +453,29 @@ THREE.ShaderSkin = {
 
 				"vec4 mSpecular = vec4( specular, opacity );",
 
-				"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
-				"normalTex.xy *= uNormalScale;",
-				"normalTex = normalize( normalTex );",
-
 				"vec4 colDiffuse = texture2D( tDiffuse, vUv );",
 				"colDiffuse *= colDiffuse;",
 
 				"diffuseColor *= colDiffuse;",
 
-				"mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
+				// normal mapping
+
+				"vec4 posAndU = vec4( -vViewPosition, vUv.x );",
+				"vec4 posAndU_dx = dFdx( posAndU ),  posAndU_dy = dFdy( posAndU );",
+				"vec3 tangent = posAndU_dx.w * posAndU_dx.xyz + posAndU_dy.w * posAndU_dy.xyz;",
+				"vec3 normal = normalize( vNormal );",
+				"vec3 binormal = normalize( cross( tangent, normal ) );",
+				"tangent = cross( normal, binormal );",	// no normalization required
+				"mat3 tsb = mat3( tangent, binormal, normal );",
+
+				"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
+				"normalTex.xy *= uNormalScale;",
+				"normalTex = normalize( normalTex );",
+
 				"vec3 finalNormal = tsb * normalTex;",
+				"normal = normalize( finalNormal );",
 
-				"vec3 normal = normalize( finalNormal );",
-				"vec3 viewPosition = normalize( vViewPosition );",
+				"vec3 viewerDirection = normalize( vViewPosition );",
 
 				// point lights
 
@@ -478,14 +487,19 @@ THREE.ShaderSkin = {
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
 						"vec3 pointVector = normalize( vPointLight[ i ].xyz );",
-						"float pointDistance = vPointLight[ i ].w;",
+						"float attenuation = vPointLight[ i ].w;",
 
 						"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
 
-						"totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
+						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
+
+						"if ( passID == 1 ) {",
 
-						"if ( passID == 1 )",
-							"totalSpecularLight += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );",
+							"float pointSpecularWeight = KS_Skin_Specular( normal, pointVector, viewerDirection, uRoughness, uSpecularBrightness );",
+
+							"totalSpecularLight += pointLightColor[ i ] * mSpecular.xyz * ( pointSpecularWeight * attenuation );",
+
+						"}",
 
 					"}",
 
@@ -497,14 +511,19 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
-						"vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );",
+						"vec3 dirVector = directionalLightDirection[ i ];",
 
 						"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
 
 						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
 
-						"if ( passID == 1 )",
-							"totalSpecularLight += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"if ( passID == 1 ) {",
+
+							"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
+
+							"totalSpecularLight += directionalLightColor[ i ] * mSpecular.xyz * dirSpecularWeight;",
+
+						"}",
 
 					"}",
 
@@ -572,8 +591,6 @@ THREE.ShaderSkin = {
 
 		vertexShader: [
 
-			"attribute vec4 tangent;",
-
 			"#ifdef VERTEX_TEXTURES",
 
 				"uniform sampler2D tDisplacement;",
@@ -582,8 +599,6 @@ THREE.ShaderSkin = {
 
 			"#endif",
 
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -611,13 +626,6 @@ THREE.ShaderSkin = {
 
 				"vNormal = normalize( normalMatrix * normal );",
 
-				// tangent and binormal vectors
-
-				"vTangent = normalize( normalMatrix * tangent.xyz );",
-
-				"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
-				"vBinormal = normalize( vBinormal );",
-
 				"vUv = uv;",
 
 				// point lights
@@ -626,7 +634,7 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
 
-						"vec3 lVector = pointLightPosition[ i ] - mvPosition.xyz;",
+						"vec3 lVector = pointLightPosition[ i ] - vViewPosition;",
 
 						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
 
@@ -659,18 +667,6 @@ THREE.ShaderSkin = {
 
 		vertexShaderUV: [
 
-			"attribute vec4 tangent;",
-
-			"#ifdef VERTEX_TEXTURES",
-
-				"uniform sampler2D tDisplacement;",
-				"uniform float uDisplacementScale;",
-				"uniform float uDisplacementBias;",
-
-			"#endif",
-
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -698,13 +694,6 @@ THREE.ShaderSkin = {
 
 				"vNormal = normalize( normalMatrix * normal );",
 
-				// tangent and binormal vectors
-
-				"vTangent = normalize( normalMatrix * tangent.xyz );",
-
-				"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
-				"vBinormal = normalize( vBinormal );",
-
 				"vUv = uv;",
 
 				// point lights
@@ -713,7 +702,7 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
 
-						"vec3 lVector = pointLightPosition[ i ] - mvPosition.xyz;",
+						"vec3 lVector = pointLightPosition[ i ] - vViewPosition;",
 
 						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
 

+ 5 - 5
examples/js/UCSCharacter.js

@@ -15,6 +15,8 @@ THREE.UCSCharacter = function() {
 	this.materials = [];
 	this.morphs = [];
 
+	this.mixer = new THREE.AnimationMixer( this.root );
+
 	this.onLoadComplete = function () {};
 	
 	this.loadCounter = 0;
@@ -41,10 +43,9 @@ THREE.UCSCharacter = function() {
 
 			geometry.computeBoundingBox();
 			geometry.computeVertexNormals();
-
-			//THREE.AnimationHandler.add( geometry.animation );
-
+			
 			mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshFaceMaterial() );
+			mesh.name = config.character;
 			scope.root.add( mesh );
 			
 			var bb = geometry.boundingBox;
@@ -54,8 +55,7 @@ THREE.UCSCharacter = function() {
 			mesh.castShadow = true;
 			mesh.receiveShadow = true;
 
-			animation = new THREE.Animation( mesh, geometry.animation );
-			animation.play();
+			scope.mixer.addAction( new THREE.AnimationAction( geometry.animations[0] ).setLocalRoot( mesh ) );
 			
 			scope.setSkin( 0 );
 			

+ 28 - 15
examples/js/WaterShader.js

@@ -9,17 +9,21 @@
 
 THREE.ShaderLib[ 'water' ] = {
 
-	uniforms: { "normalSampler":	{ type: "t", value: null },
-				"mirrorSampler":	{ type: "t", value: null },
-				"alpha":			{ type: "f", value: 1.0 },
-				"time":				{ type: "f", value: 0.0 },
-				"distortionScale":	{ type: "f", value: 20.0 },
-				"textureMatrix" :	{ type: "m4", value: new THREE.Matrix4() },
-				"sunColor":			{ type: "c", value: new THREE.Color( 0x7F7F7F ) },
-				"sunDirection":		{ type: "v3", value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
-				"eye":				{ type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
-				"waterColor":		{ type: "c", value: new THREE.Color( 0x555555 ) }
-	},
+	uniforms: THREE.UniformsUtils.merge( [
+		THREE.UniformsLib[ "fog" ], { 
+			"normalSampler":    { type: "t", value: null },
+			"mirrorSampler":    { type: "t", value: null },
+			"alpha":            { type: "f", value: 1.0 },
+			"time":             { type: "f", value: 0.0 },
+			"distortionScale":  { type: "f", value: 20.0 },
+			"noiseScale":       { type: "f", value: 1.0 },
+			"textureMatrix" :   { type: "m4", value: new THREE.Matrix4() },
+			"sunColor":         { type: "c", value: new THREE.Color(0x7F7F7F) },
+			"sunDirection":     { type: "v3", value: new THREE.Vector3(0.70707, 0.70707, 0) },
+			"eye":              { type: "v3", value: new THREE.Vector3(0, 0, 0) },
+			"waterColor":       { type: "c", value: new THREE.Color(0x555555) }
+		}
+	] ),
 
 	vertexShader: [
 		'uniform mat4 textureMatrix;',
@@ -73,7 +77,10 @@ THREE.ShaderLib[ 'water' ] = {
 		'	specularColor += pow( direction, shiny ) * sunColor * spec;',
 		'	diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;',
 		'}',
-		
+
+		THREE.ShaderChunk[ "common" ],
+		THREE.ShaderChunk[ "fog_pars_fragment" ],		
+
 		'void main()',
 		'{',
 		'	vec4 noise = getNoise( worldPosition.xz );',
@@ -96,7 +103,9 @@ THREE.ShaderLib[ 'water' ] = {
 		'	float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );',
 		'	vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;',
 		'	vec3 albedo = mix( sunColor * diffuseLight * 0.3 + scatter, ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance );',
-		'	gl_FragColor = vec4( albedo, alpha );',
+		'	vec3 outgoingLight = albedo;',
+			THREE.ShaderChunk[ "fog_fragment" ],
+		'	gl_FragColor = vec4( outgoingLight, alpha );',		
 		'}'
 	].join( '\n' )
 
@@ -128,7 +137,9 @@ THREE.Water = function ( renderer, camera, scene, options ) {
 	this.waterColor = new THREE.Color( optionalParameter( options.waterColor, 0x7F7F7F ) );
 	this.eye = optionalParameter( options.eye, new THREE.Vector3( 0, 0, 0 ) );
 	this.distortionScale = optionalParameter( options.distortionScale, 20.0 );
-	
+	this.side = optionalParameter(options.side, THREE.FrontSide);
+	this.fog = optionalParameter(options.fog, false);
+
 	this.renderer = renderer;
 	this.scene = scene;
 	this.mirrorPlane = new THREE.Plane();
@@ -162,7 +173,9 @@ THREE.Water = function ( renderer, camera, scene, options ) {
 		fragmentShader: mirrorShader.fragmentShader, 
 		vertexShader: mirrorShader.vertexShader, 
 		uniforms: mirrorUniforms,
-		transparent: true
+		transparent: true,
+		side: this.side,
+		fog: this.fog		
 	} );
 
 	this.material.uniforms.mirrorSampler.value = this.texture;

+ 1 - 1
examples/js/controls/OrthographicTrackballControls.js

@@ -245,7 +245,7 @@ THREE.OrthographicTrackballControls = function ( object, domElement ) {
 
 			if ( Math.abs( factor - 1.0 ) > EPS && factor > 0.0 ) {
 
-				_this.object.zoom *= factor;
+				_this.object.zoom /= factor;
 
 				if ( _this.staticMoving ) {
 

+ 59 - 16
examples/js/controls/TransformControls.js

@@ -617,7 +617,8 @@
 
 		this.object = undefined;
 		this.visible = false;
-		this.snap = null;
+		this.translationSnap = null;
+		this.rotationSnap = null;
 		this.space = "world";
 		this.size = 1;
 		this.axis = null;
@@ -756,9 +757,15 @@
 
 		};
 
-		this.setSnap = function ( snap ) {
+		this.setTranslationSnap = function ( translationSnap ) {
 
-			scope.snap = snap;
+			scope.translationSnap = translationSnap;
+
+		};
+
+		this.setRotationSnap = function ( rotationSnap ) {
+
+			scope.rotationSnap = rotationSnap;
 
 		};
 
@@ -812,7 +819,7 @@
 
 		function onPointerHover( event ) {
 
-			if ( scope.object === undefined || _dragging === true ) return;
+			if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
 
 			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
@@ -840,7 +847,7 @@
 
 		function onPointerDown( event ) {
 
-			if ( scope.object === undefined || _dragging === true ) return;
+			if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
 
 			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
@@ -890,7 +897,7 @@
 
 		function onPointerMove( event ) {
 
-			if ( scope.object === undefined || scope.axis === null || _dragging === false ) return;
+			if ( scope.object === undefined || scope.axis === null || _dragging === false || ( event.button !== undefined && event.button !== 0 ) ) return;
 
 			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
@@ -936,11 +943,23 @@
 
 				}
 
-				if ( scope.snap !== null ) {
+				if ( scope.translationSnap !== null ) {
+
+					if ( scope.space === "local" ) {
+
+						scope.object.position.applyMatrix4( tempMatrix.getInverse( worldRotationMatrix ) );
+
+					}
+
+					if ( scope.axis.search( "X" ) !== - 1 ) scope.object.position.x = Math.round( scope.object.position.x / scope.translationSnap ) * scope.translationSnap;
+					if ( scope.axis.search( "Y" ) !== - 1 ) scope.object.position.y = Math.round( scope.object.position.y / scope.translationSnap ) * scope.translationSnap;
+					if ( scope.axis.search( "Z" ) !== - 1 ) scope.object.position.z = Math.round( scope.object.position.z / scope.translationSnap ) * scope.translationSnap;
 
-					if ( scope.axis.search( "X" ) !== - 1 ) scope.object.position.x = Math.round( scope.object.position.x / scope.snap ) * scope.snap;
-					if ( scope.axis.search( "Y" ) !== - 1 ) scope.object.position.y = Math.round( scope.object.position.y / scope.snap ) * scope.snap;
-					if ( scope.axis.search( "Z" ) !== - 1 ) scope.object.position.z = Math.round( scope.object.position.z / scope.snap ) * scope.snap;
+					if ( scope.space === "local" ) {
+
+						scope.object.position.applyMatrix4( worldRotationMatrix );
+
+					}
 
 				}
 
@@ -1019,9 +1038,20 @@
 					offsetRotation.set( Math.atan2( tempVector.z, tempVector.y ), Math.atan2( tempVector.x, tempVector.z ), Math.atan2( tempVector.y, tempVector.x ) );
 
 					quaternionXYZ.setFromRotationMatrix( oldRotationMatrix );
-					quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
-					quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
-					quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
+
+					if ( scope.rotationSnap !== null ) {
+
+						quaternionX.setFromAxisAngle( unitX, Math.round( ( rotation.x - offsetRotation.x ) / scope.rotationSnap ) * scope.rotationSnap );
+						quaternionY.setFromAxisAngle( unitY, Math.round( ( rotation.y - offsetRotation.y ) / scope.rotationSnap ) * scope.rotationSnap );
+						quaternionZ.setFromAxisAngle( unitZ, Math.round( ( rotation.z - offsetRotation.z ) / scope.rotationSnap ) * scope.rotationSnap );
+
+					} else {
+
+						quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
+						quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
+						quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
+
+					}
 
 					if ( scope.axis === "X" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionX );
 					if ( scope.axis === "Y" ) quaternionXYZ.multiplyQuaternions( quaternionXYZ, quaternionY );
@@ -1036,9 +1066,20 @@
 
 					tempQuaternion.setFromRotationMatrix( tempMatrix.getInverse( parentRotationMatrix ) );
 
-					quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
-					quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
-					quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
+					if ( scope.rotationSnap !== null ) {
+
+						quaternionX.setFromAxisAngle( unitX, Math.round( ( rotation.x - offsetRotation.x ) / scope.rotationSnap ) * scope.rotationSnap );
+						quaternionY.setFromAxisAngle( unitY, Math.round( ( rotation.y - offsetRotation.y ) / scope.rotationSnap ) * scope.rotationSnap );
+						quaternionZ.setFromAxisAngle( unitZ, Math.round( ( rotation.z - offsetRotation.z ) / scope.rotationSnap ) * scope.rotationSnap );
+
+					} else {
+
+						quaternionX.setFromAxisAngle( unitX, rotation.x - offsetRotation.x );
+						quaternionY.setFromAxisAngle( unitY, rotation.y - offsetRotation.y );
+						quaternionZ.setFromAxisAngle( unitZ, rotation.z - offsetRotation.z );
+
+					}
+
 					quaternionXYZ.setFromRotationMatrix( worldRotationMatrix );
 
 					if ( scope.axis === "X" ) tempQuaternion.multiplyQuaternions( tempQuaternion, quaternionX );
@@ -1061,6 +1102,8 @@
 
 		function onPointerUp( event ) {
 
+			if ( event.button !== undefined && event.button !== 0 ) return;
+
 			if ( _dragging && ( scope.axis !== null ) ) {
 
 				mouseUpEvent.mode = _mode;

+ 22 - 23
examples/js/geometries/DecalGeometry.js

@@ -27,7 +27,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 	this.cube.updateMatrix();
 
 	this.iCubeMatrix = ( new THREE.Matrix4() ).getInverse( this.cube.matrix );
-	
+
 	this.faceIndices = [ 'a', 'b', 'c', 'd' ];
 
 	this.clipFace = function( inVertices, plane ) {
@@ -40,16 +40,16 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 				d1 = v1.vertex.dot( p ) - size;
 
 			var s = d0 / ( d0 - d1 );
-			var v = new THREE.DecalVertex( 
-				new THREE.Vector3( 
+			var v = new THREE.DecalVertex(
+				new THREE.Vector3(
 					v0.vertex.x + s * ( v1.vertex.x - v0.vertex.x ),
 					v0.vertex.y + s * ( v1.vertex.y - v0.vertex.y ),
-					v0.vertex.z + s * ( v1.vertex.z - v0.vertex.z ) 
+					v0.vertex.z + s * ( v1.vertex.z - v0.vertex.z )
 				),
 				new THREE.Vector3(
 					v0.normal.x + s * ( v1.normal.x - v0.normal.x ),
 					v0.normal.y + s * ( v1.normal.y - v0.normal.y ),
-					v0.normal.z + s * ( v1.normal.z - v0.normal.z ) 
+					v0.normal.z + s * ( v1.normal.z - v0.normal.z )
 				)
 			);
 
@@ -91,19 +91,19 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 					var nV1, nV2, nV3;
 					if ( v1Out ) {
 
-						nV1 = inVertices[ j + 1 ]; 
+						nV1 = inVertices[ j + 1 ];
 						nV2 = inVertices[ j + 2 ];
 						nV3 = clip( inVertices[ j ], nV1, plane );
 						nV4 = clip( inVertices[ j ], nV2, plane );
 
 					}
-					if ( v2Out ) { 
+					if ( v2Out ) {
 
-						nV1 = inVertices[ j ]; 
+						nV1 = inVertices[ j ];
 						nV2 = inVertices[ j + 2 ];
 						nV3 = clip( inVertices[ j + 1 ], nV1, plane );
 						nV4 = clip( inVertices[ j + 1 ], nV2, plane );
-						
+
 						outVertices.push( nV3 );
 						outVertices.push( nV2.clone() );
 						outVertices.push( nV1.clone() );
@@ -114,9 +114,9 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 						break;
 
 					}
-					if ( v3Out ) { 
+					if ( v3Out ) {
 
-						nV1 = inVertices[ j ]; 
+						nV1 = inVertices[ j ];
 						nV2 = inVertices[ j + 1 ];
 						nV3 = clip( inVertices[ j + 2 ], nV1, plane );
 						nV4 = clip( inVertices[ j + 2 ], nV2, plane );
@@ -137,17 +137,17 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 				case 2: {
 
 					var nV1, nV2, nV3;
-					if ( ! v1Out ) { 
+					if ( ! v1Out ) {
 
 						nV1 = inVertices[ j ].clone();
 						nV2 = clip( nV1, inVertices[ j + 1 ], plane );
-						nV3 = clip( nV1, inVertices[ j + 2 ], plane ); 
+						nV3 = clip( nV1, inVertices[ j + 2 ], plane );
 						outVertices.push( nV1 );
 						outVertices.push( nV2 );
 						outVertices.push( nV3 );
 
 					}
-					if ( ! v2Out ) { 
+					if ( ! v2Out ) {
 
 						nV1 = inVertices[ j + 1 ].clone();
 						nV2 = clip( nV1, inVertices[ j + 2 ], plane );
@@ -245,30 +245,30 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 		}
 
 		for ( var k = 0; k < finalVertices.length; k += 3 ) {
-			
+
 			this.vertices.push(
 				finalVertices[ k ].vertex,
 				finalVertices[ k + 1 ].vertex,
 				finalVertices[ k + 2 ].vertex
 			);
 
-			var f = new THREE.Face3( 
-				k, 
-				k + 1, 
+			var f = new THREE.Face3(
+				k,
+				k + 1,
 				k + 2
 			);
 			f.vertexNormals.push( finalVertices[ k + 0 ].normal );
 			f.vertexNormals.push( finalVertices[ k + 1 ].normal );
 			f.vertexNormals.push( finalVertices[ k + 2 ].normal );
-			
+
 			this.faces.push( f );
-			
+
 			this.faceVertexUvs[ 0 ].push( [
 				this.uvs[ k ],
-				this.uvs[ k + 1 ], 
+				this.uvs[ k + 1 ],
 				this.uvs[ k + 2 ]
 			] );
-		
+
 		}
 
 		this.verticesNeedUpdate = true;
@@ -277,7 +277,6 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 		this.uvsNeedUpdate = true;
 		this.normalsNeedUpdate = true;
 		this.colorsNeedUpdate = true;
-		this.tangentsNeedUpdate = true;
 		this.computeFaceNormals();
 
 	};

+ 751 - 0
examples/js/geometries/TeapotBufferGeometry.js

@@ -0,0 +1,751 @@
+/**
+ * @author Eric Haines / http://erichaines.com/
+ *
+ * Tessellates the famous Utah teapot database by Martin Newell into triangles.
+ *
+ * THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn )
+ *
+ * defaults: size = 50, segments = 10, bottom = true, lid = true, body = true,
+ *   fitLid = false, blinn = true
+ *
+ * size is a relative scale: I've scaled the teapot to fit vertically between -1 and 1.
+ * Think of it as a "radius".
+ * segments - number of line segments to subdivide each patch edge;
+ *   1 is possible but gives degenerates, so two is the real minimum.
+ * bottom - boolean, if true (default) then the bottom patches are added. Some consider
+ *   adding the bottom heresy, so set this to "false" to adhere to the One True Way.
+ * lid - to remove the lid and look inside, set to true.
+ * body - to remove the body and leave the lid, set this and "bottom" to false.
+ * fitLid - the lid is a tad small in the original. This stretches it a bit so you can't
+ *   see the teapot's insides through the gap.
+ * blinn - Jim Blinn scaled the original data vertically by dividing by about 1.3 to look
+ *   nicer. If you want to see the original teapot, similar to the real-world model, set
+ *   this to false. True by default.
+ *   See http://en.wikipedia.org/wiki/File:Original_Utah_Teapot.jpg for the original
+ *   real-world teapot (from http://en.wikipedia.org/wiki/Utah_teapot).
+ *
+ * Note that the bottom (the last four patches) is not flat - blame Frank Crow, not me.
+ *
+ * The teapot should normally be rendered as a double sided object, since for some
+ * patches both sides can be seen, e.g., the gap around the lid and inside the spout.
+ *
+ * Segments 'n' determines the number of triangles output.
+ *   Total triangles = 32*2*n*n - 8*n    [degenerates at the top and bottom cusps are deleted]
+ *
+ *   size_factor   # triangles
+ *       1          56
+ *       2         240
+ *       3         552
+ *       4         992
+ *
+ *      10        6320
+ *      20       25440
+ *      30       57360
+ *
+ * Code converted from my ancient SPD software, http://tog.acm.org/resources/SPD/
+ * Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity
+ * Lesson: https://www.udacity.com/course/viewer#!/c-cs291/l-68866048/m-106482448
+ * YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc
+ *
+ * See https://en.wikipedia.org/wiki/Utah_teapot for the history of the teapot
+ *
+ */
+/*global THREE */
+
+THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn ) {
+
+	"use strict";
+
+	// 32 * 4 * 4 Bezier spline patches
+	var teapotPatches = [
+/*rim*/
+0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+3,16,17,18,7,19,20,21,11,22,23,24,15,25,26,27,
+18,28,29,30,21,31,32,33,24,34,35,36,27,37,38,39,
+30,40,41,0,33,42,43,4,36,44,45,8,39,46,47,12,
+/*body*/
+12,13,14,15,48,49,50,51,52,53,54,55,56,57,58,59,
+15,25,26,27,51,60,61,62,55,63,64,65,59,66,67,68,
+27,37,38,39,62,69,70,71,65,72,73,74,68,75,76,77,
+39,46,47,12,71,78,79,48,74,80,81,52,77,82,83,56,
+56,57,58,59,84,85,86,87,88,89,90,91,92,93,94,95,
+59,66,67,68,87,96,97,98,91,99,100,101,95,102,103,104,
+68,75,76,77,98,105,106,107,101,108,109,110,104,111,112,113,
+77,82,83,56,107,114,115,84,110,116,117,88,113,118,119,92,
+/*handle*/
+120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
+123,136,137,120,127,138,139,124,131,140,141,128,135,142,143,132,
+132,133,134,135,144,145,146,147,148,149,150,151,68,152,153,154,
+135,142,143,132,147,155,156,144,151,157,158,148,154,159,160,68,
+/*spout*/
+161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
+164,177,178,161,168,179,180,165,172,181,182,169,176,183,184,173,
+173,174,175,176,185,186,187,188,189,190,191,192,193,194,195,196,
+176,183,184,173,188,197,198,185,192,199,200,189,196,201,202,193,
+/*lid*/
+203,203,203,203,204,205,206,207,208,208,208,208,209,210,211,212,
+203,203,203,203,207,213,214,215,208,208,208,208,212,216,217,218,
+203,203,203,203,215,219,220,221,208,208,208,208,218,222,223,224,
+203,203,203,203,221,225,226,204,208,208,208,208,224,227,228,209,
+209,210,211,212,229,230,231,232,233,234,235,236,237,238,239,240,
+212,216,217,218,232,241,242,243,236,244,245,246,240,247,248,249,
+218,222,223,224,243,250,251,252,246,253,254,255,249,256,257,258,
+224,227,228,209,252,259,260,229,255,261,262,233,258,263,264,237,
+/*bottom*/
+265,265,265,265,266,267,268,269,270,271,272,273,92,119,118,113,
+265,265,265,265,269,274,275,276,273,277,278,279,113,112,111,104,
+265,265,265,265,276,280,281,282,279,283,284,285,104,103,102,95,
+265,265,265,265,282,286,287,266,285,288,289,270,95,94,93,92
+	] ;
+
+	var teapotVertices = [
+1.4,0,2.4,
+1.4,-0.784,2.4,
+0.784,-1.4,2.4,
+0,-1.4,2.4,
+1.3375,0,2.53125,
+1.3375,-0.749,2.53125,
+0.749,-1.3375,2.53125,
+0,-1.3375,2.53125,
+1.4375,0,2.53125,
+1.4375,-0.805,2.53125,
+0.805,-1.4375,2.53125,
+0,-1.4375,2.53125,
+1.5,0,2.4,
+1.5,-0.84,2.4,
+0.84,-1.5,2.4,
+0,-1.5,2.4,
+-0.784,-1.4,2.4,
+-1.4,-0.784,2.4,
+-1.4,0,2.4,
+-0.749,-1.3375,2.53125,
+-1.3375,-0.749,2.53125,
+-1.3375,0,2.53125,
+-0.805,-1.4375,2.53125,
+-1.4375,-0.805,2.53125,
+-1.4375,0,2.53125,
+-0.84,-1.5,2.4,
+-1.5,-0.84,2.4,
+-1.5,0,2.4,
+-1.4,0.784,2.4,
+-0.784,1.4,2.4,
+0,1.4,2.4,
+-1.3375,0.749,2.53125,
+-0.749,1.3375,2.53125,
+0,1.3375,2.53125,
+-1.4375,0.805,2.53125,
+-0.805,1.4375,2.53125,
+0,1.4375,2.53125,
+-1.5,0.84,2.4,
+-0.84,1.5,2.4,
+0,1.5,2.4,
+0.784,1.4,2.4,
+1.4,0.784,2.4,
+0.749,1.3375,2.53125,
+1.3375,0.749,2.53125,
+0.805,1.4375,2.53125,
+1.4375,0.805,2.53125,
+0.84,1.5,2.4,
+1.5,0.84,2.4,
+1.75,0,1.875,
+1.75,-0.98,1.875,
+0.98,-1.75,1.875,
+0,-1.75,1.875,
+2,0,1.35,
+2,-1.12,1.35,
+1.12,-2,1.35,
+0,-2,1.35,
+2,0,0.9,
+2,-1.12,0.9,
+1.12,-2,0.9,
+0,-2,0.9,
+-0.98,-1.75,1.875,
+-1.75,-0.98,1.875,
+-1.75,0,1.875,
+-1.12,-2,1.35,
+-2,-1.12,1.35,
+-2,0,1.35,
+-1.12,-2,0.9,
+-2,-1.12,0.9,
+-2,0,0.9,
+-1.75,0.98,1.875,
+-0.98,1.75,1.875,
+0,1.75,1.875,
+-2,1.12,1.35,
+-1.12,2,1.35,
+0,2,1.35,
+-2,1.12,0.9,
+-1.12,2,0.9,
+0,2,0.9,
+0.98,1.75,1.875,
+1.75,0.98,1.875,
+1.12,2,1.35,
+2,1.12,1.35,
+1.12,2,0.9,
+2,1.12,0.9,
+2,0,0.45,
+2,-1.12,0.45,
+1.12,-2,0.45,
+0,-2,0.45,
+1.5,0,0.225,
+1.5,-0.84,0.225,
+0.84,-1.5,0.225,
+0,-1.5,0.225,
+1.5,0,0.15,
+1.5,-0.84,0.15,
+0.84,-1.5,0.15,
+0,-1.5,0.15,
+-1.12,-2,0.45,
+-2,-1.12,0.45,
+-2,0,0.45,
+-0.84,-1.5,0.225,
+-1.5,-0.84,0.225,
+-1.5,0,0.225,
+-0.84,-1.5,0.15,
+-1.5,-0.84,0.15,
+-1.5,0,0.15,
+-2,1.12,0.45,
+-1.12,2,0.45,
+0,2,0.45,
+-1.5,0.84,0.225,
+-0.84,1.5,0.225,
+0,1.5,0.225,
+-1.5,0.84,0.15,
+-0.84,1.5,0.15,
+0,1.5,0.15,
+1.12,2,0.45,
+2,1.12,0.45,
+0.84,1.5,0.225,
+1.5,0.84,0.225,
+0.84,1.5,0.15,
+1.5,0.84,0.15,
+-1.6,0,2.025,
+-1.6,-0.3,2.025,
+-1.5,-0.3,2.25,
+-1.5,0,2.25,
+-2.3,0,2.025,
+-2.3,-0.3,2.025,
+-2.5,-0.3,2.25,
+-2.5,0,2.25,
+-2.7,0,2.025,
+-2.7,-0.3,2.025,
+-3,-0.3,2.25,
+-3,0,2.25,
+-2.7,0,1.8,
+-2.7,-0.3,1.8,
+-3,-0.3,1.8,
+-3,0,1.8,
+-1.5,0.3,2.25,
+-1.6,0.3,2.025,
+-2.5,0.3,2.25,
+-2.3,0.3,2.025,
+-3,0.3,2.25,
+-2.7,0.3,2.025,
+-3,0.3,1.8,
+-2.7,0.3,1.8,
+-2.7,0,1.575,
+-2.7,-0.3,1.575,
+-3,-0.3,1.35,
+-3,0,1.35,
+-2.5,0,1.125,
+-2.5,-0.3,1.125,
+-2.65,-0.3,0.9375,
+-2.65,0,0.9375,
+-2,-0.3,0.9,
+-1.9,-0.3,0.6,
+-1.9,0,0.6,
+-3,0.3,1.35,
+-2.7,0.3,1.575,
+-2.65,0.3,0.9375,
+-2.5,0.3,1.125,
+-1.9,0.3,0.6,
+-2,0.3,0.9,
+1.7,0,1.425,
+1.7,-0.66,1.425,
+1.7,-0.66,0.6,
+1.7,0,0.6,
+2.6,0,1.425,
+2.6,-0.66,1.425,
+3.1,-0.66,0.825,
+3.1,0,0.825,
+2.3,0,2.1,
+2.3,-0.25,2.1,
+2.4,-0.25,2.025,
+2.4,0,2.025,
+2.7,0,2.4,
+2.7,-0.25,2.4,
+3.3,-0.25,2.4,
+3.3,0,2.4,
+1.7,0.66,0.6,
+1.7,0.66,1.425,
+3.1,0.66,0.825,
+2.6,0.66,1.425,
+2.4,0.25,2.025,
+2.3,0.25,2.1,
+3.3,0.25,2.4,
+2.7,0.25,2.4,
+2.8,0,2.475,
+2.8,-0.25,2.475,
+3.525,-0.25,2.49375,
+3.525,0,2.49375,
+2.9,0,2.475,
+2.9,-0.15,2.475,
+3.45,-0.15,2.5125,
+3.45,0,2.5125,
+2.8,0,2.4,
+2.8,-0.15,2.4,
+3.2,-0.15,2.4,
+3.2,0,2.4,
+3.525,0.25,2.49375,
+2.8,0.25,2.475,
+3.45,0.15,2.5125,
+2.9,0.15,2.475,
+3.2,0.15,2.4,
+2.8,0.15,2.4,
+0,0,3.15,
+0.8,0,3.15,
+0.8,-0.45,3.15,
+0.45,-0.8,3.15,
+0,-0.8,3.15,
+0,0,2.85,
+0.2,0,2.7,
+0.2,-0.112,2.7,
+0.112,-0.2,2.7,
+0,-0.2,2.7,
+-0.45,-0.8,3.15,
+-0.8,-0.45,3.15,
+-0.8,0,3.15,
+-0.112,-0.2,2.7,
+-0.2,-0.112,2.7,
+-0.2,0,2.7,
+-0.8,0.45,3.15,
+-0.45,0.8,3.15,
+0,0.8,3.15,
+-0.2,0.112,2.7,
+-0.112,0.2,2.7,
+0,0.2,2.7,
+0.45,0.8,3.15,
+0.8,0.45,3.15,
+0.112,0.2,2.7,
+0.2,0.112,2.7,
+0.4,0,2.55,
+0.4,-0.224,2.55,
+0.224,-0.4,2.55,
+0,-0.4,2.55,
+1.3,0,2.55,
+1.3,-0.728,2.55,
+0.728,-1.3,2.55,
+0,-1.3,2.55,
+1.3,0,2.4,
+1.3,-0.728,2.4,
+0.728,-1.3,2.4,
+0,-1.3,2.4,
+-0.224,-0.4,2.55,
+-0.4,-0.224,2.55,
+-0.4,0,2.55,
+-0.728,-1.3,2.55,
+-1.3,-0.728,2.55,
+-1.3,0,2.55,
+-0.728,-1.3,2.4,
+-1.3,-0.728,2.4,
+-1.3,0,2.4,
+-0.4,0.224,2.55,
+-0.224,0.4,2.55,
+0,0.4,2.55,
+-1.3,0.728,2.55,
+-0.728,1.3,2.55,
+0,1.3,2.55,
+-1.3,0.728,2.4,
+-0.728,1.3,2.4,
+0,1.3,2.4,
+0.224,0.4,2.55,
+0.4,0.224,2.55,
+0.728,1.3,2.55,
+1.3,0.728,2.55,
+0.728,1.3,2.4,
+1.3,0.728,2.4,
+0,0,0,
+1.425,0,0,
+1.425,0.798,0,
+0.798,1.425,0,
+0,1.425,0,
+1.5,0,0.075,
+1.5,0.84,0.075,
+0.84,1.5,0.075,
+0,1.5,0.075,
+-0.798,1.425,0,
+-1.425,0.798,0,
+-1.425,0,0,
+-0.84,1.5,0.075,
+-1.5,0.84,0.075,
+-1.5,0,0.075,
+-1.425,-0.798,0,
+-0.798,-1.425,0,
+0,-1.425,0,
+-1.5,-0.84,0.075,
+-0.84,-1.5,0.075,
+0,-1.5,0.075,
+0.798,-1.425,0,
+1.425,-0.798,0,
+0.84,-1.5,0.075,
+1.5,-0.84,0.075
+	] ;
+
+	THREE.BufferGeometry.call( this );
+
+	this.type = 'TeapotBufferGeometry';
+
+	this.parameters = {
+		size: size,
+		segments: segments,
+		bottom: bottom,
+		lid: lid,
+		body: body,
+		fitLid: fitLid,
+		blinn: blinn
+	};
+
+	size = size || 50;
+
+	// number of segments per patch
+	segments = segments !== undefined ? Math.max( 2, Math.floor( segments ) || 10 ) : 10;
+
+	// which parts should be visible
+	bottom = bottom === undefined ? true : bottom;
+	lid = lid === undefined ? true : lid;
+	body = body === undefined ? true : body;
+
+	// Should the lid be snug? It's not traditional, so off by default
+	fitLid = fitLid === undefined ? false : fitLid;
+
+	// Jim Blinn scaled the teapot down in size by about 1.3 for
+	// some rendering tests. He liked the new proportions that he kept
+	// the data in this form. The model was distributed with these new
+	// proportions and became the norm. Trivia: comparing images of the
+	// real teapot and the computer model, the ratio for the bowl of the
+	// real teapot is more like 1.25, but since 1.3 is the traditional
+	// value given, we use it here.
+	var blinnScale = 1.3;
+	blinn = blinn === undefined ? true : blinn;
+
+	// scale the size to be the real scaling factor
+	var maxHeight = 3.15 * ( blinn ? 1 : blinnScale );
+
+	var maxHeight2 = maxHeight / 2;
+	var trueSize = size / maxHeight2;
+
+	// Number of elements depends on what is needed. Subtract degenerate
+	// triangles at tip of bottom and lid out in advance.
+	var numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0;
+	numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0;
+	numTriangles += body ? 40 * segments * segments : 0;
+
+	var indices = new Uint32Array( numTriangles * 3 );
+
+	var numVertices = bottom ? 4 : 0;
+	numVertices += lid ? 8 : 0;
+	numVertices += body ? 20 : 0;
+	numVertices *= ( segments + 1 ) * ( segments + 1 );
+
+	var vertices = new Float32Array( numVertices * 3 );
+	var normals = new Float32Array( numVertices * 3 );
+	var uvs = new Float32Array( numVertices * 2 );
+
+	// Bezier form
+	var ms = new THREE.Matrix4();
+	ms.set( -1.0,  3.0, -3.0,  1.0,
+			 3.0, -6.0,  3.0,  0.0,
+			-3.0,  3.0,  0.0,  0.0,
+			 1.0,  0.0,  0.0,  0.0 ) ;
+
+	var g = [];
+	var i, r, c;
+
+	var sp = [];
+	var tp = [];
+	var dsp = [];
+	var dtp = [];
+
+	// M * G * M matrix, sort of see
+	// http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html
+	var mgm = [];
+
+	var vert = [];
+	var sdir = [];
+	var tdir = [];
+
+	var norm = new THREE.Vector3();
+
+	var tcoord;
+
+	var sstep, tstep;
+	var vertPerRow, eps;
+
+	var s, t, sval, tval, p, dsval, dtval;
+
+	var normOut = new THREE.Vector3();
+	var v1, v2, v3, v4;
+
+	var gmx = new THREE.Matrix4();
+	var tmtx = new THREE.Matrix4();
+
+	var vsp = new THREE.Vector4();
+	var vtp = new THREE.Vector4();
+	var vdsp = new THREE.Vector4();
+	var vdtp = new THREE.Vector4();
+
+	var vsdir = new THREE.Vector3();
+	var vtdir = new THREE.Vector3();
+
+	var mst = ms.clone();
+	mst.transpose();
+
+	// internal function: test if triangle has any matching vertices;
+	// if so, don't save triangle, since it won't display anything.
+	var notDegenerate = function ( vtx1, vtx2, vtx3 ) {
+
+		// if any vertex matches, return false
+		return ! ( ( ( vertices[ vtx1 * 3 ]     === vertices[ vtx2 * 3 ] ) &&
+					 ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx2 * 3 + 1 ] ) &&
+					 ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx2 * 3 + 2 ] ) ) ||
+				   ( ( vertices[ vtx1 * 3 ]     === vertices[ vtx3 * 3 ] ) &&
+					 ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
+					 ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) ||
+				   ( ( vertices[ vtx2 * 3 ]     === vertices[ vtx3 * 3 ] ) &&
+					 ( vertices[ vtx2 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
+					 ( vertices[ vtx2 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) );
+
+	};
+
+
+	for ( i = 0; i < 3; i ++ )
+	{
+
+		mgm[ i ] = new THREE.Matrix4();
+
+	}
+
+	var minPatches = body ? 0 : 20;
+	var maxPatches = bottom ? 32 : 28;
+
+	vertPerRow = segments + 1;
+
+	eps = 0.0000001;
+
+	var surfCount = 0;
+
+	var vertCount = 0;
+	var normCount = 0;
+	var uvCount = 0;
+
+	var indexCount = 0;
+
+	for ( var surf = minPatches ; surf < maxPatches ; surf ++ ) {
+
+		// lid is in the middle of the data, patches 20-27,
+		// so ignore it for this part of the loop if the lid is not desired
+		if ( lid || ( surf < 20 || surf >= 28 ) ) {
+
+			// get M * G * M matrix for x,y,z
+			for ( i = 0 ; i < 3 ; i ++ ) {
+
+				// get control patches
+				for ( r = 0 ; r < 4 ; r ++ ) {
+
+					for ( c = 0 ; c < 4 ; c ++ ) {
+
+						// transposed
+						g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ] ;
+
+						// is the lid to be made larger, and is this a point on the lid
+						// that is X or Y?
+						if ( fitLid && ( surf >= 20 && surf < 28 ) && ( i !== 2 ) ) {
+
+							// increase XY size by 7.7%, found empirically. I don't
+							// increase Z so that the teapot will continue to fit in the
+							// space -1 to 1 for Y (Y is up for the final model).
+							g[ c * 4 + r ] *= 1.077;
+
+						}
+
+						// Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the
+						// data we now use. The original teapot is taller. Fix it:
+						if ( ! blinn && ( i === 2 ) ) {
+
+							g[ c * 4 + r ] *= blinnScale;
+
+						}
+
+					}
+
+				}
+
+				gmx.set( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ], g[ 4 ], g[ 5 ], g[ 6 ], g[ 7 ], g[ 8 ], g[ 9 ], g[ 10 ], g[ 11 ], g[ 12 ], g[ 13 ], g[ 14 ], g[ 15 ] );
+
+				tmtx.multiplyMatrices( gmx, ms );
+				mgm[ i ].multiplyMatrices( mst, tmtx );
+
+			}
+
+			// step along, get points, and output
+			for ( sstep = 0 ; sstep <= segments ; sstep ++ ) {
+
+				s = sstep / segments;
+
+				for ( tstep = 0 ; tstep <= segments ; tstep ++ ) {
+
+					t = tstep / segments;
+
+					// point from basis
+					// get power vectors and their derivatives
+					for ( p = 4, sval = tval = 1.0 ; p -- ; ) {
+
+						sp[ p ] = sval ;
+						tp[ p ] = tval ;
+						sval *= s ;
+						tval *= t ;
+
+						if ( p === 3 ) {
+
+							dsp[ p ] = dtp[ p ] = 0.0 ;
+							dsval = dtval = 1.0 ;
+
+						} else {
+
+							dsp[ p ] = dsval * ( 3 - p ) ;
+							dtp[ p ] = dtval * ( 3 - p ) ;
+							dsval *= s ;
+							dtval *= t ;
+
+						}
+
+					}
+
+					vsp.fromArray( sp );
+					vtp.fromArray( tp );
+					vdsp.fromArray( dsp );
+					vdtp.fromArray( dtp );
+
+					// do for x,y,z
+					for ( i = 0 ; i < 3 ; i ++ ) {
+
+						// multiply power vectors times matrix to get value
+						tcoord = vsp.clone();
+						tcoord.applyMatrix4( mgm[ i ] );
+						vert[ i ] = tcoord.dot( vtp );
+
+						// get s and t tangent vectors
+						tcoord = vdsp.clone();
+						tcoord.applyMatrix4( mgm[ i ] );
+						sdir[ i ] = tcoord.dot( vtp ) ;
+
+						tcoord = vsp.clone();
+						tcoord.applyMatrix4( mgm[ i ] );
+						tdir[ i ] = tcoord.dot( vdtp ) ;
+
+					}
+
+					// find normal
+					vsdir.fromArray( sdir );
+					vtdir.fromArray( tdir );
+					norm.crossVectors( vtdir, vsdir );
+					norm.normalize();
+
+					// if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number
+					if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 )
+					{
+
+						// if above the middle of the teapot, normal points up, else down
+						normOut.set( 0, vert[ 2 ] > maxHeight2 ? 1 : - 1, 0 );
+
+					}
+					else
+					{
+
+						// standard output: rotate on X axis
+						normOut.set( norm.x, norm.z, - norm.y );
+
+					}
+
+					// store it all
+					vertices[ vertCount ++ ] = trueSize * vert[ 0 ];
+					vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 );
+					vertices[ vertCount ++ ] = - trueSize * vert[ 1 ];
+
+					normals[ normCount ++ ] = normOut.x;
+					normals[ normCount ++ ] = normOut.y;
+					normals[ normCount ++ ] = normOut.z;
+
+					uvs[ uvCount ++ ] = 1 - t;
+					uvs[ uvCount ++ ] = 1 - s;
+
+				}
+
+			}
+
+			// save the faces
+			for ( sstep = 0 ; sstep < segments ; sstep ++ ) {
+
+				for ( tstep = 0 ; tstep < segments ; tstep ++ ) {
+
+					v1 = surfCount * vertPerRow * vertPerRow + sstep * vertPerRow + tstep;
+					v2 = v1 + 1;
+					v3 = v2 + vertPerRow;
+					v4 = v1 + vertPerRow;
+
+					// Normals and UVs cannot be shared. Without clone(), you can see the consequences
+					// of sharing if you call geometry.applyMatrix( matrix ).
+					if ( notDegenerate ( v1, v2, v3 ) ) {
+
+						indices[ indexCount ++ ] = v1;
+						indices[ indexCount ++ ] = v2;
+						indices[ indexCount ++ ] = v3;
+
+					}
+					if ( notDegenerate ( v1, v3, v4 ) ) {
+
+						indices[ indexCount ++ ] = v1;
+						indices[ indexCount ++ ] = v3;
+						indices[ indexCount ++ ] = v4;
+
+					}
+
+				}
+
+			}
+
+			// increment only if a surface was used
+			surfCount ++;
+
+		}
+
+	}
+
+	this.setIndex( new THREE.BufferAttribute( indices, 1 ) );
+	this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+	this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+	this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
+
+	this.computeBoundingSphere();
+
+};
+
+
+THREE.TeapotBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+THREE.TeapotBufferGeometry.prototype.constructor = THREE.TeapotBufferGeometry;
+
+THREE.TeapotBufferGeometry.prototype.clone = function () {
+
+	var bufferGeometry = new THREE.TeapotBufferGeometry(
+		this.parameters.size,
+		this.parameters.segments,
+		this.parameters.bottom,
+		this.parameters.lid,
+		this.parameters.body,
+		this.parameters.fitLid,
+		this.parameters.blinn
+	);
+
+	return bufferGeometry;
+
+};

+ 0 - 0
editor/js/libs/jszip.min.js → examples/js/libs/jszip.min.js


+ 491 - 0
examples/js/loaders/AMFLoader.js

@@ -0,0 +1,491 @@
+/*
+ * @author tamarintech / https://tamarintech.com
+ *
+ * Description: Early release of an AMF Loader following the pattern of the
+ * example loaders in the three.js project.
+ *
+ * More information about the AMF format: http://amf.wikispaces.com
+ *
+ * Usage:
+ *	var loader = new AMFLoader();
+ *	loader.load('/path/to/project.amf', function(objecttree) {
+ *		scene.add(objecttree);
+ *	});
+ *
+ * Materials now supported, material colors supported
+ * Zip support, requires jszip
+ * TextDecoder polyfill required by some browsers (particularly IE, Edge)
+ * No constellation support (yet)!
+ *
+ */
+
+THREE.AMFLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
+
+THREE.AMFLoader.prototype = {
+
+	constructor: THREE.AMFLoader,
+
+	load: function ( url, onLoad, onProgress, onError ) {
+
+		var scope = this;
+
+		var loader = new THREE.XHRLoader( scope.manager );
+		loader.setCrossOrigin( this.crossOrigin );
+		loader.setResponseType( 'arraybuffer' );
+
+		loader.load( url, function( text ) {
+
+			var amfObject = scope.parse( text );
+			onLoad( amfObject );
+
+		}, onProgress, onError );
+
+	},
+
+	parse: function ( data ) {
+
+		function loadDocument( data ) {
+
+			var view = new DataView( data );
+			var magic = String.fromCharCode( view.getUint8( 0 ), view.getUint8( 1 ) );
+
+			if ( magic === "PK" ) {
+
+				var zip = null;
+				var file = null;
+
+				console.log( "Loading Zip" );
+
+				try {
+
+					zip = new JSZip( data );
+
+				} catch ( e ) {
+
+					if ( e instanceof ReferenceError ) {
+
+						console.log( "	jszip missing and file is compressed." );
+						return null;
+
+					}
+
+				}
+
+				for ( file in zip.files ) {
+
+					if ( file.toLowerCase().endsWith( ".amf" ) ) {
+
+						break;
+
+					}
+
+				}
+
+				console.log( "	Trying to load file asset: " + file );
+				view = new DataView( zip.file( file ).asArrayBuffer() );
+
+			}
+
+			if ( TextDecoder === undefined ) {
+
+				console.log( "	TextDecoder not present.	Please use TextDecoder polyfill." );
+				return null;
+
+			}
+
+			var fileText = new TextDecoder( 'utf-8' ).decode( view );
+			var xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
+
+			if ( xmlData.documentElement.nodeName.toLowerCase() !== "amf" ) {
+
+				console.log( "	Error loading AMF - no AMF document found." );
+				return null;
+
+			}
+
+			return xmlData;
+
+		}
+
+		function loadDocumentScale( node ) {
+
+			var scale = 1.0;
+			var unit = 'millimeter';
+
+			if ( node.documentElement.attributes[ 'unit' ] !== undefined ) {
+
+				unit = node.documentElement.attributes[ 'unit' ].value.toLowerCase();
+
+			}
+
+			var scaleUnits = {
+				'millimeter': 1.0,
+				'inch': 25.4,
+				'feet': 304.8,
+				'meter': 1000.0,
+				'micron': 0.001
+			};
+
+			if ( scaleUnits[ unit ] !== undefined ) {
+
+				scale = scaleUnits[ unit ];
+
+			}
+
+			console.log( "	Unit scale: " + scale );
+			return scale;
+
+		}
+
+		function loadMaterials( node ) {
+
+			var matName = "AMF Material";
+			var matId = node.attributes[ 'id' ].textContent;
+			var color;
+
+			var loadedMaterial = null;
+
+			for ( var i = 0; i < node.children.length; i ++ ) {
+
+				var matChildEl = node.children[ i ];
+
+				if ( matChildEl.nodeName === "metadata" && matChildEl.attributes[ 'type' ] !== undefined ) {
+
+					if ( matChildEl.attributes[ 'type' ].value === 'name' ) {
+
+						matname = matChildEl.textContent;
+
+					}
+
+				} else if ( matChildEl.nodeName === 'color' ) {
+
+					color = loadColor( matChildEl );
+
+				}
+
+			}
+
+			loadedMaterial = new THREE.MeshPhongMaterial( {
+				shading: THREE.FlatShading,
+				color: new THREE.Color( color.r, color.g, color.b ),
+				name: matName
+			} );
+
+			if ( color.opacity !== 1.0 ) {
+
+				loadedMaterial.transparent = true;
+				loadedMaterial.opacity = color.opacity;
+
+			}
+
+			return { 'id': matId, 'material': loadedMaterial };
+
+		}
+
+		function loadColor( node ) {
+
+			var color = { 'r': 1.0, 'g': 1.0, 'b': 1.0, 'a': 1.0, opacity: 1.0 };
+
+			for ( var i = 0; i < node.children.length; i ++ ) {
+
+				var matColor = node.children[ i ];
+
+				if ( matColor.nodeName === 'r' ) {
+
+					color.r = matColor.textContent;
+
+				} else if ( matColor.nodeName === 'g' ) {
+
+					color.g = matColor.textContent;
+
+				} else if ( matColor.nodeName === 'b' ) {
+
+					color.b = matColor.textContent;
+
+				} else if ( matColor.nodeName === 'a' ) {
+
+					color.opacity = matColor.textContent;
+
+				}
+
+			}
+
+			return color;
+
+		}
+
+		function loadMeshVolume( node ) {
+
+			var volume = { "name": "", "triangles": [], "materialid": null };
+
+			var currVolumeNode = node.firstElementChild;
+
+			if ( node.attributes[ 'materialid' ] !== undefined ) {
+
+				volume.materialId = node.attributes[ 'materialid' ].nodeValue;
+
+			}
+
+			while ( currVolumeNode ) {
+
+				if ( currVolumeNode.nodeName === "metadata" ) {
+
+					if ( currVolumeNode.attributes[ 'type' ] !== undefined ) {
+
+						if ( currVolumeNode.attributes[ 'type' ].value === 'name' ) {
+
+							volume.name = currVolumeNode.textContent;
+
+						}
+
+					}
+
+				} else if ( currVolumeNode.nodeName === "triangle" ) {
+
+					var triangleNode = currVolumeNode.firstElementChild;
+
+					while ( triangleNode ) {
+
+						if ( triangleNode.nodeName === "v1" ||
+								triangleNode.nodeName === "v2" ||
+								triangleNode.nodeName === "v3" ) {
+
+							volume.triangles.push( triangleNode.textContent );
+
+						}
+
+						triangleNode = triangleNode.nextElementSibling;
+
+					}
+
+				}
+
+				currVolumeNode = currVolumeNode.nextElementSibling;
+
+			}
+
+			return volume;
+
+		}
+
+		function loadMeshVertices( node ) {
+
+			var vertArray = [];
+			var currVerticesNode = node.firstElementChild;
+
+			while ( currVerticesNode ) {
+
+				if ( currVerticesNode.nodeName === "vertex" ) {
+
+					var vNode = currVerticesNode.firstElementChild;
+
+					while ( vNode ) {
+
+						if ( vNode.nodeName === "coordinates" ) {
+
+							var coordNode = vNode.firstElementChild;
+
+							while ( coordNode ) {
+
+								if ( coordNode.nodeName === "x" ||
+										 coordNode.nodeName === "y" ||
+										 coordNode.nodeName === "z" ) {
+
+									vertArray.push( coordNode.textContent );
+
+								}
+
+								coordNode = coordNode.nextElementSibling;
+
+							}
+
+						}
+						vNode = vNode.nextElementSibling;
+
+					}
+
+				}
+				currVerticesNode = currVerticesNode.nextElementSibling;
+
+			}
+
+			return vertArray;
+
+		}
+
+		function loadObject( node ) {
+
+			var objId = node.attributes[ 'id' ].textContent;
+			var loadedObject = { "name": "amfobject", "meshes": [] };
+			var currColor = null;
+			var currObjNode = node.firstElementChild;
+
+			while ( currObjNode ) {
+
+				if ( currObjNode.nodeName === "metadata" ) {
+
+					if ( currObjNode.attributes[ 'type' ] !== undefined ) {
+
+						if ( currObjNode.attributes[ 'type' ].value === 'name' ) {
+
+							loadedObject.name = currObjNode.textContent;
+
+						}
+
+					}
+
+				} else if ( currObjNode.nodeName === "color" ) {
+
+					currColor = loadColor( currObjNode );
+
+				} else if ( currObjNode.nodeName === "mesh" ) {
+
+					var currMeshNode = currObjNode.firstElementChild;
+					var mesh = { "vertices": [], "volumes": [], "color": currColor };
+
+					while ( currMeshNode ) {
+
+						if ( currMeshNode.nodeName === "vertices" ) {
+
+							mesh.vertices = mesh.vertices.concat( loadMeshVertices( currMeshNode ) );
+
+						} else if ( currMeshNode.nodeName === "volume" ) {
+
+							mesh.volumes.push( loadMeshVolume( currMeshNode ) );
+
+						}
+
+						currMeshNode = currMeshNode.nextElementSibling;
+
+					}
+
+					loadedObject.meshes.push( mesh );
+
+				}
+
+				currObjNode = currObjNode.nextElementSibling;
+
+			}
+
+			return { 'id': objId, 'obj': loadedObject };
+
+		}
+
+		var xmlData = loadDocument( data );
+		var amfName = "";
+		var amfAuthor = "";
+		var amfScale = loadDocumentScale( xmlData );
+		var amfMaterials = {};
+		var amfObjects = {};
+		var children = xmlData.documentElement.children;
+
+		for ( var i = 0; i < children.length; i ++ ) {
+
+			var child = children[ i ];
+
+			if ( child.nodeName === 'metadata' ) {
+
+				if ( child.attributes[ 'type' ] !== undefined ) {
+
+					if ( child.attributes[ 'type' ].value === 'name' ) {
+
+						amfName = child.textContent;
+
+					} else if ( child.attributes[ 'type' ].value === 'author' ) {
+
+						amfAuthor = child.textContent;
+
+					}
+
+				}
+
+			} else if ( child.nodeName === 'material' ) {
+
+				var loadedMaterial = loadMaterials( child );
+
+				amfMaterials[ loadedMaterial.id ] = loadedMaterial.material;
+
+			} else if ( child.nodeName === 'object' ) {
+
+				var loadedObject = loadObject( child );
+
+				amfObjects[ loadedObject.id ] = loadedObject.obj;
+
+			}
+
+		}
+
+		var sceneObject = new THREE.Group();
+		var defaultMaterial = new THREE.MeshPhongMaterial( { color: 0xaaaaff, shading: THREE.FlatShading } );
+
+		sceneObject.name = amfName;
+		sceneObject.userData.author = amfAuthor;
+		sceneObject.userData.loader = "AMF";
+
+		for ( var id in amfObjects ) {
+
+			var meshes = amfObjects[ id ].meshes;
+			var newObject = new THREE.Group();
+
+			for ( var i = 0; i < meshes.length; i ++ ) {
+
+				var mesh = meshes[ i ];
+				var meshVertices = Float32Array.from( mesh.vertices );
+				var vertices = new THREE.BufferAttribute( Float32Array.from( meshVertices ), 3 );
+				var objDefaultMaterial = defaultMaterial;
+
+				if ( mesh.color ) {
+
+					var color = mesh.color;
+
+					objDefaultMaterial = defaultMaterial.clone();
+					objDefaultMaterial.color = new THREE.Color( color.r, color.g, color.b );
+
+					if ( color.a !== 1.0 ) {
+
+						objDefaultMaterial.transparent = true;
+						objDefaultMaterial.opacity = color.a;
+
+					}
+
+				}
+
+				var volumes = mesh.volumes;
+
+				for ( var j = 0; j < volumes.length; j ++ ) {
+
+					var volume = volumes[ j ];
+					var newGeometry = new THREE.BufferGeometry();
+					var indexes = Uint32Array.from( volume.triangles );
+					var normals = new Uint32Array( vertices.array.length );
+					var material = objDefaultMaterial;
+
+					newGeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );
+					newGeometry.addAttribute( 'position', vertices.clone() );
+
+					if ( amfMaterials[ volume.materialid ] !== undefined ) {
+
+						material = amfMaterials[ volume.materialid ];
+
+					}
+
+					newGeometry.scale( amfScale, amfScale, amfScale );
+					newObject.add( new THREE.Mesh( newGeometry, material.clone() ) );
+
+				}
+
+			}
+
+			sceneObject.add( newObject );
+
+		}
+
+		return sceneObject;
+
+	}
+
+};

+ 1 - 1
examples/js/loaders/AWDLoader.js

@@ -764,7 +764,7 @@
 
 						buffer = new Uint16Array( str_len / 2 );
 						attrib = new THREE.BufferAttribute( buffer, 1 );
-						geom.addIndex( attrib );
+						geom.setIndex( attrib );
 
 						idx = 0;
 

+ 0 - 2
examples/js/loaders/AssimpJSONLoader.js

@@ -212,10 +212,8 @@ THREE.AssimpJSONLoader.prototype = {
 
 		//geometry.computeFaceNormals();
 		//geometry.computeVertexNormals();
-		//geometry.computeTangents();
 		geometry.computeBoundingSphere();
 
-		// TODO: tangents
 		return geometry;
 
 	},

+ 1 - 1
examples/js/loaders/BabylonLoader.js

@@ -87,7 +87,7 @@ THREE.BabylonLoader.prototype = {
 
 		var indices = new Uint16Array( json.indices );
 
-		geometry.addIndex( new THREE.BufferAttribute( indices, 1 ) );
+		geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
 
 		// positions
 

+ 22 - 2
examples/js/loaders/BinaryLoader.js

@@ -4,6 +4,13 @@
 
 THREE.BinaryLoader = function ( manager ) {
 
+	if ( typeof manager === 'boolean' ) {
+
+		console.warn( 'THREE.BinaryLoader: showStatus parameter has been removed from constructor.' );
+		manager = undefined;
+
+	}
+
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 };
@@ -12,6 +19,21 @@ THREE.BinaryLoader.prototype = {
 
 	constructor: THREE.BinaryLoader,
 
+	// Deprecated
+	
+	get statusDomElement () {
+
+		if ( this._statusDomElement === undefined ) {
+
+			this._statusDomElement = document.createElement( 'div' );
+
+		}
+
+		console.warn( 'THREE.BinaryLoader: .statusDomElement has been removed.' );
+		return this._statusDomElement;
+
+	},
+
 	// Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
 	//  - binary models consist of two files: JS and BIN
 	//  - parameters
@@ -686,8 +708,6 @@ THREE.BinaryLoader.prototype = {
 		var geometry = new Model( texturePath );
 		var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath, this.crossOrigin );
 
-		if ( THREE.Loader.prototype.needsTangents( materials ) ) geometry.computeTangents();
-
 		callback( geometry, materials );
 
 	}

+ 23 - 15
examples/js/loaders/DDSLoader.js

@@ -16,7 +16,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 	var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
 
 	// Adapted from @toji's DDS utils
-	//	https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
+	// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
 
 	// All values and structures referenced from:
 	// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
@@ -175,9 +175,9 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 		default:
 
-			if ( header[ off_RGBBitCount ] == 32 
+			if ( header[ off_RGBBitCount ] === 32
 				&& header[ off_RBitMask ] & 0xff0000
-				&& header[ off_GBitMask ] & 0xff00 
+				&& header[ off_GBitMask ] & 0xff00
 				&& header[ off_BBitMask ] & 0xff
 				&& header[ off_ABitMask ] & 0xff000000  ) {
 
@@ -201,9 +201,21 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 	}
 
-	//TODO: Verify that all faces of the cubemap are present with DDSCAPS2_CUBEMAP_POSITIVEX, etc.
+	var caps2 = header[ off_caps2 ];
+	dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
+	if ( dds.isCubemap && (
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ )
+		) ) {
+
+		console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
+		return dds;
 
-	dds.isCubemap = header[ off_caps2 ] & DDSCAPS2_CUBEMAP ? true : false;
+	}
 
 	dds.width = header[ off_width ];
 	dds.height = header[ off_height ];
@@ -212,13 +224,13 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 	// Extract mipmaps buffers
 
-	var width = dds.width;
-	var height = dds.height;
-
 	var faces = dds.isCubemap ? 6 : 1;
 
 	for ( var face = 0; face < faces; face ++ ) {
 
+		var width = dds.width;
+		var height = dds.height;
+
 		for ( var i = 0; i < dds.mipmapCount; i ++ ) {
 
 			if ( isRGBAUncompressed ) {
@@ -232,23 +244,19 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 				var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
 
 			}
-			
+
 			var mipmap = { "data": byteArray, "width": width, "height": height };
 			dds.mipmaps.push( mipmap );
 
 			dataOffset += dataLength;
 
-			width = Math.max( width * 0.5, 1 );
-			height = Math.max( height * 0.5, 1 );
+			width = Math.max( width >> 1, 1 );
+			height = Math.max( height >> 1, 1 );
 
 		}
 
-		width = dds.width;
-		height = dds.height;
-
 	}
 
 	return dds;
 
 };
-

+ 6 - 1
examples/js/loaders/MD2Loader.js

@@ -224,7 +224,10 @@ THREE.MD2Loader.prototype = {
 
 				for ( var j = 0; j < 16; j ++ ) {
 
-					string[ j ] = data.getUint8( offset + j, true );
+					var character = data.getUint8( offset + j, true );
+					if( character === 0 ) break;
+					
+					string[ j ] = character;
 
 				}
 
@@ -302,6 +305,8 @@ THREE.MD2Loader.prototype = {
 
 			}
 
+			geometry.animations = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 )
+
 			console.timeEnd( 'MD2Loader' );
 
 			return geometry;

+ 1 - 7
examples/js/loaders/MTLLoader.js

@@ -319,7 +319,7 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 					// Diffuse color (color under white light) using RGB values
 
-					params[ 'diffuse' ] = new THREE.Color().fromArray( value );
+					params[ 'color' ] = new THREE.Color().fromArray( value );
 
 					break;
 
@@ -390,12 +390,6 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 		}
 
-		if ( params[ 'diffuse' ] ) {
-
-			params[ 'color' ] = params[ 'diffuse' ];
-
-		}
-
 		this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
 		return this.materials[ materialName ];
 

+ 1 - 1
examples/js/loaders/SVGLoader.js

@@ -25,7 +25,7 @@ THREE.SVGLoader.prototype = {
 
 			var doc = parser.parseFromString( svgString, 'image/svg+xml' );  // application/xml
 
-			onLoad( doc.firstChild );
+			onLoad( doc.documentElement );
 
 		}, onProgress, onError );
 

+ 1 - 1
examples/js/loaders/UTF8Loader.js

@@ -94,7 +94,7 @@ THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray
 
 	}
 
-	geometry.addIndex( new THREE.BufferAttribute( indices, 1 ) );
+	geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
 	geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
 	geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
 	geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );

+ 1 - 1
examples/js/loaders/VTKLoader.js

@@ -101,7 +101,7 @@ THREE.VTKLoader.prototype = {
 		}
 
 		var geometry = new THREE.BufferGeometry();
-		geometry.addIndex( new THREE.BufferAttribute( new ( indices.length > 65535 ? Uint32Array : Uint16Array )( indices ), 1 ) );
+		geometry.setIndex( new THREE.BufferAttribute( new ( indices.length > 65535 ? Uint32Array : Uint16Array )( indices ), 1 ) );
 		geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
 
 		return geometry;

+ 0 - 0
src/extras/animation/Animation.js → examples/js/loaders/collada/Animation.js


+ 0 - 0
src/extras/animation/AnimationHandler.js → examples/js/loaders/collada/AnimationHandler.js


+ 0 - 0
src/extras/animation/KeyFrameAnimation.js → examples/js/loaders/collada/KeyFrameAnimation.js


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

@@ -12,6 +12,25 @@ THREE.CTMLoader = function () {
 
 	THREE.Loader.call( this );
 
+	// Deprecated
+	
+	Object.defineProperties( this, {
+		statusDomElement: {
+			get: function () {
+
+				if ( this._statusDomElement === undefined ) {
+
+					this._statusDomElement = document.createElement( 'div' );
+
+				}
+
+				console.warn( 'THREE.BinaryLoader: .statusDomElement has been removed.' );
+				return this._statusDomElement;
+
+			}
+		},
+	} );
+
 };
 
 THREE.CTMLoader.prototype = Object.create( THREE.Loader.prototype );
@@ -219,7 +238,7 @@ THREE.CTMLoader.prototype.createModel = function ( file, callback ) {
 
 		}
 
-		this.addIndex( new THREE.BufferAttribute( indices, 1 ) );
+		this.setIndex( new THREE.BufferAttribute( indices, 1 ) );
 		this.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
 
 		if ( normals !== undefined ) {

+ 1 - 27
examples/js/loaders/deprecated/SceneLoader.js

@@ -218,10 +218,7 @@ THREE.SceneLoader.prototype = {
 
 						if ( geometry ) {
 
-							var needsTangents = false;
-
 							material = result.materials[ objJSON.material ];
-							needsTangents = material instanceof THREE.ShaderMaterial;
 
 							pos = objJSON.position;
 							rot = objJSON.rotation;
@@ -248,22 +245,6 @@ THREE.SceneLoader.prototype = {
 
 							}
 
-							if ( material instanceof THREE.MeshFaceMaterial ) {
-
-								for ( var i = 0; i < material.materials.length; i ++ ) {
-
-									needsTangents = needsTangents || ( material.materials[ i ] instanceof THREE.ShaderMaterial );
-
-								}
-
-							}
-
-							if ( needsTangents ) {
-
-								geometry.computeTangents();
-
-							}
-
 							if ( objJSON.skin ) {
 
 								object = new THREE.SkinnedMesh( geometry, material );
@@ -346,7 +327,7 @@ THREE.SceneLoader.prototype = {
 
 					} else if ( objJSON.type === "AmbientLight" || objJSON.type === "PointLight" ||
 						objJSON.type === "DirectionalLight" || objJSON.type === "SpotLight" ||
-						objJSON.type === "HemisphereLight" || objJSON.type === "AreaLight" ) {
+						objJSON.type === "HemisphereLight" ) {
 
 						var color = objJSON.color;
 						var intensity = objJSON.intensity;
@@ -384,13 +365,6 @@ THREE.SceneLoader.prototype = {
 								light.target.applyEuler( new THREE.Euler( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ], 'XYZ' ) );
 								break;
 
-							case 'AreaLight':
-								light = new THREE.AreaLight( color, intensity );
-								light.position.fromArray( position );
-								light.width = objJSON.size;
-								light.height = objJSON.size_y;
-								break;
-
 						}
 
 						parent.add( light );

File diff suppressed because it is too large
+ 506 - 329
examples/js/loaders/sea3d/SEA3D.js


+ 11 - 12
examples/js/loaders/sea3d/SEA3DDeflate.js

@@ -318,7 +318,6 @@ var zip_GET_BYTE = function() {
     if(zip_inflate_data.length == zip_inflate_pos)
 	return -1;
 	return zip_inflate_data[zip_inflate_pos++];
-    //return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
 }
 
 var zip_NEEDBITS = function(n) {
@@ -730,11 +729,11 @@ var zip_inflate_internal = function(buff, off, size) {
     return n;
 }
 
-var zip_inflate = function(str) {
+var zip_inflate = function(data) {
     var i, j, pos = 0;
 
     zip_inflate_start();
-    zip_inflate_data = str;
+    zip_inflate_data = new Uint8Array(data);
     zip_inflate_pos = 0;
 	
     var buff = new Uint8Array(1024);
@@ -745,7 +744,7 @@ var zip_inflate = function(str) {
 			out[pos++] = buff[j];		    
 	
     zip_inflate_data = null; // G.C.
-    return new Uint8Array(out);
+    return new Uint8Array(out).buffer;
 }
 
 if (! ctx.RawDeflate) ctx.RawDeflate = {};
@@ -754,14 +753,14 @@ ctx.RawDeflate.inflate = zip_inflate;
 })(this);
 
 /**
- * 	SEA3D.js - SEA3D SDK ( Deflate )
- * 	Copyright (C) 2013 Sunag Entertainment 
- * 
- * 	http://code.google.com/p/sea3d/
+ * 	SEA3D DEFLATE
+ * 	@author Sunag / http://www.sunag.com.br/
  */
- 
-SEA3D.File.DeflateUncompress = function(data) {	
-	return RawDeflate.inflate(data);
+
+SEA3D.File.DeflateUncompress = function( data ) {
+
+	return RawDeflate.inflate( data );
+
 }
 
-SEA3D.File.setDecompressionEngine(1, "deflate", SEA3D.File.DeflateUncompress);
+SEA3D.File.setDecompressionEngine( 1, "deflate", SEA3D.File.DeflateUncompress );

+ 25 - 19
examples/js/loaders/sea3d/SEA3DLZMA.js

@@ -561,32 +561,38 @@ LZMA.decompressFile = function(inStream, outStream){
 };
 
 /**
- * 	SEA3D.js - SEA3D SDK ( LZMA )
- * 	Copyright (C) 2013 Sunag Entertainment 
- * 
- * 	http://code.google.com/p/sea3d/
+ * 	SEA3D LZMA
+ * 	@author Sunag / http://www.sunag.com.br/
  */
- 
-SEA3D.File.LZMAUncompress = function(data) {	
+
+SEA3D.File.LZMAUncompress = function( data ) {
+
+	data = new Uint8Array( data );
+
 	var inStream = {
-		data:data,
-		position:0,
-		readByte:function(){
-			return this.data[this.position++];
+		data: data,
+		position: 0,
+		readByte: function() {
+
+			return this.data[ this.position ++ ];
+
 		}
 	}
-	
+
 	var outStream = {
-		data:[],
-		position:0,
-		writeByte: function(value){
-			this.data[this.position++] = value;
+		data: [],
+		position: 0,
+		writeByte: function( value ) {
+
+			this.data[ this.position ++ ] = value;
+
 		}
 	}
-	
-	LZMA.decompressFile(inStream, outStream);
 
-	return new Uint8Array(outStream.data);
+	LZMA.decompressFile( inStream, outStream );
+
+	return new Uint8Array( outStream.data ).buffer;
+
 }
 
-SEA3D.File.setDecompressionEngine(2, "lzma", SEA3D.File.LZMAUncompress);
+SEA3D.File.setDecompressionEngine( 2, "lzma", SEA3D.File.LZMAUncompress );

File diff suppressed because it is too large
+ 0 - 13
examples/js/loaders/sea3d/SEA3DLZMA_LZIP.js


File diff suppressed because it is too large
+ 760 - 1087
examples/js/loaders/sea3d/SEA3DLoader.js


+ 2 - 2
examples/js/math/Lut.js

@@ -330,7 +330,7 @@ THREE.Lut.prototype = {
 		var txtTitle = new THREE.CanvasTexture( canvasTitle );
 		txtTitle.minFilter = THREE.LinearFilter;
 
-		var spriteMaterialTitle = new THREE.SpriteMaterial( { map: txtTitle, useScreenCoordinates: false } );
+		var spriteMaterialTitle = new THREE.SpriteMaterial( { map: txtTitle } );
 
 		var spriteTitle = new THREE.Sprite( spriteMaterialTitle );
 
@@ -410,7 +410,7 @@ THREE.Lut.prototype = {
 				var txtTick = new THREE.CanvasTexture( canvasTick );
 				txtTick.minFilter = THREE.LinearFilter;
 
-				var spriteMaterialTick = new THREE.SpriteMaterial( { map: txtTick, useScreenCoordinates: false } );
+				var spriteMaterialTick = new THREE.SpriteMaterial( { map: txtTick } );
 
 				var spriteTick = new THREE.Sprite( spriteMaterialTick );
 

+ 2 - 2
examples/js/renderers/Projector.js

@@ -616,9 +616,9 @@ THREE.Projector = function () {
 
 						}
 
-						if ( attributes.index !== undefined ) {
+						if ( geometry.index !== null ) {
 
-							var indices = attributes.index.array;
+							var indices = geometry.index.array;
 
 							for ( var i = 0, l = indices.length; i < l; i += 2 ) {
 

+ 0 - 1209
examples/js/renderers/WebGLDeferredRenderer.js

@@ -1,1209 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author MPanknin / http://www.redplant.de/
- */
-
-THREE.WebGLDeferredRenderer = function ( parameters ) {
-
-	var _this = this;
-
-	var pixelWidth = parameters.width !== undefined ? parameters.width : 800;
-	var pixelHeight = parameters.height !== undefined ? parameters.height : 600;
-	var currentScale = parameters.scale !== undefined ? parameters.scale : 1;
-
-	var scaledWidth = Math.floor( currentScale * pixelWidth );
-	var scaledHeight = Math.floor( currentScale * pixelHeight );
-
-	var brightness = parameters.brightness !== undefined ? parameters.brightness : 1;
-	var tonemapping = parameters.tonemapping !== undefined ? parameters.tonemapping : THREE.SimpleOperator;
-	var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
-
-	this.renderer = parameters.renderer;
-
-	if ( this.renderer === undefined ) {
-
-		this.renderer = new THREE.WebGLRenderer( { antialias: false } );
-		this.renderer.setSize( pixelWidth, pixelHeight );
-		this.renderer.setClearColor( 0x000000, 0 );
-
-		this.renderer.autoClear = false;
-
-	}
-
-	this.domElement = this.renderer.domElement;
-
-	//
-
-	var gl = this.renderer.context;
-
-	//
-
-	var currentCamera = null;
-	var projectionMatrixInverse = new THREE.Matrix4();
-
-	var positionVS = new THREE.Vector3();
-	var directionVS = new THREE.Vector3();
-	var tempVS = new THREE.Vector3();
-
-	var rightVS = new THREE.Vector3();
-	var normalVS = new THREE.Vector3();
-	var upVS = new THREE.Vector3();
-
-	//
-
-	var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
-	var geometryLightPlane = new THREE.PlaneBufferGeometry( 2, 2 );
-
-	var black = new THREE.Color( 0x000000 );
-
-	var colorShader = THREE.ShaderDeferred[ "color" ];
-	var normalDepthShader = THREE.ShaderDeferred[ "normalDepth" ];
-
-	//
-
-	var emissiveLightShader = THREE.ShaderDeferred[ "emissiveLight" ];
-	var pointLightShader = THREE.ShaderDeferred[ "pointLight" ];
-	var spotLightShader = THREE.ShaderDeferred[ "spotLight" ];
-	var directionalLightShader = THREE.ShaderDeferred[ "directionalLight" ];
-	var hemisphereLightShader = THREE.ShaderDeferred[ "hemisphereLight" ];
-	var areaLightShader = THREE.ShaderDeferred[ "areaLight" ];
-
-	var compositeShader = THREE.ShaderDeferred[ "composite" ];
-
-	//
-
-	var compColor, compNormal, compDepth, compLight, compFinal;
-	var passColor, passNormal, passDepth, passLightFullscreen, passLightProxy, compositePass;
-
-	var effectFXAA;
-
-	//
-
-	var lightSceneFullscreen, lightSceneProxy;
-
-	//
-
-	var resizableMaterials = [];
-
-	//
-
-	var invisibleMaterial = new THREE.ShaderMaterial();
-	invisibleMaterial.visible = false;
-
-
-	var defaultNormalDepthMaterial = new THREE.ShaderMaterial( {
-
-		uniforms:       THREE.UniformsUtils.clone( normalDepthShader.uniforms ),
-		vertexShader:   normalDepthShader.vertexShader,
-		fragmentShader: normalDepthShader.fragmentShader,
-		blending:       THREE.NoBlending,
-		derivatives:    true
-
-	} );
-
-	//
-
-	var initDeferredMaterials = function ( object ) {
-
-		if ( object.material instanceof THREE.MeshFaceMaterial ) {
-
-			var colorMaterials = [];
-			var normalDepthMaterials = [];
-
-			var materials = object.material.materials;
-
-			for ( var i = 0, il = materials.length; i < il; i ++ ) {
-
-				var deferredMaterials = createDeferredMaterials( materials[ i ] );
-
-				if ( deferredMaterials.transparent ) {
-
-					colorMaterials.push( invisibleMaterial );
-					normalDepthMaterials.push( invisibleMaterial );
-
-				} else {
-
-					colorMaterials.push( deferredMaterials.colorMaterial );
-					normalDepthMaterials.push( deferredMaterials.normalDepthMaterial );
-
-				}
-
-			}
-
-			object.userData.colorMaterial = new THREE.MeshFaceMaterial( colorMaterials );
-			object.userData.normalDepthMaterial = new THREE.MeshFaceMaterial( normalDepthMaterials );
-
-		} else {
-
-			var deferredMaterials = createDeferredMaterials( object.material );
-
-			object.userData.colorMaterial = deferredMaterials.colorMaterial;
-			object.userData.normalDepthMaterial = deferredMaterials.normalDepthMaterial;
-			object.userData.transparent = deferredMaterials.transparent;
-
-		}
-
-	};
-
-	var createDeferredMaterials = function ( originalMaterial ) {
-
-		var deferredMaterials = {};
-
-		// color material
-		// -----------------
-		// 	diffuse color
-		//	specular color
-		//	shininess
-		//	diffuse map
-		//	vertex colors
-		//	alphaTest
-		// 	morphs
-
-		var uniforms = THREE.UniformsUtils.clone( colorShader.uniforms );
-		var defines = { "USE_MAP": !! originalMaterial.map, "USE_ENVMAP": !! originalMaterial.envMap, "GAMMA_INPUT": true };
-
-		var material = new THREE.ShaderMaterial( {
-
-			fragmentShader: colorShader.fragmentShader,
-			vertexShader: 	colorShader.vertexShader,
-			uniforms: 		uniforms,
-			defines: 		defines,
-			shading:		originalMaterial.shading
-
-		} );
-
-		if ( originalMaterial instanceof THREE.MeshBasicMaterial ) {
-
-			var diffuse = black;
-			var emissive = originalMaterial.color;
-
-		} else {
-
-			var diffuse = originalMaterial.color;
-			var emissive = originalMaterial.emissive !== undefined ? originalMaterial.emissive : black;
-
-		}
-
-		var specular = originalMaterial.specular !== undefined ? originalMaterial.specular : black;
-		var shininess = originalMaterial.shininess !== undefined ? originalMaterial.shininess : 1;
-		var wrapAround = originalMaterial.wrapAround !== undefined ? ( originalMaterial.wrapAround ? - 1 : 1 ) : 1;
-		var additiveSpecular = originalMaterial.metal !== undefined ? ( originalMaterial.metal ? 1 : - 1 ) : - 1;
-
-		uniforms.emissive.value.copyGammaToLinear( emissive );
-		uniforms.diffuse.value.copyGammaToLinear( diffuse );
-		uniforms.specular.value.copyGammaToLinear( specular );
-		uniforms.shininess.value = shininess;
-		uniforms.wrapAround.value = wrapAround;
-		uniforms.additiveSpecular.value = additiveSpecular;
-
-		uniforms.map.value = originalMaterial.map;
-
-		if ( originalMaterial.envMap ) {
-
-			uniforms.envMap.value = originalMaterial.envMap;
-			uniforms.refractionRatio.value = originalMaterial.refractionRatio;
-			uniforms.reflectivity.value = originalMaterial.reflectivity;
-			uniforms.flipEnvMap.value = ( originalMaterial.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
-
-			uniforms.samplerNormalDepth.value = compNormalDepth.renderTarget2;
-			uniforms.viewWidth.value = scaledWidth;
-			uniforms.viewHeight.value = scaledHeight;
-
-			resizableMaterials.push( { "material": material } );
-
-		}
-
-		material.vertexColors = originalMaterial.vertexColors;
-		material.morphTargets = originalMaterial.morphTargets;
-		material.morphNormals = originalMaterial.morphNormals;
-		material.skinning = originalMaterial.skinning;
-
-		material.alphaTest = originalMaterial.alphaTest;
-		material.wireframe = originalMaterial.wireframe;
-
-		// uv repeat and offset setting priorities
-		//	1. color map
-		//	2. specular map
-		//	3. normal map
-		//	4. bump map
-
-		var uvScaleMap;
-
-		if ( originalMaterial.map ) {
-
-			uvScaleMap = originalMaterial.map;
-
-		} else if ( originalMaterial.specularMap ) {
-
-			uvScaleMap = originalMaterial.specularMap;
-
-		} else if ( originalMaterial.normalMap ) {
-
-			uvScaleMap = originalMaterial.normalMap;
-
-		} else if ( originalMaterial.bumpMap ) {
-
-			uvScaleMap = originalMaterial.bumpMap;
-
-		}
-
-		if ( uvScaleMap !== undefined ) {
-
-			var offset = uvScaleMap.offset;
-			var repeat = uvScaleMap.repeat;
-
-			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
-
-		}
-
-		deferredMaterials.colorMaterial = material;
-
-		// normal + depth material
-		// -----------------
-		//	vertex normals
-		//	morph normals
-		//	bump map
-		//	bump scale
-		//  clip depth
-
-		if ( originalMaterial.morphTargets || originalMaterial.skinning || originalMaterial.bumpMap ) {
-
-			var uniforms = THREE.UniformsUtils.clone( normalDepthShader.uniforms );
-			var defines = { "USE_BUMPMAP": !! originalMaterial.bumpMap };
-
-			var normalDepthMaterial = new THREE.ShaderMaterial( {
-
-				uniforms:       uniforms,
-				vertexShader:   normalDepthShader.vertexShader,
-				fragmentShader: normalDepthShader.fragmentShader,
-				shading:        originalMaterial.shading,
-				defines:        defines,
-				blending:       THREE.NoBlending,
-				derivatives:    true
-
-			} );
-
-			normalDepthMaterial.morphTargets = originalMaterial.morphTargets;
-			normalDepthMaterial.morphNormals = originalMaterial.morphNormals;
-			normalDepthMaterial.skinning = originalMaterial.skinning;
-
-			if ( originalMaterial.bumpMap ) {
-
-				uniforms.bumpMap.value = originalMaterial.bumpMap;
-				uniforms.bumpScale.value = originalMaterial.bumpScale;
-
-				var offset = originalMaterial.bumpMap.offset;
-				var repeat = originalMaterial.bumpMap.repeat;
-
-				uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
-
-			}
-
-		} else {
-
-			var normalDepthMaterial = defaultNormalDepthMaterial.clone();
-
-		}
-
-		normalDepthMaterial.wireframe = originalMaterial.wireframe;
-		normalDepthMaterial.vertexColors = originalMaterial.vertexColors;
-
-		deferredMaterials.normalDepthMaterial = normalDepthMaterial;
-
-		//
-
-		deferredMaterials.transparent = originalMaterial.transparent;
-
-		return deferredMaterials;
-
-	};
-
-	var updatePointLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		// skip infinite pointlights
-		// right now you can't switch between infinite and finite pointlights
-		// it's just too messy as they use different proxies
-
-		var distance = light.distance;
-
-		if ( distance > 0 ) {
-
-			lightProxy.scale.set( 1, 1, 1 ).multiplyScalar( distance );
-			uniforms[ "lightRadius" ].value = distance;
-
-			positionVS.setFromMatrixPosition( light.matrixWorld );
-			positionVS.applyMatrix4( currentCamera.matrixWorldInverse );
-
-			uniforms[ "lightPositionVS" ].value.copy( positionVS );
-
-			lightProxy.position.setFromMatrixPosition( light.matrixWorld );
-
-		} else {
-
-			uniforms[ "lightRadius" ].value = Infinity;
-
-		}
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredPointLight = function ( light ) {
-
-		// setup light material
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       THREE.UniformsUtils.clone( pointLightShader.uniforms ),
-			vertexShader:   pointLightShader.vertexShader,
-			fragmentShader: pointLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			transparent:	true,
-
-			side: THREE.BackSide
-
-		} );
-
-		// infinite pointlights use full-screen quad proxy
-		// regular pointlights use sphere proxy
-
-		var  geometry;
-
-		if ( light.distance > 0 ) {
-
-			geometry = geometryLightSphere;
-
-		} else {
-
-			geometry = geometryLightPlane;
-
-			materialLight.depthTest = false;
-			materialLight.side = THREE.FrontSide;
-
-		}
-
-		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
-		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
-
-		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometry, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updatePointLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateSpotLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		var viewMatrix = currentCamera.matrixWorldInverse;
-		var modelMatrix = light.matrixWorld;
-
-		positionVS.setFromMatrixPosition( modelMatrix );
-		positionVS.applyMatrix4( viewMatrix );
-
-		directionVS.setFromMatrixPosition( modelMatrix );
-		tempVS.setFromMatrixPosition( light.target.matrixWorld );
-		directionVS.sub( tempVS );
-		directionVS.normalize();
-		directionVS.transformDirection( viewMatrix );
-
-		uniforms[ "lightPositionVS" ].value.copy( positionVS );
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		uniforms[ "lightAngle" ].value = light.angle;
-		uniforms[ "lightDistance" ].value = light.distance;
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredSpotLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( spotLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   spotLightShader.vertexShader,
-			fragmentShader: spotLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateSpotLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateDirectionalLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		directionVS.setFromMatrixPosition( light.matrixWorld );
-		tempVS.setFromMatrixPosition( light.target.matrixWorld );
-		directionVS.sub( tempVS );
-		directionVS.normalize();
-		directionVS.transformDirection( currentCamera.matrixWorldInverse );
-
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredDirectionalLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( directionalLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   directionalLightShader.vertexShader,
-			fragmentShader: directionalLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateDirectionalLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateHemisphereLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		directionVS.setFromMatrixPosition( light.matrixWorld );
-		directionVS.normalize();
-		directionVS.transformDirection( currentCamera.matrixWorldInverse );
-
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColorSky" ].value.copyGammaToLinear( light.color );
-		uniforms[ "lightColorGround" ].value.copyGammaToLinear( light.groundColor );
-
-	};
-
-	var createDeferredHemisphereLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( hemisphereLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   hemisphereLightShader.vertexShader,
-			fragmentShader: hemisphereLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateHemisphereLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateAreaLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		var modelMatrix = light.matrixWorld;
-		var viewMatrix = currentCamera.matrixWorldInverse;
-
-		positionVS.setFromMatrixPosition( modelMatrix );
-		positionVS.applyMatrix4( viewMatrix );
-
-		uniforms[ "lightPositionVS" ].value.copy( positionVS );
-
-		rightVS.copy( light.right );
-		rightVS.transformDirection( modelMatrix );
-		rightVS.transformDirection( viewMatrix );
-
-		normalVS.copy( light.normal );
-		normalVS.transformDirection( modelMatrix );
-		normalVS.transformDirection( viewMatrix );
-
-		upVS.crossVectors( rightVS, normalVS );
-		upVS.normalize();
-
-		uniforms[ "lightRightVS" ].value.copy( rightVS );
-		uniforms[ "lightNormalVS" ].value.copy( normalVS );
-		uniforms[ "lightUpVS" ].value.copy( upVS );
-
-		uniforms[ "lightWidth" ].value = light.width;
-		uniforms[ "lightHeight" ].value = light.height;
-
-		uniforms[ "constantAttenuation" ].value = light.constantAttenuation;
-		uniforms[ "linearAttenuation" ].value = light.linearAttenuation;
-		uniforms[ "quadraticAttenuation" ].value = light.quadraticAttenuation;
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredAreaLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( areaLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   areaLightShader.vertexShader,
-			fragmentShader: areaLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateAreaLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var createDeferredEmissiveLight = function () {
-
-		// setup light material
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       THREE.UniformsUtils.clone( emissiveLightShader.uniforms ),
-			vertexShader:   emissiveLightShader.vertexShader,
-			fragmentShader: emissiveLightShader.fragmentShader,
-			depthTest:		false,
-			depthWrite:		false,
-			blending:		THREE.NoBlending
-
-		} );
-
-		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
-		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
-
-		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		return meshLight;
-
-	};
-
-	var initDeferredProperties = function ( object ) {
-
-		if ( object.userData.deferredInitialized ) return;
-
-		if ( object.material ) initDeferredMaterials( object );
-
-		if ( object instanceof THREE.PointLight ) {
-
-			var proxy = createDeferredPointLight( object );
-
-			if ( object.distance > 0 ) {
-
-				lightSceneProxy.add( proxy );
-
-			} else {
-
-				lightSceneFullscreen.add( proxy );
-
-			}
-
-		} else if ( object instanceof THREE.SpotLight ) {
-
-			var proxy = createDeferredSpotLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.DirectionalLight ) {
-
-			var proxy = createDeferredDirectionalLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.HemisphereLight ) {
-
-			var proxy = createDeferredHemisphereLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.AreaLight ) {
-
-			var proxy = createDeferredAreaLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		}
-
-		object.userData.deferredInitialized = true;
-
-	};
-
-	//
-
-	var setMaterialColor = function ( object ) {
-
-		if ( object.material ) {
-
-			if ( object.userData.transparent ) {
-
-				object.material = invisibleMaterial;
-
-			} else {
-
-				object.material = object.userData.colorMaterial;
-
-			}
-
-		}
-
-	};
-
-	var setMaterialNormalDepth = function ( object ) {
-
-		if ( object.material ) {
-
-			if ( object.userData.transparent ) {
-
-				object.material = invisibleMaterial;
-
-			} else {
-
-				object.material = object.userData.normalDepthMaterial;
-
-			}
-
-		}
-
-	};
-
-	// external API
-
-	this.setAntialias = function ( enabled ) {
-
-		antialias = enabled;
-
-		if ( antialias ) {
-
-			effectFXAA.enabled = true;
-			compositePass.renderToScreen = false;
-
-		} else {
-
-			effectFXAA.enabled = false;
-			compositePass.renderToScreen = true;
-
-		}
-
-	};
-
-	this.getAntialias = function () {
-
-		return antialias;
-
-	};
-
-	this.addEffect = function ( effect, normalDepthUniform, colorUniform ) {
-
-		if ( effect.material && effect.uniforms ) {
-
-			if ( normalDepthUniform ) effect.uniforms[ normalDepthUniform ].value = compNormalDepth.renderTarget2;
-			if ( colorUniform )    	  effect.uniforms[ colorUniform ].value = compColor.renderTarget2;
-
-			if ( normalDepthUniform || colorUniform ) {
-
-				resizableMaterials.push( { "material": effect.material, "normalDepth": normalDepthUniform, "color": colorUniform } );
-
-			}
-
-		}
-
-		compFinal.insertPass( effect, - 1 );
-
-	};
-
-	this.setScale = function ( scale ) {
-
-		currentScale = scale;
-
-		scaledWidth = Math.floor( currentScale * pixelWidth );
-		scaledHeight = Math.floor( currentScale * pixelHeight );
-
-		compNormalDepth.setSize( scaledWidth, scaledHeight );
-		compColor.setSize( scaledWidth, scaledHeight );
-		compLight.setSize( scaledWidth, scaledHeight );
-		compFinal.setSize( scaledWidth, scaledHeight );
-
-		compColor.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-		compLight.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		for ( var i = 0, il = resizableMaterials.length; i < il; i ++ ) {
-
-			var materialEntry = resizableMaterials[ i ];
-
-			var material = materialEntry.material;
-			var uniforms = material.uniforms;
-
-			var colorLabel = materialEntry.color !== undefined ? materialEntry.color : 'samplerColor';
-			var normalDepthLabel = materialEntry.normalDepth !== undefined ? materialEntry.normalDepth : 'samplerNormalDepth';
-
-			if ( uniforms[ colorLabel ] ) uniforms[ colorLabel ].value = compColor.renderTarget2;
-			if ( uniforms[ normalDepthLabel ] ) uniforms[ normalDepthLabel ].value = compNormalDepth.renderTarget2;
-
-			if ( uniforms[ 'viewWidth' ] ) uniforms[ "viewWidth" ].value = scaledWidth;
-			if ( uniforms[ 'viewHeight' ] ) uniforms[ "viewHeight" ].value = scaledHeight;
-
-		}
-
-		compositePass.uniforms[ 'samplerLight' ].value = compLight.renderTarget2;
-
-		effectFXAA.uniforms[ 'resolution' ].value.set( 1 / pixelWidth, 1 / pixelHeight );
-
-	};
-
-	this.setSize = function ( width, height ) {
-
-		pixelWidth = width;
-		pixelHeight = height;
-
-		this.renderer.setSize( pixelWidth, pixelHeight );
-
-		this.setScale( currentScale );
-
-	};
-
-	//
-
-	function updateLightProxy ( proxy ) {
-
-		var uniforms = proxy.material.uniforms;
-
-		if ( uniforms[ "matProjInverse" ] ) uniforms[ "matProjInverse" ].value = projectionMatrixInverse;
-		if ( uniforms[ "matView" ] ) uniforms[ "matView" ].value = currentCamera.matrixWorldInverse;
-
-		var originalLight = proxy.userData.originalLight;
-
-		if ( originalLight ) {
-
-			proxy.visible = originalLight.visible;
-
-			if ( originalLight instanceof THREE.PointLight ) {
-
-				updatePointLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.SpotLight ) {
-
-				updateSpotLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.DirectionalLight ) {
-
-				updateDirectionalLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.HemisphereLight ) {
-
-				updateHemisphereLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.AreaLight ) {
-
-				updateAreaLightProxy( proxy );
-
-			}
-
-		}
-
-	}
-
-	this.render = function ( scene, camera ) {
-
-		// setup deferred properties
-
-		if ( ! scene.userData.lightSceneProxy ) {
-
-			scene.userData.lightSceneProxy = new THREE.Scene();
-			scene.userData.lightSceneFullscreen = new THREE.Scene();
-
-			var meshLight = createDeferredEmissiveLight();
-			scene.userData.lightSceneFullscreen.add( meshLight );
-
-		}
-
-		currentCamera = camera;
-
-		lightSceneProxy = scene.userData.lightSceneProxy;
-		lightSceneFullscreen = scene.userData.lightSceneFullscreen;
-
-		passColor.camera = currentCamera;
-		passNormalDepth.camera = currentCamera;
-		passLightProxy.camera = currentCamera;
-		passLightFullscreen.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-
-		passColor.scene = scene;
-		passNormalDepth.scene = scene;
-		passLightFullscreen.scene = lightSceneFullscreen;
-		passLightProxy.scene = lightSceneProxy;
-
-		scene.traverse( initDeferredProperties );
-
-		// update scene graph only once per frame
-		// (both color and normalDepth passes use exactly the same scene state)
-
-		scene.autoUpdate = false;
-		scene.updateMatrixWorld();
-
-		// 1) g-buffer normals + depth pass
-
-		scene.traverse( setMaterialNormalDepth );
-
-		// clear shared depth buffer
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = true;
-
-		// write 1 to shared stencil buffer
-		// for non-background pixels
-
-		//gl.enable( gl.STENCIL_TEST );
-		gl.stencilOp( gl.REPLACE, gl.REPLACE, gl.REPLACE );
-		gl.stencilFunc( gl.ALWAYS, 1, 0xffffffff );
-		gl.clearStencil( 0 );
-
-		compNormalDepth.render();
-
-		// just touch foreground pixels (stencil == 1)
-		// both in color and light passes
-
-		gl.stencilFunc( gl.EQUAL, 1, 0xffffffff );
-		gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP );
-
-		// 2) g-buffer color pass
-
-		scene.traverse( setMaterialColor );
-
-		// must use clean slate depth buffer
-		// otherwise there are z-fighting glitches
-		// not enough precision between two geometry passes
-		// just to use EQUAL depth test
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = false;
-
-		compColor.render();
-
-		// 3) light pass
-
-		// do not clear depth buffer in this pass
-		// depth from geometry pass is used for light culling
-		// (write light proxy color pixel if behind scene pixel)
-
-		this.renderer.autoClearDepth = false;
-
-		scene.autoUpdate = true;
-
-		gl.depthFunc( gl.GEQUAL );
-
-		projectionMatrixInverse.getInverse( currentCamera.projectionMatrix );
-
-		for ( var i = 0, il = lightSceneProxy.children.length; i < il; i ++ ) {
-
-			var proxy = lightSceneProxy.children[ i ];
-			updateLightProxy( proxy );
-
-		}
-
-		for ( var i = 0, il = lightSceneFullscreen.children.length; i < il; i ++ ) {
-
-			var proxy = lightSceneFullscreen.children[ i ];
-			updateLightProxy( proxy );
-
-		}
-
-		compLight.render();
-
-		// 4) composite pass
-
-		// return back to usual depth and stencil handling state
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = true;
-		gl.depthFunc( gl.LEQUAL );
-		gl.disable( gl.STENCIL_TEST );
-
-		compFinal.render( 0.1 );
-
-	};
-
-	//
-
-	var createRenderTargets = function ( ) {
-
-		var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: true,
-									format: THREE.RGBAFormat, type: THREE.FloatType };
-
-		var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: true,
-									 format: THREE.RGBAFormat, type: THREE.FloatType };
-
-		var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-							  format: THREE.RGBFormat, type: THREE.UnsignedByteType };
-
-		// g-buffers
-
-		var rtColor   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatNearest );
-		var rtNormalDepth = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatNearest );
-		var rtLight   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatLinear );
-		var rtFinal   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsUByte );
-
-		rtColor.generateMipmaps = false;
-		rtNormalDepth.generateMipmaps = false;
-		rtLight.generateMipmaps = false;
-		rtFinal.generateMipmaps = false;
-
-		// normal + depth composer
-
-		passNormalDepth = new THREE.RenderPass();
-		passNormalDepth.clear = true;
-
-		compNormalDepth = new THREE.EffectComposer( _this.renderer, rtNormalDepth );
-		compNormalDepth.addPass( passNormalDepth );
-
-		// color composer
-
-		passColor = new THREE.RenderPass();
-		passColor.clear = true;
-
-		compColor = new THREE.EffectComposer( _this.renderer, rtColor );
-		compColor.addPass( passColor );
-
-		compColor.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		// light composer
-
-		passLightFullscreen = new THREE.RenderPass();
-		passLightFullscreen.clear = true;
-
-		passLightProxy = new THREE.RenderPass();
-		passLightProxy.clear = false;
-
-		compLight = new THREE.EffectComposer( _this.renderer, rtLight );
-		compLight.addPass( passLightFullscreen );
-		compLight.addPass( passLightProxy );
-
-		compLight.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		// final composer
-
-		compositePass = new THREE.ShaderPass( compositeShader );
-		compositePass.uniforms[ 'samplerLight' ].value = compLight.renderTarget2;
-		compositePass.uniforms[ 'brightness' ].value = brightness;
-		compositePass.material.blending = THREE.NoBlending;
-		compositePass.clear = true;
-
-		var defines;
-
-		switch ( tonemapping ) {
-
-			case THREE.SimpleOperator:    defines = { "TONEMAP_SIMPLE": true };    break;
-			case THREE.LinearOperator:    defines = { "TONEMAP_LINEAR": true };    break;
-			case THREE.ReinhardOperator:  defines = { "TONEMAP_REINHARD": true };  break;
-			case THREE.FilmicOperator:    defines = { "TONEMAP_FILMIC": true };    break;
-			case THREE.UnchartedOperator: defines = { "TONEMAP_UNCHARTED": true }; break;
-
-		}
-
-		compositePass.material.defines = defines;
-
-		// FXAA
-
-		effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
-		effectFXAA.uniforms[ 'resolution' ].value.set( 1 / pixelWidth, 1 / pixelHeight );
-		effectFXAA.renderToScreen = true;
-
-		//
-
-		compFinal = new THREE.EffectComposer( _this.renderer, rtFinal );
-		compFinal.addPass( compositePass );
-		compFinal.addPass( effectFXAA );
-
-		if ( antialias ) {
-
-			effectFXAA.enabled = true;
-			compositePass.renderToScreen = false;
-
-		} else {
-
-			effectFXAA.enabled = false;
-			compositePass.renderToScreen = true;
-
-		}
-
-	};
-
-	// init
-
-	createRenderTargets();
-
-};
-
-// tonemapping operator types
-
-THREE.NoOperator = 0;
-THREE.SimpleOperator = 1;
-THREE.LinearOperator = 2;
-THREE.ReinhardOperator = 3;
-THREE.FilmicOperator = 4;
-THREE.UnchartedOperator = 5;

+ 0 - 515
examples/js/shaders/NormalDisplacementShader.js

@@ -1,515 +0,0 @@
-/*
- * @author alteredq / http://alteredqualia.com/
- *
- * Normal map shader
- *  - Blinn-Phong
- *  - normal + diffuse + specular + AO + displacement + reflection + shadow maps
- *  - point and directional lights (use with "lights: true" material option)
- */
-
-THREE.NormalDisplacementShader = {
-
-	uniforms: THREE.UniformsUtils.merge( [
-
-		THREE.UniformsLib[ "fog" ],
-		THREE.UniformsLib[ "lights" ],
-		THREE.UniformsLib[ "shadowmap" ],
-
-		{
-
-			"enableAO"          : { type: "i", value: 0 },
-			"enableDiffuse"     : { type: "i", value: 0 },
-			"enableSpecular"    : { type: "i", value: 0 },
-			"enableReflection"  : { type: "i", value: 0 },
-			"enableDisplacement": { type: "i", value: 0 },
-
-			"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: "v2", value: new THREE.Vector2( 1, 1 ) },
-
-			"uDisplacementBias": { type: "f", value: 0.0 },
-			"uDisplacementScale": { type: "f", value: 1.0 },
-
-			"diffuse": { type: "c", value: new THREE.Color( 0xffffff ) },
-			"specular": { type: "c", value: new THREE.Color( 0x111111 ) },
-			"shininess": { type: "f", value: 30 },
-			"opacity": { type: "f", value: 1 },
-
-			"refractionRatio": { type: "f", value: 0.98 },
-			"reflectivity": { type: "f", value: 0.5 },
-
-			"uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) },
-			"uRepeat" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
-
-		}
-
-	] ),
-
-	fragmentShader: [
-
-		"uniform vec3 diffuse;",
-		"uniform vec3 specular;",
-		"uniform float shininess;",
-		"uniform float opacity;",
-
-		"uniform bool enableDiffuse;",
-		"uniform bool enableSpecular;",
-		"uniform bool enableAO;",
-		"uniform bool enableReflection;",
-
-		"uniform sampler2D tDiffuse;",
-		"uniform sampler2D tNormal;",
-		"uniform sampler2D tSpecular;",
-		"uniform sampler2D tAO;",
-
-		"uniform samplerCube tCube;",
-
-		"uniform vec2 uNormalScale;",
-
-		"uniform float refractionRatio;",
-		"uniform float reflectivity;",
-
-		"varying vec3 vTangent;",
-		"varying vec3 vBinormal;",
-		"varying vec3 vNormal;",
-		"varying vec2 vUv;",
-
-		"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 hemisphereLightDirection[ 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",
-
-		"#if MAX_SPOT_LIGHTS > 0",
-
-		"	uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
-		"	uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
-		"	uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
-
-		"#endif",
-
-		"varying vec3 vWorldPosition;",
-		"varying vec3 vViewPosition;",
-
-		THREE.ShaderChunk[ "common" ],
-		THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-		THREE.ShaderChunk[ "fog_pars_fragment" ],
-		THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
-
-		"void main() {",
-
-			THREE.ShaderChunk[ "logdepthbuf_fragment" ],
-
-		"	vec3 outgoingLight = vec3( 0.0 );",
-
-		"	vec4 diffuseColor = vec4( diffuse, opacity );",
-
-		"	vec3 specularTex = vec3( 1.0 );",
-
-		"	vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
-		"	normalTex.xy *= uNormalScale;",
-		"	normalTex = normalize( normalTex );",
-
-		"	if( enableDiffuse ) {",
-
-		"		#ifdef GAMMA_INPUT",
-
-		"			vec4 texelColor = texture2D( tDiffuse, vUv );",
-		"			texelColor.xyz *= texelColor.xyz;",
-
-		"			diffuseColor *= texelColor;",
-
-		"		#else",
-
-		"			diffuseColor *= texture2D( tDiffuse, vUv );",
-
-		"		#endif",
-
-		"	}",
-
-		"	if( enableAO ) {",
-
-		"		diffuseColor.rgb *= texture2D( tAO, vUv ).xyz;", // actually, the AOmap should be modulating ambient light sources only,
-																 // and should use the second set of UVs, as is done elsewhere in the library
-		"	}",
-
-			THREE.ShaderChunk[ "alphatest_fragment" ],
-
-		"	if( enableSpecular )",
-		"		specularTex = texture2D( tSpecular, vUv ).xyz;",
-
-		"	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 );",
-
-		"	vec3 totalDiffuseLight = vec3( 0.0 );",
-		"	vec3 totalSpecularLight = vec3( 0.0 );",
-
-			// point lights
-
-		"	#if MAX_POINT_LIGHTS > 0",
-
-		"		for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
-
-		"			vec3 pointVector = pointLightPosition[ i ] + vViewPosition.xyz;",
-
-		"			float pointDistance = 1.0;",
-		"			if ( pointLightDistance[ i ] > 0.0 )",
-		"				pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );",
-
-		"			pointVector = normalize( pointVector );",
-
-					// diffuse
-
-		"			float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
-
-		"			totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
-
-					// specular
-
-		"			vec3 pointHalfVector = normalize( pointVector + viewPosition );",
-		"			float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
-		"			float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
-
-		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( pointVector, pointHalfVector ), 0.0 ), 5.0 );",
-		"			totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
-
-		"		}",
-
-		"	#endif",
-
-			// spot lights
-
-		"	#if MAX_SPOT_LIGHTS > 0",
-
-		"		for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
-
-		"			vec3 spotVector = spotLightPosition[ i ] + vViewPosition.xyz;",
-
-		"			float spotDistance = 1.0;",
-		"			if ( spotLightDistance[ i ] > 0.0 )",
-		"				spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );",
-
-		"			spotVector = normalize( spotVector );",
-
-		"			float spotEffect = dot( spotLightDirection[ i ], spotVector );",
-
-		"			if ( spotEffect > spotLightAngleCos[ i ] ) {",
-
-		"				spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );",
-
-						// diffuse
-
-
-		"				float spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );",
-
-		"				totalDiffuseLight += spotDistance * spotLightColor[ i ] * spotDiffuseWeight * spotEffect;",
-
-						// specular
-
-		"				vec3 spotHalfVector = normalize( spotVector + viewPosition );",
-		"				float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
-		"				float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, shininess ), 0.0 );",
-
-		"				float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"				vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( spotVector, spotHalfVector ), 0.0 ), 5.0 );",
-		"				totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
-
-		"			}",
-
-		"		}",
-
-		"	#endif",
-
-			// directional lights
-
-		"	#if MAX_DIR_LIGHTS > 0",
-
-		"		for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
-
-		"			vec3 dirVector = directionalLightDirection[ i ];",
-
-					// diffuse
-
-		"			float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
-
-		"			totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-
-					// specular
-
-		"			vec3 dirHalfVector = normalize( dirVector + viewPosition );",
-		"			float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
-		"			float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
-
-		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );",
-		"			totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
-
-		"		}",
-
-		"	#endif",
-
-			// hemisphere lights
-
-		"	#if MAX_HEMI_LIGHTS > 0",
-
-		"		for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
-
-		"			vec3 lVector = hemisphereLightDirection[ i ];",
-
-					// diffuse
-
-		"			float dotProduct = dot( normal, lVector );",
-		"			float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
-
-		"			vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
-
-		"			totalDiffuseLight += hemiColor;",
-
-					// specular (sky light)
-
-		"			vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
-		"			float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
-		"			float hemiSpecularWeightSky = specularTex.r * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );",
-
-					//
-
-		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"			vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );",
-		"			totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) );",
-
-		"		}",
-
-		"	#endif",
-
-		"	#ifdef METAL",
-
-		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );",
-
-		"	#else",
-
-		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight;",
-
-		"	#endif",
-
-		"	if ( enableReflection ) {",
-
-		"		vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
-
-		"		vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );",
-
-		"		#ifdef ENVMAP_MODE_REFLECTION",
-
-		"			vec3 vReflect = reflect( cameraToVertex, worldNormal );",
-
-		"		#else",
-
-		"			vec3 vReflect = refract( cameraToVertex, worldNormal, refractionRatio );",
-
-		"		#endif",
-
-		"		vec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
-
-		"		#ifdef GAMMA_INPUT",
-
-		"			cubeColor.xyz *= cubeColor.xyz;",
-
-		"		#endif",
-
-		"		outgoingLight = mix( outgoingLight, cubeColor.xyz, specularTex.r * reflectivity );",
-
-		"	}",
-
-			THREE.ShaderChunk[ "shadowmap_fragment" ],
-			THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ],
-
-		"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
-
-		"}"
-
-	].join( "\n" ),
-
-	vertexShader: [
-
-		"attribute vec4 tangent;",
-
-		"uniform vec2 uOffset;",
-		"uniform vec2 uRepeat;",
-
-		"uniform bool enableDisplacement;",
-
-		"#ifdef VERTEX_TEXTURES",
-
-		"	uniform sampler2D tDisplacement;",
-		"	uniform float uDisplacementScale;",
-		"	uniform float uDisplacementBias;",
-
-		"#endif",
-
-		"varying vec3 vTangent;",
-		"varying vec3 vBinormal;",
-		"varying vec3 vNormal;",
-		"varying vec2 vUv;",
-
-		"varying vec3 vWorldPosition;",
-		"varying vec3 vViewPosition;",
-
-		THREE.ShaderChunk[ "skinning_pars_vertex" ],
-		THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-		THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
-
-		"void main() {",
-
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-
-			// normal, tangent and binormal vectors
-
-		"	#ifdef USE_SKINNING",
-
-		"		vNormal = normalize( normalMatrix * skinnedNormal.xyz );",
-
-		"		vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
-		"		vTangent = normalize( normalMatrix * skinnedTangent.xyz );",
-
-		"	#else",
-
-		"		vNormal = normalize( normalMatrix * normal );",
-		"		vTangent = normalize( normalMatrix * tangent.xyz );",
-
-		"	#endif",
-
-		"	vBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );",
-
-		"	vUv = uv * uRepeat + uOffset;",
-
-			// displacement mapping
-
-		"	vec3 displacedPosition;",
-
-		"	#ifdef VERTEX_TEXTURES",
-
-		"		if ( enableDisplacement ) {",
-
-		"			vec3 dv = texture2D( tDisplacement, uv ).xyz;",
-		"			float df = uDisplacementScale * dv.x + uDisplacementBias;",
-		"			displacedPosition = position + normalize( normal ) * df;",
-
-		"		} else {",
-
-		"			#ifdef USE_SKINNING",
-
-		"				vec4 skinVertex = bindMatrix * vec4( position, 1.0 );",
-
-		"				vec4 skinned = vec4( 0.0 );",
-		"				skinned += boneMatX * skinVertex * skinWeight.x;",
-		"				skinned += boneMatY * skinVertex * skinWeight.y;",
-		"				skinned += boneMatZ * skinVertex * skinWeight.z;",
-		"				skinned += boneMatW * skinVertex * skinWeight.w;",
-		"				skinned  = bindMatrixInverse * skinned;",
-
-		"				displacedPosition = skinned.xyz;",
-
-		"			#else",
-
-		"				displacedPosition = position;",
-
-		"			#endif",
-
-		"		}",
-
-		"	#else",
-
-		"		#ifdef USE_SKINNING",
-
-		"			vec4 skinVertex = bindMatrix * vec4( position, 1.0 );",
-
-		"			vec4 skinned = vec4( 0.0 );",
-		"			skinned += boneMatX * skinVertex * skinWeight.x;",
-		"			skinned += boneMatY * skinVertex * skinWeight.y;",
-		"			skinned += boneMatZ * skinVertex * skinWeight.z;",
-		"			skinned += boneMatW * skinVertex * skinWeight.w;",
-		"			skinned  = bindMatrixInverse * skinned;",
-
-		"			displacedPosition = skinned.xyz;",
-
-		"		#else",
-
-		"			displacedPosition = position;",
-
-		"		#endif",
-
-		"	#endif",
-
-			//
-
-		"	vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
-		"	vec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
-
-		"	gl_Position = projectionMatrix * mvPosition;",
-
-			THREE.ShaderChunk[ "logdepthbuf_vertex" ],
-
-			//
-
-		"	vWorldPosition = worldPosition.xyz;",
-		"	vViewPosition = - mvPosition.xyz;",
-
-			// shadows
-
-		"	#ifdef USE_SHADOWMAP",
-
-		"		for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
-
-		"			vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;",
-
-		"		}",
-
-		"	#endif",
-
-		"}"
-
-	].join( "\n" )
-
-};

+ 3 - 0
examples/misc_animation_keys.html

@@ -37,6 +37,9 @@
 		</div>
 
 		<script src="../build/three.min.js"></script>
+		<script src="js/loaders/collada/Animation.js"></script>
+		<script src="js/loaders/collada/AnimationHandler.js"></script>
+		<script src="js/loaders/collada/KeyFrameAnimation.js"></script>
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 

+ 13 - 14
examples/misc_controls_fly.html

@@ -108,20 +108,19 @@
 				scene.add( dirLight );
 
 				var materialNormalMap = new THREE.MeshPhongMaterial( {
-				
+
 					specular: 0x333333,
 					shininess: 15,
 					map: THREE.ImageUtils.loadTexture( "textures/planets/earth_atmos_2048.jpg" ),
 					specularMap: THREE.ImageUtils.loadTexture( "textures/planets/earth_specular_2048.jpg" ),
 					normalMap: THREE.ImageUtils.loadTexture( "textures/planets/earth_normal_2048.jpg" ),
 					normalScale: new THREE.Vector2( 0.85, 0.85 )
-				
+
 				} );
 
 				// planet
 
 				geometry = new THREE.SphereGeometry( radius, 100, 50 );
-				geometry.computeTangents();
 
 				meshPlanet = new THREE.Mesh( geometry, materialNormalMap );
 				meshPlanet.rotation.y = 0;
@@ -131,10 +130,10 @@
 				// clouds
 
 				var materialClouds = new THREE.MeshLambertMaterial( {
-				
+
 					map: THREE.ImageUtils.loadTexture( "textures/planets/earth_clouds_1024.png" ),
 					transparent: true
-				
+
 				} );
 
 				meshClouds = new THREE.Mesh( geometry, materialClouds );
@@ -145,9 +144,9 @@
 				// moon
 
 				var materialMoon = new THREE.MeshPhongMaterial( {
-				
+
 					map: THREE.ImageUtils.loadTexture( "textures/planets/moon_1024.jpg" )
-				
+
 				} );
 
 				meshMoon = new THREE.Mesh( geometry, materialMoon );
@@ -185,17 +184,17 @@
 
 				var stars;
 				var starsMaterials = [
-					new THREE.PointCloudMaterial( { color: 0x555555, size: 2, sizeAttenuation: false } ),
-					new THREE.PointCloudMaterial( { color: 0x555555, size: 1, sizeAttenuation: false } ),
-					new THREE.PointCloudMaterial( { color: 0x333333, size: 2, sizeAttenuation: false } ),
-					new THREE.PointCloudMaterial( { color: 0x3a3a3a, size: 1, sizeAttenuation: false } ),
-					new THREE.PointCloudMaterial( { color: 0x1a1a1a, size: 2, sizeAttenuation: false } ),
-					new THREE.PointCloudMaterial( { color: 0x1a1a1a, size: 1, sizeAttenuation: false } )
+					new THREE.PointsMaterial( { color: 0x555555, size: 2, sizeAttenuation: false } ),
+					new THREE.PointsMaterial( { color: 0x555555, size: 1, sizeAttenuation: false } ),
+					new THREE.PointsMaterial( { color: 0x333333, size: 2, sizeAttenuation: false } ),
+					new THREE.PointsMaterial( { color: 0x3a3a3a, size: 1, sizeAttenuation: false } ),
+					new THREE.PointsMaterial( { color: 0x1a1a1a, size: 2, sizeAttenuation: false } ),
+					new THREE.PointsMaterial( { color: 0x1a1a1a, size: 1, sizeAttenuation: false } )
 				];
 
 				for ( i = 10; i < 30; i ++ ) {
 
-					stars = new THREE.PointCloud( starsGeometry[ i % 2 ], starsMaterials[ i % 6 ] );
+					stars = new THREE.Points( starsGeometry[ i % 2 ], starsMaterials[ i % 6 ] );
 
 					stars.rotation.x = Math.random() * 6;
 					stars.rotation.y = Math.random() * 6;

+ 51 - 25
examples/misc_controls_transform.html

@@ -26,7 +26,7 @@
 
 		<div id="info">
 		"W" translate | "E" rotate | "R" scale | "+" increase size | "-" decrease size<br />
-		Press "Q" twice to toggle world/local space
+		Press "Q" to toggle world/local space, keep "Ctrl" down to snap to grid
 		</div>
 
 		<script src="../build/three.min.js"></script>
@@ -79,30 +79,56 @@
 				window.addEventListener( 'resize', onWindowResize, false );
 
 				window.addEventListener( 'keydown', function ( event ) {
-		            //console.log(event.which);
-		            switch ( event.keyCode ) {
-		              case 81: // Q
-		                control.setSpace( control.space == "local" ? "world" : "local" );
-		                break;
-		              case 87: // W
-		                control.setMode( "translate" );
-		                break;
-		              case 69: // E
-		                control.setMode( "rotate" );
-		                break;
-		              case 82: // R
-		                control.setMode( "scale" );
-		                break;
-					case 187:
-					case 107: // +,=,num+
-						control.setSize( control.size + 0.1 );
-						break;
-					case 189:
-					case 109: // -,_,num-
-						control.setSize( Math.max(control.size - 0.1, 0.1 ) );
-						break;
-		            }
-        		});
+
+					switch ( event.keyCode ) {
+
+						case 81: // Q
+							control.setSpace( control.space === "local" ? "world" : "local" );
+							break;
+
+						case 17: // Ctrl
+							control.setTranslationSnap( 100 );
+							control.setRotationSnap( THREE.Math.degToRad( 15 ) );
+							break;
+
+						case 87: // W
+							control.setMode( "translate" );
+							break;
+
+						case 69: // E
+							control.setMode( "rotate" );
+							break;
+
+						case 82: // R
+							control.setMode( "scale" );
+							break;
+
+						case 187:
+						case 107: // +, =, num+
+							control.setSize( control.size + 0.1 );
+							break;
+
+						case 189:
+						case 109: // -, _, num-
+							control.setSize( Math.max( control.size - 0.1, 0.1 ) );
+							break;
+
+					}
+
+				});
+
+				window.addEventListener( 'keyup', function ( event ) {
+
+					switch ( event.keyCode ) {
+
+						case 17: // Ctrl
+							control.setTranslationSnap( null );
+							control.setRotationSnap( null );
+							break;
+
+					}
+
+				});
 
 			}
 

File diff suppressed because it is too large
+ 1 - 0
examples/models/amf/rook.amf


File diff suppressed because it is too large
+ 0 - 43
examples/models/animated/elderlyWalk.js


+ 121 - 0
examples/models/json/blend-animation.json

@@ -0,0 +1,121 @@
+{
+    "metadata": {
+        "generator": "io_three",
+        "type": "Object",
+        "version": 4.3
+    },
+    "textures": [],
+    "geometries": [{
+        "uuid": "9C17D067-6185-36C2-898A-43F0618F9682",
+        "type": "Geometry",
+        "data": {
+            "skinWeights": [],
+            "skinIndices": [],
+            "faces": [42,0,2,3,0,0,1,2,0,1,2,42,3,1,0,0,2,3,0,2,3,0,42,4,5,7,0,3,0,1,4,5,6,42,7,6,4,0,1,2,3,6,7,4,42,0,1,9,0,3,0,4,0,3,8,42,9,8,0,0,4,5,3,8,9,0,42,8,9,13,0,5,4,6,9,8,10,42,13,12,8,0,6,7,5,10,11,9,42,12,13,17,0,7,6,8,11,10,12,42,17,16,12,0,8,9,7,12,13,11,42,16,17,21,0,9,8,10,13,12,14,42,21,20,16,0,10,11,9,14,15,13,42,20,21,5,0,11,10,1,15,14,5,42,5,4,20,0,1,2,11,5,4,15,42,1,3,10,0,3,0,4,3,2,16,42,10,9,1,0,4,5,3,16,8,3,42,9,10,14,0,5,4,6,8,16,17,42,14,13,9,0,6,7,5,17,10,8,42,13,14,18,0,7,6,8,10,17,18,42,18,17,13,0,8,9,7,18,12,10,42,17,18,22,0,9,8,10,12,18,19,42,22,21,17,0,10,11,9,19,14,12,42,21,22,7,0,11,10,1,14,19,6,42,7,5,21,0,1,2,11,6,5,14,42,3,2,11,0,3,0,4,2,1,20,42,11,10,3,0,4,5,3,20,16,2,42,10,11,15,0,5,4,6,16,20,21,42,15,14,10,0,6,7,5,21,17,16,42,14,15,19,0,7,6,8,17,21,22,42,19,18,14,0,8,9,7,22,18,17,42,33,34,35,0,9,8,10,23,24,25,42,35,32,33,0,10,11,9,25,26,23,42,22,23,6,0,11,10,1,19,27,7,42,6,7,22,0,1,2,11,7,6,19,42,2,0,8,0,3,0,4,1,0,9,42,8,11,2,0,4,5,3,9,20,1,42,11,8,12,0,5,4,6,20,9,11,42,12,15,11,0,6,7,5,11,21,20,42,15,12,16,0,7,6,8,21,11,13,42,16,19,15,0,8,9,7,13,22,21,42,19,16,20,0,9,8,10,22,13,15,42,20,23,19,0,10,11,9,15,27,22,42,23,20,4,0,11,10,1,27,15,4,42,4,6,23,0,1,2,11,4,7,27,42,25,24,22,0,9,11,10,28,29,19,42,22,18,25,0,10,8,9,19,18,28,42,26,25,18,0,8,9,9,30,28,18,42,18,19,26,0,9,8,8,18,22,30,42,27,26,19,0,10,8,9,31,30,22,42,19,23,27,0,9,11,10,22,27,31,42,24,27,23,0,11,10,10,29,31,27,42,23,22,24,0,10,11,11,27,19,29,42,29,28,24,0,9,11,11,28,29,29,42,24,25,29,0,11,9,9,29,28,28,42,30,29,25,0,8,9,9,30,28,28,42,25,26,30,0,9,8,8,28,30,30,42,31,30,26,0,10,8,8,31,30,30,42,26,27,31,0,8,10,10,30,31,31,42,28,31,27,0,11,10,10,29,31,31,42,27,24,28,0,10,11,11,31,29,29,42,33,32,28,0,9,11,11,23,26,29,42,28,29,33,0,11,9,9,29,28,23,42,34,33,29,0,8,9,9,24,23,28,42,29,30,34,0,9,8,8,28,30,24,42,35,34,30,0,10,8,8,25,24,30,42,30,31,35,0,8,10,10,30,31,25,42,32,35,31,0,11,10,10,26,25,31,42,31,28,32,0,10,11,11,31,29,26],
+            "morphTargets": [{
+                "name": "T",
+                "vertices": [[-4,0.620216,-4],[4,0.620216,-4],[-4,0.620216,4],[4,0.620216,4],[-2.34599,-60.3799,-2.34599],[2.34599,-60.3799,-2.34599],[-2.34599,-60.3799,2.34599],[2.34599,-60.3799,2.34599],[-3.05437,-11.951,-3.05437],[3.05437,-11.951,-3.05437],[3.05437,-11.951,3.05437],[-3.05437,-11.951,3.05437],[-3.05437,-26.2605,-3.05437],[3.05437,-26.2605,-3.05437],[3.05437,-26.2605,3.05437],[-3.05437,-26.2605,3.05437],[-2.91343,-43.3116,-2.91343],[2.91343,-43.3116,-2.91343],[2.91343,-43.3116,2.91343],[-2.91343,-43.3116,2.91343],[-2.91343,-47.6772,-2.91343],[2.91343,-47.6772,-2.91343],[2.91343,-47.6772,2.91343],[-2.91343,-47.6772,2.91343],[2.91343,-47.6772,9.18208],[2.91343,-43.3116,9.18208],[-2.91343,-43.3116,9.18208],[-2.91343,-47.6772,9.18208],[2.91343,-47.6772,14.6098],[2.91343,-43.3116,14.6098],[-2.91343,-43.3116,14.6098],[-2.91343,-47.6772,14.6098],[2.91343,-47.6772,18.4439],[2.91343,-43.3116,18.4439],[-2.91343,-43.3116,18.4439],[-2.91343,-47.6772,18.4439]]
+            }],
+            "uvs": [[1,0,1,1,0,1,0,0,1,0.2,0,0.2,1,0.4,0,0.4,1,0.6,0,0.6,1,0.8,0,0.8]],
+            "influencesPerVertex": 2,
+            "metadata": {
+                "morphTargets": 1,
+                "normals": 32,
+                "version": 3,
+                "vertices": 36,
+                "faces": 68,
+                "materials": 1,
+                "generator": "io_three",
+                "uvs": 1,
+                "bones": 0
+            },
+            "normals": [-0.586627,0.558306,-0.586627,-0.586627,0.558306,0.586627,0.586627,0.558306,0.586627,0.586627,0.558306,-0.586627,-0.571917,-0.588,-0.571917,0.571917,-0.588,-0.571917,0.571917,-0.588,0.571917,-0.571917,-0.588,0.571917,0.706839,-0.02591,-0.706839,-0.706839,-0.02591,-0.706839,0.707083,-0.005799,-0.707083,-0.707083,-0.005799,-0.707083,0.707083,-0.00586,-0.707083,-0.707083,-0.00586,-0.707083,0.707022,-0.014252,-0.707022,-0.707022,-0.014252,-0.707022,0.706839,-0.02591,0.706839,0.707083,-0.005799,0.707083,0.905728,0.296365,0.302957,0.901486,-0.313913,0.29783,-0.706839,-0.02591,0.706839,-0.707083,-0.005799,0.707083,-0.905728,0.296365,0.302957,0.577349,0.577349,0.577349,-0.577349,0.577349,0.577349,-0.577349,-0.577349,0.577349,0.577349,-0.577349,0.577349,-0.901486,-0.313913,0.29783,0.707083,0.707083,0,0.707083,-0.707083,0,-0.707083,0.707083,0,-0.707083,-0.707083,0],
+            "bones": [],
+            "animations": {
+                "morphTargets[T]": [{
+                    "time": 0,
+                    "value": 0
+                },{
+                    "time": 10,
+                    "value": 0
+                },{
+                    "time": 50,
+                    "value": 0.5
+                },{
+                    "time": 95,
+                    "value": 1
+                },{
+                    "time": 110,
+                    "value": 1
+                },{
+                    "time": 140,
+                    "value": 0
+                },{
+                    "time": 150,
+                    "value": 0
+                }]
+            },
+            "name": "test-objGeometry",
+            "vertices": [-4,0.620216,-4,4,0.620216,-4,-4,0.620216,4,4,0.620216,4,-2.34599,-89.0885,-2.34599,2.34599,-89.0885,-2.34599,-2.34599,-89.0885,2.34599,2.34599,-89.0885,2.34599,-3.05437,-25.4524,-3.05437,3.05437,-25.4524,-3.05437,3.05437,-25.4524,3.05437,-3.05437,-25.4524,3.05437,-3.05437,-39.7619,-3.05437,3.05437,-39.7619,-3.05437,3.05437,-39.7619,3.05437,-3.05437,-39.7619,3.05437,-2.91343,-56.813,-2.91343,2.91343,-56.813,-2.91343,2.91343,-56.813,2.91343,-2.91343,-56.813,2.91343,-2.91343,-61.1786,-2.91343,2.91343,-61.1786,-2.91343,2.91343,-61.1786,2.91343,-2.91343,-61.1786,2.91343,2.91343,-61.1786,12.081,2.91343,-56.813,12.081,-2.91343,-56.813,12.081,-2.91343,-61.1786,12.081,2.91343,-61.1786,23.2496,2.91343,-56.813,23.2496,-2.91343,-56.813,23.2496,-2.91343,-61.1786,23.2496,2.91343,-61.1786,35.7722,2.91343,-56.813,35.7722,-2.91343,-56.813,35.7722,-2.91343,-61.1786,35.7722]
+        },
+        "materials": [{
+            "opacity": 1,
+            "colorAmbient": [0.8,0.8,0.8],
+            "doubleSided": true,
+            "depthWrite": true,
+            "depthTest": true,
+            "colorDiffuse": [0.8,0.8,0.8],
+            "DbgName": "01-default",
+            "specularCoef": 50,
+            "colorSpecular": [0.44902,0.44902,0.44902],
+            "shading": "phong",
+            "DbgIndex": 0,
+            "DbgColor": 15658734,
+            "visible": true,
+            "blending": "NormalBlending",
+            "wireframe": false,
+            "colorEmissive": [0,0,0],
+            "transparent": false
+        }]
+    }],
+    "materials": [{
+        "ambient": 13421772,
+        "depthWrite": true,
+        "depthTest": true,
+        "specular": 7500402,
+        "name": "01-default",
+        "emissive": 0,
+        "shininess": 50,
+        "color": 13421772,
+        "uuid": "8DC6308D-11A2-3251-91BC-D52FB2C734BD",
+        "type": "MeshPhongMaterial",
+        "blending": "NormalBlending",
+        "vertexColors": false
+    }],
+    "object": {
+        "uuid": "13D0028E-5D9E-44AF-BB17-B385656A35C6",
+        "type": "Scene",
+        "children": [{
+            "type": "Object",
+            "name": "lighthaus-test-morph01",
+            "uuid": "C3F5BA0D-BEB5-3118-9CF8-738E95FF4EF3",
+            "matrix": [-1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1],
+            "visible": true,
+            "animations": {},
+            "children": [{
+                "type": "Mesh",
+                "name": "test-obj",
+                "uuid": "1202E101-A129-3E65-A14B-8546898B2323",
+                "matrix": [1,0,0,0,0,-0,-1,0,0,1,-0,0,0,-0,0.563976,1],
+                "visible": true,
+                "material": "8DC6308D-11A2-3251-91BC-D52FB2C734BD",
+                "castShadow": true,
+                "receiveShadow": true,
+                "geometry": "9C17D067-6185-36C2-898A-43F0618F9682",
+                "animations": {}
+            }]
+        }],
+        "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
+    },
+    "images": []
+}

File diff suppressed because it is too large
+ 2696 - 0
examples/models/json/scene-animation.json


BIN
examples/models/sea3d/flag.sea


BIN
examples/models/sea3d/flag.tjs.sea


BIN
examples/models/sea3d/keyframe.tjs.sea


BIN
examples/models/sea3d/mascot.tjs.sea


BIN
examples/models/sea3d/morph.tjs.sea


BIN
examples/models/sea3d/robot.tjs.sea


BIN
examples/models/sea3d/skin.tjs.sea


BIN
examples/models/sea3d/sound.tjs.sea


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