Forráskód Böngészése

Merge branch 'dev' of [email protected]:mrdoob/three.js into simplified_lighting

Conflicts:
	examples/webgl_lights_hemisphere.html
	examples/webgl_morphnormals.html
	src/renderers/shaders/ShaderChunk/common.glsl
	src/renderers/shaders/ShaderChunk/hemilight_fragment.glsl
	src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl
	src/renderers/shaders/ShaderChunk/lights_pars.glsl
	src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl
	src/renderers/shaders/ShaderLib.js
	utils/build/includes/common.json
Ben Houston 9 éve
szülő
commit
fdaad8df8b
100 módosított fájl, 4650 hozzáadás és 2720 törlés
  1. 254 383
      build/three.js
  2. 293 253
      build/three.min.js
  3. 0 7
      docs/api/core/Geometry.html
  4. 2 2
      docs/api/examples/SpriteCanvasMaterial.html
  5. 2 2
      docs/api/extras/geometries/TextGeometry.html
  6. 1 7
      docs/api/lights/DirectionalLight.html
  7. 0 6
      docs/api/lights/SpotLight.html
  8. 77 89
      docs/api/loaders/JSONLoader.html
  9. 1 1
      docs/api/materials/MeshPhongMaterial.html
  10. 9 9
      docs/api/math/Box2.html
  11. 14 14
      docs/api/math/Box3.html
  12. 7 16
      docs/api/math/Math.html
  13. 1 1
      docs/api/math/Matrix4.html
  14. 4 4
      docs/api/math/Plane.html
  15. 9 9
      docs/api/math/Ray.html
  16. 161 161
      docs/api/renderers/CanvasRenderer.html
  17. 1 0
      docs/index.html
  18. 3 4
      docs/list.js
  19. 32 30
      docs/scenes/geometry-browser.html
  20. 1 1
      docs/scenes/js/material.js
  21. 1 0
      editor/css/dark.css
  22. 1 0
      editor/css/light.css
  23. 12 0
      editor/css/main.css
  24. 11 19
      editor/index.html
  25. 1 0
      editor/js/Config.js
  26. 3 9
      editor/js/Editor.js
  27. 25 8
      editor/js/Loader.js
  28. 21 21
      editor/js/Menubar.File.js
  29. 10 6
      editor/js/Menubar.Status.js
  30. 4 0
      editor/js/Sidebar.Animation.js
  31. 23 3
      editor/js/Sidebar.Geometry.CircleGeometry.js
  32. 1 1
      editor/js/Sidebar.Material.js
  33. 67 2
      editor/js/Sidebar.Object3D.js
  34. 43 16
      editor/js/Sidebar.Project.js
  35. 2 2
      editor/js/Storage.js
  36. 7 8
      editor/js/Toolbar.js
  37. 4 0
      editor/js/Viewport.js
  38. 21 21
      editor/js/libs/app.js
  39. 0 160
      editor/js/libs/tern-threejs/threejs.js
  40. 103 74
      editor/js/libs/ui.js
  41. 1 1
      examples/canvas_geometry_panorama_fisheye.html
  42. 8 4
      examples/canvas_geometry_text.html
  43. 2 2
      examples/canvas_interactive_cubes.html
  44. 2 2
      examples/canvas_interactive_cubes_tween.html
  45. 2 2
      examples/canvas_interactive_voxelpainter.html
  46. 0 1
      examples/canvas_materials.html
  47. 0 238
      examples/canvas_materials_depth.html
  48. 10 4
      examples/canvas_morphtargets_horse.html
  49. 8 3
      examples/index.html
  50. 6 5
      examples/js/ShaderSkin.js
  51. 2 2
      examples/js/controls/EditorControls.js
  52. 2 2
      examples/js/controls/OrbitControls.js
  53. 2 2
      examples/js/controls/OrthographicTrackballControls.js
  54. 2 2
      examples/js/controls/TrackballControls.js
  55. 0 0
      examples/js/geometries/TextGeometry.js
  56. 674 0
      examples/js/libs/earcut.js
  57. 475 328
      examples/js/loaders/AMFLoader.js
  58. 3 5
      examples/js/loaders/ColladaLoader.js
  59. 865 0
      examples/js/loaders/ColladaLoader2.js
  60. 54 0
      examples/js/loaders/KMZLoader.js
  61. 1 1
      examples/js/loaders/MTLLoader.js
  62. 1 1
      examples/js/loaders/SVGLoader.js
  63. 146 32
      examples/js/loaders/VRMLLoader.js
  64. 716 258
      examples/js/loaders/sea3d/SEA3D.js
  65. 244 152
      examples/js/loaders/sea3d/SEA3DLoader.js
  66. 0 5
      examples/js/postprocessing/GlitchPass.js
  67. 1 1
      examples/js/renderers/CSS3DRenderer.js
  68. 1 1
      examples/js/renderers/CSS3DStereoRenderer.js
  69. 14 15
      examples/js/renderers/CanvasRenderer.js
  70. 19 19
      examples/js/renderers/Projector.js
  71. 2 8
      examples/js/renderers/SVGRenderer.js
  72. 13 205
      examples/js/utils/FontUtils.js
  73. 136 0
      examples/js/utils/ImageUtils.js
  74. 3 3
      examples/js/utils/ShadowMapViewer.js
  75. 1 0
      examples/misc_controls_pointerlock.html
  76. 1 1
      examples/misc_lookat.html
  77. 1 0
      examples/models/amf/rook.amf
  78. 0 1
      examples/models/animated/horse.js
  79. 0 1
      examples/models/animated/monster/monster.js
  80. 0 2
      examples/models/animated/sittingBox.js
  81. 0 1
      examples/models/animated/stork.js
  82. 0 8
      examples/models/ctm/camaro/camaro.js
  83. 0 1
      examples/models/json/blend-animation.json
  84. 0 0
      examples/models/md2/ratamahatta/w_chaingun.md2
  85. 0 0
      examples/models/obj/tree.obj
  86. 0 1
      examples/models/skinned/UCS/umich_ucs.js
  87. 0 1
      examples/models/skinned/knight.js
  88. 0 1
      examples/models/skinned/marine/m4.js
  89. 0 1
      examples/models/skinned/marine/marine.js
  90. 0 1
      examples/models/skinned/marine/marine_anims.js
  91. 0 1
      examples/models/skinned/marine/marine_ikrig.js
  92. 0 1
      examples/models/skinned/simple/simple.js
  93. 0 1
      examples/obj/blenderscene/scene.Cube.js
  94. 0 1
      examples/obj/blenderscene/scene.Monkey.js
  95. 0 1
      examples/obj/blenderscene/scene.Plane.js
  96. 0 9
      examples/obj/camaro/CamaroNoUv_bin.js
  97. 0 1
      examples/obj/cubecolors/cube_fvc.js
  98. 0 1
      examples/obj/cubecolors/cubecolors.js
  99. 0 25
      examples/obj/f50/F50NoUv_bin.js
  100. 0 6
      examples/obj/female02/Female02_bin.js

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 254 - 383
build/three.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 293 - 253
build/three.min.js


+ 0 - 7
docs/api/core/Geometry.html

@@ -88,13 +88,6 @@
 		Morph vertices match number and order of primary vertices.
 		</div>
 
-		<h3>[property:Array morphColors]</h3>
-		<div>
-		Array of morph colors. Morph colors have similar structure as morph targets, each color set is a Javascript object:
-		<code>morphColor = { name: "colorName", colors: [ new THREE.Color(), ... ] }</code>
-		Morph colors can match either the number and order of faces (face colors) or the number of vertices (vertex colors).
-		</div>
-
 		<h3>[property:Array morphNormals]</h3>
 		<div>
 		Array of morph normals. Morph normals have similar structure as morph targets, each normal set is a Javascript object:

+ 2 - 2
docs/api/materials/SpriteCanvasMaterial.html → docs/api/examples/SpriteCanvasMaterial.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>
@@ -52,6 +52,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CanvasRenderer.js examples/js/renderers/CanvasRenderer.js]
 	</body>
 </html>

+ 2 - 2
docs/api/extras/geometries/TextGeometry.html

@@ -93,13 +93,13 @@
 				<td>/examples/fonts/gentilis_bold.typeface.js</td>
 			</tr>
 			<tr>
-				<td>driod sans</td>
+				<td>droid sans</td>
 				<td>normal</td>
 				<td>normal</td>
 				<td>/examples/fonts/droid/droid_sans_regular.typeface.js</td>
 			</tr>
 			<tr>
-				<td>driod sans</td>
+				<td>droid sans</td>
 				<td>bold</td>
 				<td>normal</td>
 				<td>/examples/fonts/droid/droid_sans_bold.typeface.js</td>

+ 1 - 7
docs/api/lights/DirectionalLight.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>
@@ -123,12 +123,6 @@ scene.add( directionalLight );</code>
 			Default — *0*.
 		</div>
 
-		<h3>[property:Float shadowDarkness]</h3>
-		<div>
-			Darkness of shadow casted by this light (from *0* to *1*).<br />
-			Default — *0.5*.
-		</div>
-
 		<h3>[property:Integer shadowMapWidth]</h3>
 		<div>
 			Shadow map texture width in pixels.<br />

+ 0 - 6
docs/api/lights/SpotLight.html

@@ -146,12 +146,6 @@
 			Default — *0*.
 		</div>
 
-		<h3>[property:Float shadowDarkness]</h3>
-		<div>
-			Darkness of shadow casted by this light (from *0* to *1*).<br />
-			Default — *0.5*.
-		</div>
-
 		<h3>[property:Integer shadowMapWidth]</h3>
 		<div>
 			Shadow map texture width in pixels.<br />

+ 77 - 89
docs/api/loaders/JSONLoader.html

@@ -1,90 +1,78 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!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:Loader] &rarr;
-		<h1>[name]</h1>
-
-		<div class="desc">A loader for loading objects in JSON format.</div>
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]()</h3>
-		<div>
-		Creates a new [name].
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>[property:boolean withCredentials]</h3>
-		<div>
-		If true, the ajax request will use cookies.
-		</div>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null load]( [page:String url], [page:Function callback], [page:String texturePath] )</h3>
-		<div>
-		[page:String url] — required<br />
-		[page:Function callback] — required. Will be called when load completes. The arguments will be the loaded [page:Object3D] and the loaded [page:Array materials].<br />
-		[page:String texturePath] — optional. If not specified, textures will be assumed to be in the same folder as the Javascript model file.
-		</div>
-
-		<h3>[method:null loadAjaxJSON]([page:JSONLoader context], [page:String url], [page:Function callback], [page:String texturePath], [page:Function callbackProgress])</h3>
-		<div>
-		[page:JSONLoader context] — The [page:JSONLoader] instance<br />
-		[page:String url] — required<br />
-		[page:Function callback] — required. This function will be called with the loaded model as an instance of [page:Geometry geometry] when the load is completed.<br />
-		[page:String texturePath] — Base path for textures.<br />
-		[page:Function callbackProgress] — Will be called while load progresses. The argument will be an [page:Object] containing two attributes: .[page:Integer total] and .[page:Integer loaded] bytes.
-		</div>
-		<div>
-		Begin loading from url and call <em>callback</em> with the parsed response content.
-		</div>
-
-		<h3>[method:Object3D parse]( [page:Object json], [page:String texturePath] )</h3>
-		<div>
-		[page:String json] — JSON object to parse.<br />
-		[page:String texturePath] — Base path for textures.
-		</div>
-		<div>
-		Parse a <em>JSON</em> structure and return an [page:Object] containing the parsed .[page:Geometry] and .[page:Array materials].
-		</div>
-
-
-		<h2>Example</h2>
-
-		<code>
-		// instantiate a loader
-		var loader = new THREE.JSONLoader();
-
-		// load a resource
-		loader.load(
-			// resource URL
-			'models/animated/monster/monster.js',
-			// Function when resource is loaded
-			function ( geometry, materials ) {
-				var material = new THREE.MeshFaceMaterial( materials );
-				var object = new THREE.Mesh( geometry, material );
-				scene.add( object );
-			}
-		);
-		</code>
-
-		[example:webgl_loader_json_blender]
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Loader] &rarr;
+		<h1>[name]</h1>
+
+		<div class="desc">A loader for loading objects in JSON format.</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+		<div>
+		Creates a new [name].
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<h3>[property:boolean withCredentials]</h3>
+		<div>
+		If true, the ajax request will use cookies.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null load]( [page:String url], [page:Function callback], [page:String texturePath] )</h3>
+		<div>
+		[page:String url] — required<br />
+		[page:Function callback] — required. Will be called when load completes. The arguments will be the loaded [page:Object3D] and the loaded [page:Array materials].<br />
+		[page:String texturePath] — optional. If not specified, textures will be assumed to be in the same folder as the Javascript model file.
+		</div>
+
+		<h3>[method:Object3D parse]( [page:Object json], [page:String texturePath] )</h3>
+		<div>
+		[page:String json] — JSON object to parse.<br />
+		[page:String texturePath] — Base path for textures.
+		</div>
+		<div>
+		Parse a <em>JSON</em> structure and return an [page:Object] containing the parsed .[page:Geometry] and .[page:Array materials].
+		</div>
+
+
+		<h2>Example</h2>
+
+		<code>
+		// instantiate a loader
+		var loader = new THREE.JSONLoader();
+
+		// load a resource
+		loader.load(
+			// resource URL
+			'models/animated/monster/monster.js',
+			// Function when resource is loaded
+			function ( geometry, materials ) {
+				var material = new THREE.MeshFaceMaterial( materials );
+				var object = new THREE.Mesh( geometry, material );
+				scene.add( object );
+			}
+		);
+		</code>
+
+		[example:webgl_loader_json_blender]
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

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

@@ -68,7 +68,7 @@
 		</div>
 
 		<h3>[property:Float shininess]</h3>
-		<div>How shiny the specular highlight is; a higher value gives a sharper highlight. Default is *30*. It should not be set to 0.</div>
+		<div>How shiny the specular highlight is; a higher value gives a sharper highlight. Default is *30*.</div>
 
 		<h3>[property:boolean metal]</h3>
 		<div>

+ 9 - 9
docs/api/math/Box2.html

@@ -22,7 +22,7 @@
 		max -- Upper (x, y) boundary of the box.
 		</div>
 		<div>
-		Creates a box bounded by min and max. 
+		Creates a box bounded by min and max.
 		</div>
 
 
@@ -33,12 +33,12 @@
 		<h3>[property:Vector2 min]</h3>
 		<div>
 		Lower (x, y) boundary of this box.
-		</div> 
+		</div>
 
 		<h3>[property:Vector2 max]</h3>
 		<div>
 		Upper (x, y) boundary of this box.
-		</div> 
+		</div>
 
 		<h2>Methods</h2>
 
@@ -70,7 +70,7 @@
 		Clamps *point* within the bounds of this box.
 		</div>
 
-		<h3>[method:Boolean isIntersectionBox]([page:Box2 box])</h3>
+		<h3>[method:Boolean intersectsBox]([page:Box2 box])</h3>
 		<div>
 		box -- Box to check for intersection against.
 		</div>
@@ -99,7 +99,7 @@
 		box -- Box that will be unioned with this box.
 		</div>
 		<div>
-		Unions this box with *box* setting the upper bound of this box to the greater of the 
+		Unions this box with *box* setting the upper bound of this box to the greater of the
 		two boxes' upper bounds and the lower bound of this box to the lesser of the two boxes'
 		lower bounds.
 		</div>
@@ -108,7 +108,7 @@
 		<div>
 		point -- [page:Vector2]<br/>
 		optionalTarget -- [page:Vector2]<br/>
-		
+
 		</div>
 		<div>
 		Returns a point as a proportion of this box's width and height.
@@ -139,7 +139,7 @@
 		</div>
 		<div>
 		Returns true if this box includes the entirety of *box*. If this and *box* overlap exactly,</br>
-		this function also returns true. 
+		this function also returns true.
 		</div>
 
 		<h3>[method:Box2 translate]([page:Vector2 offset]) [page:Box2 this]</h3>
@@ -177,7 +177,7 @@
 		</div>
 		<div>
 		Expands this box equilaterally by *vector*. The width of this box will be
-		expanded by the x component of *vector* in both directions. The height of 
+		expanded by the x component of *vector* in both directions. The height of
 		this box will be expanded by the y component of *vector* in both directions.
 		</div>
 
@@ -222,7 +222,7 @@
 		<h3>[method:Box2 setFromCenterAndSize]([page:Vector2 center], [page:Vector2 size]) [page:Box2 this]</h3>
 		<div>
 		center -- Desired center position of the box. <br />
-		size -- Desired x and y dimensions of the box. 
+		size -- Desired x and y dimensions of the box.
 		</div>
 		<div>
 		Centers this box on *center* and sets this box's width and height to the values specified

+ 14 - 14
docs/api/math/Box3.html

@@ -22,7 +22,7 @@
 		max -- Upper (x, y, z) boundary of the box.
 		</div>
 		<div>
-		Creates a box bounded by min and max. 
+		Creates a box bounded by min and max.
 		</div>
 
 		<h2>Properties</h2>
@@ -37,7 +37,7 @@
 		<h3>[property:Vector3 max]</h3>
 		<div>
 		Upper (x, y, z) boundary of this box.
-		</div> 
+		</div>
 
 		<h2>Methods</h2>
 
@@ -51,7 +51,7 @@
 		<div>
 		Sets the lower and upper (x, y, z) boundaries of this box.
 		</div>
-		
+
 		<h3>[method:Box3 applyMatrix4]([page:Matrix4 matrix]) [page:Box3 this]</h3>
 		<div>
 		matrix -- The [page:Matrix4] to apply
@@ -69,7 +69,7 @@
 		Clamps *point* within the bounds of this box.
 		</div>
 
-		<h3>[method:Boolean isIntersectionBox]([page:Box3 box])</h3>
+		<h3>[method:Boolean intersectsBox]([page:Box3 box])</h3>
 		<div>
 		box -- Box to check for intersection against.
 		</div>
@@ -84,7 +84,7 @@
 		<div>
 		Sets the upper and lower bounds of this box to include all of the points in *points*.
 		</div>
-		
+
 		<h3>[method:Box3 setFromObject]([page:Object3D object]) [page:Box3 this]</h3>
 		<div>
 		object -- [page:Object3D] to compute the bounding box for.
@@ -93,8 +93,8 @@
 		Computes the world-axis-aligned bounding box of an object (including its children),
 		accounting for both the object's, and childrens', world transforms
 		</div>
-		
-		
+
+
 
 		<h3>[method:Vector3 size]([page:Vector3 optionalTarget])</h3>
 		<div>
@@ -109,7 +109,7 @@
 		box -- Box that will be unioned with this box.
 		</div>
 		<div>
-		Unions this box with *box* setting the upper bound of this box to the greater of the 
+		Unions this box with *box* setting the upper bound of this box to the greater of the
 		two boxes' upper bounds and the lower bound of this box to the lesser of the two boxes'
 		lower bounds.
 		</div>
@@ -139,7 +139,7 @@
 		</div>
 		<div>
 		Returns true if this box includes the entirety of *box*. If this and *box* overlap exactly,</br>
-		this function also returns true. 
+		this function also returns true.
 		</div>
 
 		<h3>[method:Boolean containsPoint]([page:Vector3 point])</h3>
@@ -149,7 +149,7 @@
 		<div>
 		Returns true if the specified point lies within the boundaries of this box.
 		</div>
-		
+
 		<h3>[method:Box3 translate]([page:Vector3 offset]) [page:Box3 this]</h3>
 		<div>
 		offset -- Direction and distance of offset.
@@ -186,7 +186,7 @@
 		<div>
 		Expands the boundaries of this box to include *point*.
 		</div>
-		
+
 		<h3>[method:Box3 expandByScalar]([page:float scalar]) [page:Box3 this]</h3>
 		<div>
 		scalar -- Distance to expand.
@@ -195,14 +195,14 @@
 		Expands each dimension of the box by *scalar*. If negative, the dimensions of the box <br/>
 		will be contracted.
 		</div>
-		
+
 		<h3>[method:Box3 expandByVector]([page:Vector3 vector]) [page:Box3 this]</h3>
 		<div>
 		vector -- Amount to expand this box in each dimension.
 		</div>
 		<div>
 		Expands this box equilaterally by *vector*. The width of this box will be
-		expanded by the x component of *vector* in both directions. The height of 
+		expanded by the x component of *vector* in both directions. The height of
 		this box will be expanded by the y component of *vector* in both directions.
 		The depth of this box will be expanded by the z component of *vector* in
 		both directions.
@@ -249,7 +249,7 @@
 		<h3>[method:Box3 setFromCenterAndSize]([page:Vector3 center], [page:Vector3 size]) [page:Box3 this]</h3>
 		<div>
 		center -- Desired center position of the box. <br />
-		size -- Desired x and y dimensions of the box. 
+		size -- Desired x and y dimensions of the box.
 		</div>
 		<div>
 		Centers this box on *center* and sets this box's width and height to the values specified

+ 7 - 16
docs/api/math/Math.html

@@ -16,23 +16,14 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Float clamp]( [page:Float x], [page:Float a], [page:Float b] )</h3>
+		<h3>[method:Float clamp]( [page:Float value], [page:Float min], [page:Float max] )</h3>
 		<div>
-		x — Value to be clamped.<br />
-		a — Minimum value<br />
-		b — Maximum value.
+		value — Value to be clamped.<br />
+		min — Minimum value<br />
+		max — Maximum value.
 		</div>
 		<div>
-		Clamps the *x* to be between *a* and *b*.
-		</div>
-
-		<h3>[method:Float clampBottom]( [page:Float x], [page:Float a] )</h3>
-		<div>
-		x — Value to be clamped.<br />
-		a — Minimum value
-		</div>
-		<div>
-		Clamps the *x* to be larger than *a*.
+		Clamps the *value* to be between *min* and *max*.
 		</div>
 
 		<h3>[method:Float mapLinear]( [page:Float x], [page:Float a1], [page:Float a2], [page:Float b1], [page:Float b2] )</h3>
@@ -97,7 +88,7 @@
 		</div>
 		<div>
 		Returns a value between 0-1 that represents the percentage that x has moved between min and max, but smoothed or slowed down the closer X is to the min and max.<br/><br/>
-		
+
 		[link:http://en.wikipedia.org/wiki/Smoothstep Wikipedia]
 		</div>
 
@@ -110,7 +101,7 @@
 		<div>
 		Returns a value between 0-1. It works the same as smoothstep, but more smooth.
 		</div>
-		
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

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

@@ -223,7 +223,7 @@
 		Creates a perspective projection matrix.
 		</div>
 
-		<h3>[method:Matrix4 makeOrthographic]( [page:Float left], [page:Float right], [page:Float bottom], [page:Float top], [page:Float near], [page:Float far] ) [page:Matrix4 this]</h3>
+		<h3>[method:Matrix4 makeOrthographic]( [page:Float left], [page:Float right], [page:Float top], [page:Float bottom], [page:Float near], [page:Float far] ) [page:Matrix4 this]</h3>
 		<div>
 		Creates an orthographic projection matrix.
 		</div>

+ 4 - 4
docs/api/math/Plane.html

@@ -28,7 +28,7 @@
 		<h3>[property:Vector3 normal]</h3>
 
 		<h3>[property:Float constant]</h3>
-		
+
 		<h2>Methods</h2>
 
 
@@ -62,9 +62,9 @@
 		</div>
 		<div>
 		Apply a Matrix4 to the plane. The second parameter is optional.
-		
+
 		<code>
-		var optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix ) 
+		var optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix )
 		</code>
 		</div>
 
@@ -77,7 +77,7 @@
 		Returns a vector in the same direction as the Plane's normal, but the magnitude is passed point's original distance to the plane.
 		</div>
 
-		<h3>[method:Boolean isIntersectionLine]([page:Line3 line])</h3>
+		<h3>[method:Boolean intersectsLine]([page:Line3 line])</h3>
 		<div>
 		line -- [page:Line3]
 		</div>

+ 9 - 9
docs/api/math/Ray.html

@@ -30,12 +30,12 @@
 		<h3>[property:Vector3 origin]</h3>
 		<div>
 		The origin of the [page:Ray].
-		</div> 
+		</div>
 
 		<h3>[property:Vector3 direction]</h3>
 		<div>
 		The direction of the [page:Ray]. This must be normalized (with [page:Vector3].normalize) for the methods to operate properly.
-		</div> 
+		</div>
 
 		<h2>Methods</h2>
 
@@ -77,7 +77,7 @@
 		<div>
 		Copy the properties of the provided [page:Ray], then return this [page:Ray].
 		</div>
-		
+
 		<h3>.distanceSqToSegment([page:Vector3 v0], [page:Vector3 v1], [page:Vector3 optionalPointOnRay] = null, [page:Vector3 optionalPointOnSegment] = null) [page:Float]</h3>
 		<div>
 		v0 -- [page:Vector3] The start of the line segment.
@@ -129,7 +129,7 @@
 		<div>
 		Intersect this [page:Ray] with a [page:Box3], returning the intersection point or *null* if there is no intersection.
 		</div>
-		
+
 		<h3>.intersectPlane([page:Plane plane], [page:Vector3 optionalTarget] = null) [page:Vector3]?</h3>
 		<div>
 		plane -- [page:Plane] The [page:Plane] to intersect with.<br />
@@ -139,7 +139,7 @@
 		Intersect this [page:Ray] with a [page:Plane], returning the intersection point or *null* if there is no intersection.
 		</div>
 		function ( a, b, c, backfaceCulling, optionalTarget )
-		
+
 		<h3>.intersectTriangle([page:Vector3 a], [page:Vector3 b], [page:Vector3 c], [page:Boolean backfaceCulling], [page:Vector3 optionalTarget] = null) [page:Vector3]?</h3>
 		<div>
 		a, b, c -- [page:Vector3] The [page:Vector3] points on the triangle.<br />
@@ -149,8 +149,8 @@
 		<div>
 		Intersect this [page:Ray] with a triangle, returning the intersection point or *null* if there is no intersection.
 		</div>
-		
-		<h3>[method:Boolean isIntersectionBox]([page:Box3 box])</h3>
+
+		<h3>[method:Boolean intersectsBox]([page:Box3 box])</h3>
 		<div>
 		box -- [page:Box3] The [page:Box3] to intersect with.
 		</div>
@@ -158,7 +158,7 @@
 		Return whether or not this [page:Ray] intersects with the [page:Box3].
 		</div>
 
-		<h3>[method:Boolean isIntersectionPlane]([page:Plane plane])</h3>
+		<h3>[method:Boolean intersectsPlane]([page:Plane plane])</h3>
 		<div>
 		plane -- [page:Plane] The [page:Plane] to intersect with.
 		</div>
@@ -166,7 +166,7 @@
 		Return whether or not this [page:Ray] intersects with the [page:Plane].
 		</div>
 
-		<h3>[method:Boolean isIntersectionSphere]([page:Sphere sphere])</h3>
+		<h3>[method:Boolean intersectsSphere]([page:Sphere sphere])</h3>
 		<div>
 		sphere -- [page:Sphere] The [page:Sphere] to intersect with.
 		</div>

+ 161 - 161
docs/api/renderers/CanvasRenderer.html

@@ -1,162 +1,162 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!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>
-		<h1>[name]</h1>
-
-		<div class="desc">
-			The Canvas renderer displays your beautifully crafted scenes <em>not</em> using WebGL, but draws it using the (slower) <a href="http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas/">Canvas 2D Context</a> API.<br /><br />
-			This renderer can be a nice fallback from [page:WebGLRenderer] for simple scenes:
-
-			<code>
-			function webglAvailable() {
-				try {
-					var canvas = document.createElement( 'canvas' );
-					return !!( window.WebGLRenderingContext && (
-						canvas.getContext( 'webgl' ) ||
-						canvas.getContext( 'experimental-webgl' ) )
-					);
-				} catch ( e ) {
-					return false;
-				}
-			}
-
-			if ( webglAvailable() ) {
-				renderer = new THREE.WebGLRenderer();
-			} else {
-				renderer = new THREE.CanvasRenderer();
-			}
-			</code>
-
-			Note: both WebGLRenderer and CanvasRenderer are embedded in the web page using an HTML5 &lt;canvas&gt; tag.
-			The "Canvas" in CanvasRenderer means it uses Canvas 2D instead of WebGL.<br /><br />
-
-			Don't confuse either CanvasRenderer with the SoftwareRenderer example, which simulates a screen buffer in a Javascript array.
-		</div>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]([page:object parameters])</h3>
-        <div>parameters is an optional object with properties defining the renderer's behaviour. The constructor also accepts no parameters at all. In all cases, it will assume sane defaults when parameters are missing.</div>
-
-		<div>
-		canvas — A [page:Canvas] where the renderer draws its output.
-		</div>
-
-
-		<h2>Properties</h2>
-
-    <h3>[property:Object info]</h3>
-
-		<div>
-			An object with a series of statistical information about the graphics board memory and the rendering process. Useful for debugging or just for the sake of curiosity. The object contains the following fields:</div>
-			<ul>
-				<li>render:
-					<ul>
-						<li>vertices</li>
-						<li>faces</li>
-					</ul>
-				</li>
-			</ul>
-		</div>
-
-    <h3>[property:DOMElement domElement]</h3>
-
-		<div>
-			A [page:Canvas] where the renderer draws its output.<br />
-			This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page.
-		</div>
-
-		<h3>[property:Boolean autoClear]</h3>
-		<div>
-      Defines whether the renderer should automatically clear its output before rendering.
-    </div>
-
-		<h3>[property:Boolean sortObjects]</h3>
-		<div>
-      Defines whether the renderer should sort objects. Default is true.<br />
-      Note: Sorting is used to attempt to properly render objects that have some degree of transparency.  By definition, sorting objects may not work in all cases.  Depending on the needs of application, it may be neccessary to turn off sorting and use other methods to deal with transparency rendering e.g. manually determining the object rendering order.
-    </div>
-
-		<h3>[property:boolean sortElements]</h3>
-		<div>
-			Defines whether the renderer should sort the face of each object. Default is true.
-		</div>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null render]([page:Scene scene], [page:Camera camera])</h3>
-		<div>
-			scene -- The scene to render. <br />
-			camera -- the camera to view the scene.
-		</div>
-		<div>
-        Render a scene using a camera.
-		</div>
-
-		<h3>[method:null clear]()</h3>
-		<div>
-			Tells the renderer to clear its color drawing buffer with the clearcolor.
-		</div>
-
-		<h3>[method:null setClearColor]([page:Color color], [page:number alpha])</h3>
-		<div>
-			color -- The color to clear the canvas with. <br />
-			alpha -- The alpha channel to clear the canvas with.
-		</div>
-		<div>
-			This set the clearColor and the clearAlpha.
-		</div>
-
-
-		<h3>[method:null setSize]([page:Number width], [page:Number height])</h3>
-		<div>
-			width -- The width of the drawing canvas. <br />
-			height -- The height of the drawing canvas.
-		</div>
-		<div>
-			This set the size of the drawing canvas and if updateStyle is set, then the css of the canvas is updated too.
-		</div>
-
-		<h3>[method:null setClearColorHex]([page:number hex], [page:number alpha])</h3>
-		<div>
-			hex -- The the hexadecimal value of the color to clear the canvas with. <br />
-	    alpha -- The alpha channel to clear the canvas with.
-		</div>
-		<div>
-			This set the clearColor and the clearAlpha.
-		</div>
-
-		<h3>[method:number getClearColorHex]()</h3>
-		<div>
-			Returns the [page:number hex] color.
-		</div>
-
-		<h3>[method:number getClearAlpha]()</h3>
-		<div>
-			Returns the alpha value.
-		</div>
-
-		<h2>Empty Methods to Maintain Compatibility with [page:WebglRenderer]</h2>
-		<div>
-			[method:null clearColor]()<br/>
-			[method:null clearDepth]()<br/>
-			[method:null clearStencil]()<br/>
-			[method:null setFaceCulling]()<br/>
-			[method:null supportsVertexTextures]()<br/>
-			[method:number getMaxAnisotropy]() - returns 1 <br/>
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<div class="desc">
+			The Canvas renderer displays your beautifully crafted scenes <em>not</em> using WebGL, but draws it using the (slower) <a href="http://drafts.htmlwg.org/2dcontext/html5_canvas_CR/Overview.html">Canvas 2D Context</a> API.<br /><br />
+			This renderer can be a nice fallback from [page:WebGLRenderer] for simple scenes:
+
+			<code>
+			function webglAvailable() {
+				try {
+					var canvas = document.createElement( 'canvas' );
+					return !!( window.WebGLRenderingContext && (
+						canvas.getContext( 'webgl' ) ||
+						canvas.getContext( 'experimental-webgl' ) )
+					);
+				} catch ( e ) {
+					return false;
+				}
+			}
+
+			if ( webglAvailable() ) {
+				renderer = new THREE.WebGLRenderer();
+			} else {
+				renderer = new THREE.CanvasRenderer();
+			}
+			</code>
+
+			Note: both WebGLRenderer and CanvasRenderer are embedded in the web page using an HTML5 &lt;canvas&gt; tag.
+			The "Canvas" in CanvasRenderer means it uses Canvas 2D instead of WebGL.<br /><br />
+
+			Don't confuse either CanvasRenderer with the SoftwareRenderer example, which simulates a screen buffer in a Javascript array.
+		</div>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:object parameters])</h3>
+        <div>parameters is an optional object with properties defining the renderer's behaviour. The constructor also accepts no parameters at all. In all cases, it will assume sane defaults when parameters are missing.</div>
+
+		<div>
+		canvas — A [page:Canvas] where the renderer draws its output.
+		</div>
+
+
+		<h2>Properties</h2>
+
+    <h3>[property:Object info]</h3>
+
+		<div>
+			An object with a series of statistical information about the graphics board memory and the rendering process. Useful for debugging or just for the sake of curiosity. The object contains the following fields:</div>
+			<ul>
+				<li>render:
+					<ul>
+						<li>vertices</li>
+						<li>faces</li>
+					</ul>
+				</li>
+			</ul>
+		</div>
+
+    <h3>[property:DOMElement domElement]</h3>
+
+		<div>
+			A [page:Canvas] where the renderer draws its output.<br />
+			This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page.
+		</div>
+
+		<h3>[property:Boolean autoClear]</h3>
+		<div>
+      Defines whether the renderer should automatically clear its output before rendering.
+    </div>
+
+		<h3>[property:Boolean sortObjects]</h3>
+		<div>
+      Defines whether the renderer should sort objects. Default is true.<br />
+      Note: Sorting is used to attempt to properly render objects that have some degree of transparency.  By definition, sorting objects may not work in all cases.  Depending on the needs of application, it may be neccessary to turn off sorting and use other methods to deal with transparency rendering e.g. manually determining the object rendering order.
+    </div>
+
+		<h3>[property:boolean sortElements]</h3>
+		<div>
+			Defines whether the renderer should sort the face of each object. Default is true.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null render]([page:Scene scene], [page:Camera camera])</h3>
+		<div>
+			scene -- The scene to render. <br />
+			camera -- the camera to view the scene.
+		</div>
+		<div>
+        Render a scene using a camera.
+		</div>
+
+		<h3>[method:null clear]()</h3>
+		<div>
+			Tells the renderer to clear its color drawing buffer with the clearcolor.
+		</div>
+
+		<h3>[method:null setClearColor]([page:Color color], [page:number alpha])</h3>
+		<div>
+			color -- The color to clear the canvas with. <br />
+			alpha -- The alpha channel to clear the canvas with.
+		</div>
+		<div>
+			This set the clearColor and the clearAlpha.
+		</div>
+
+
+		<h3>[method:null setSize]([page:Number width], [page:Number height])</h3>
+		<div>
+			width -- The width of the drawing canvas. <br />
+			height -- The height of the drawing canvas.
+		</div>
+		<div>
+			This set the size of the drawing canvas and if updateStyle is set, then the css of the canvas is updated too.
+		</div>
+
+		<h3>[method:null setClearColorHex]([page:number hex], [page:number alpha])</h3>
+		<div>
+			hex -- The the hexadecimal value of the color to clear the canvas with. <br />
+	    alpha -- The alpha channel to clear the canvas with.
+		</div>
+		<div>
+			This set the clearColor and the clearAlpha.
+		</div>
+
+		<h3>[method:number getClearColorHex]()</h3>
+		<div>
+			Returns the [page:number hex] color.
+		</div>
+
+		<h3>[method:number getClearAlpha]()</h3>
+		<div>
+			Returns the alpha value.
+		</div>
+
+		<h2>Empty Methods to Maintain Compatibility with [page:WebglRenderer]</h2>
+		<div>
+			[method:null clearColor]()<br/>
+			[method:null clearDepth]()<br/>
+			[method:null clearStencil]()<br/>
+			[method:null setFaceCulling]()<br/>
+			[method:null supportsVertexTextures]()<br/>
+			[method:number getMaxAnisotropy]() - returns 1 <br/>
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 1 - 0
docs/index.html

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

+ 3 - 4
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,7 +31,7 @@ var list = {
 			[ "Face3", "api/core/Face3" ],
 			[ "Geometry", "api/core/Geometry" ],
 			[ "Object3D", "api/core/Object3D" ],
-			[ "Raycaster", "api/core/Raycaster" ],
+			[ "Raycaster", "api/core/Raycaster" ]
 		],
 
 		"Lights": [
@@ -80,7 +79,6 @@ var list = {
 			[ "PointsMaterial", "api/materials/PointsMaterial" ],
 			[ "RawShaderMaterial", "api/materials/RawShaderMaterial" ],
 			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],
-			[ "SpriteCanvasMaterial", "api/materials/SpriteCanvasMaterial" ],
 			[ "SpriteMaterial", "api/materials/SpriteMaterial" ]
 		],
 
@@ -240,7 +238,8 @@ var list = {
 
 		"Examples" : [
 			[ "CombinedCamera", "api/examples/cameras/CombinedCamera" ],
-			[ "LookupTable", "api/examples/Lut" ]
+			[ "LookupTable", "api/examples/Lut" ],
+			[ "SpriteCanvasMaterial", "api/examples/SpriteCanvasMaterial" ]
 
 		]
 

+ 32 - 30
docs/scenes/geometry-browser.html

@@ -10,7 +10,7 @@
 				font-weight: normal;
 				font-style: normal;
 			}
-			
+
 			body {
 				margin:0;
 				font-family: 'inconsolata';
@@ -18,9 +18,9 @@
 				line-height: 18px;
 				overflow: hidden;
 			}
-			
+
 			canvas { width: 100%; height: 100% }
-			
+
 			#newWindow {
 				display: block;
 				position: absolute;
@@ -31,12 +31,14 @@
 		</style>
 	</head>
 	<body>
-		
+
 		<a id='newWindow' href='./geometry-browser.html' target='_blank'>Open in New Window</a>
-		
+
 		<script src="../../build/three.min.js"></script>
 		<script src='../../examples/js/libs/dat.gui.min.js'></script>
 		<script src="../../examples/js/controls/OrbitControls.js"></script>
+		<script src="../../examples/js/geometries/TextGeometry.js"></script>
+		<script src="../../examples/js/utils/FontUtils.js"></script>
 		<script src="../../examples/fonts/gentilis_bold.typeface.js"></script>
 		<script src="../../examples/fonts/gentilis_regular.typeface.js"></script>
 		<script src="../../examples/fonts/optimer_bold.typeface.js"></script>
@@ -45,22 +47,22 @@
 		<script src="../../examples/fonts/helvetiker_regular.typeface.js"></script>
 		<script src="../../examples/fonts/droid/droid_serif_regular.typeface.js"></script>
 		<script src="../../examples/fonts/droid/droid_serif_bold.typeface.js"></script>
-		
+
 		<script src='js/geometry.js'></script>
-		
+
 		<script>
-			
+
 			document.getElementById('newWindow').href += window.location.hash;
-			
+
 			var gui = new dat.GUI();
 			var scene = new THREE.Scene();
 			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 50 );
 			camera.position.z = 30;
-			
+
 			var renderer = new THREE.WebGLRenderer({antialias: true});
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			document.body.appendChild( renderer.domElement );
-			
+
 			var orbit = new THREE.OrbitControls( camera, renderer.domElement );
 			orbit.enableZoom = false;
 
@@ -71,7 +73,7 @@
 			lights[0] = new THREE.PointLight( 0xffffff, 1, 0 );
 			lights[1] = new THREE.PointLight( 0xffffff, 1, 0 );
 			lights[2] = new THREE.PointLight( 0xffffff, 1, 0 );
-			
+
 			lights[0].position.set( 0, 200, 0 );
 			lights[1].position.set( 100, 200, 100 );
 			lights[2].position.set( -100, -200, -100 );
@@ -81,40 +83,40 @@
 			scene.add( lights[2] );
 
 			var mesh = new THREE.Object3D()
-			
+
 			mesh.add( new THREE.LineSegments(
-				
+
 				new THREE.Geometry(),
-				
+
 				new THREE.LineBasicMaterial({
 					color: 0xffffff,
 					transparent: true,
 					opacity: 0.5
 				})
-				
+
 			));
-			
+
 			mesh.add( new THREE.Mesh(
-				
+
 				new THREE.Geometry(),
-				
+
 				new THREE.MeshPhongMaterial({
 					color: 0x156289,
 					emissive: 0x072534,
 					side: THREE.DoubleSide,
 					shading: THREE.FlatShading
 				})
-				
+
 			));
-			
+
 			var options = chooseFromHash( mesh );
-			
+
 			scene.add( mesh );
-			
+
 			var prevFog = false;
-			
+
 			var render = function () {
-				
+
 				requestAnimationFrame( render );
 
 				var time = Date.now() * 0.001;
@@ -125,20 +127,20 @@
 				}
 
 				renderer.render( scene, camera );
-				
+
 			};
-			
+
 			window.addEventListener( 'resize', function () {
-				
+
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				
+
 			}, false );
 
 			render();
-			
+
 		</script>
 	</body>
 </html>

+ 1 - 1
docs/scenes/js/material.js

@@ -439,7 +439,7 @@ function guiMeshPhongMaterial ( gui, mesh, material, geometry ) {
 	folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) );
 	folder.addColor( data, 'specular' ).onChange( handleColorChange( material.specular ) );
 
-	folder.add( material, 'shininess', 1, 100);
+	folder.add( material, 'shininess', 0, 100);
 	folder.add( material, 'shading', constants.shading).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );

+ 1 - 0
editor/css/dark.css

@@ -86,6 +86,7 @@ input.Number {
 	#menubar .menu.right {
 		float: right;
 		cursor: auto;
+		padding-right: 0px;
 		text-align: right;
 	}
 

+ 1 - 0
editor/css/light.css

@@ -79,6 +79,7 @@ input.Number {
 	#menubar .menu.right {
 		float: right;
 		cursor: auto;
+		padding-right: 0px;
 		text-align: right;
 	}
 

+ 12 - 0
editor/css/main.css

@@ -116,6 +116,18 @@ textarea, input { outline: none; } /* osx */
 	color: #8888ee;
 }
 
+.Line {
+	color: #88ee88;
+}
+
+.LineSegments {
+	color: #88ee88;
+}
+
+.Points {
+	color: #ee8888;
+}
+
 /* */
 
 .PointLight {

+ 11 - 19
editor/index.html

@@ -14,10 +14,13 @@
 
 		<script src="../examples/js/controls/EditorControls.js"></script>
 		<script src="../examples/js/controls/TransformControls.js"></script>
+
+		<script src="../examples/js/libs/jszip.min.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>
+		<script src="../examples/js/loaders/KMZLoader.js"></script>
 		<script src="../examples/js/loaders/MD2Loader.js"></script>
 		<script src="../examples/js/loaders/OBJLoader.js"></script>
 		<script src="../examples/js/loaders/PLYLoader.js"></script>
@@ -68,7 +71,6 @@
 		<script src="js/libs/ternjs/doc_comment.js"></script>
 		<script src="js/libs/tern-threejs/threejs.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>
@@ -152,10 +154,8 @@
 			var sidebar = new Sidebar( editor );
 			document.body.appendChild( sidebar.dom );
 
-			/*
-			var dialog = new UI.Dialog();
-			document.body.appendChild( dialog.dom );
-			*/
+			var modal = new UI.Modal();
+			document.body.appendChild( modal.dom );
 
 			//
 
@@ -185,7 +185,7 @@
 
 				var timeout;
 
-				var saveState = function ( scene ) {
+				function saveState( scene ) {
 
 					if ( editor.config.getKey( 'autosave' ) === false ) {
 
@@ -213,7 +213,6 @@
 
 				var signals = editor.signals;
 
-				signals.editorCleared.add( saveState );
 				signals.geometryChanged.add( saveState );
 				signals.objectAdded.add( saveState );
 				signals.objectChanged.add( saveState );
@@ -222,18 +221,11 @@
 				signals.sceneGraphChanged.add( saveState );
 				signals.scriptChanged.add( saveState );
 
-				/*
-				var showDialog = function ( content ) {
+				signals.showModal.add( function ( content ) {
 
-					dialog.clear();
+					modal.show( content );
 
-					dialog.add( content );
-					dialog.showModal();
-
-				};
-
-				signals.showDialog.add( showDialog );
-				*/
+				} );
 
 			} );
 
@@ -279,11 +271,11 @@
 
 			}, false );
 
-			var onWindowResize = function ( event ) {
+			function onWindowResize( event ) {
 
 				editor.signals.windowResize.dispatch();
 
-			};
+			}
 
 			window.addEventListener( 'resize', onWindowResize, false );
 

+ 1 - 0
editor/js/Config.js

@@ -12,6 +12,7 @@ var Config = function () {
 
 		'project/renderer': 'WebGLRenderer',
 		'project/renderer/antialias': true,
+		'project/renderer/shadows': true,
 		'project/vr': false,
 
 		'ui/sidebar/animation/collapsed': true,

+ 3 - 9
editor/js/Editor.js

@@ -19,7 +19,7 @@ var Editor = function () {
 
 		// actions
 
-		// showDialog: new SIGNALS.Signal(),
+		showModal: new SIGNALS.Signal(),
 
 		// notifications
 
@@ -102,14 +102,6 @@ Editor.prototype = {
 
 	},
 
-	/*
-	showDialog: function ( value ) {
-
-		this.signals.showDialog.dispatch( value );
-
-	},
-	*/
-
 	//
 
 	setScene: function ( scene ) {
@@ -411,6 +403,7 @@ Editor.prototype = {
 	clear: function () {
 
 		this.history.clear();
+		this.storage.clear();
 
 		this.camera.position.set( 500, 250, 500 );
 		this.camera.lookAt( new THREE.Vector3() );
@@ -469,6 +462,7 @@ Editor.prototype = {
 		return {
 
 			project: {
+				shadows: this.config.getKey( 'project/renderer/shadows' ),
 				vr: this.config.getKey( 'project/vr' )
 			},
 			camera: this.camera.toJSON(),

+ 25 - 8
editor/js/Loader.js

@@ -127,11 +127,8 @@ var Loader = function ( editor ) {
 
 					var contents = event.target.result;
 
-					var parser = new DOMParser();
-					var xml = parser.parseFromString( contents, 'text/xml' );
-
 					var loader = new THREE.ColladaLoader();
-					var collada = loader.parse( xml );
+					var collada = loader.parse( contents );
 
 					collada.scene.name = filename;
 
@@ -200,6 +197,25 @@ var Loader = function ( editor ) {
 
 				break;
 
+
+				case 'kmz':
+
+					var reader = new FileReader();
+					reader.addEventListener( 'load', function ( event ) {
+
+						var loader = new THREE.KMZLoader();
+						var collada = loader.parse( event.target.result );
+
+						collada.scene.name = filename;
+
+						editor.addObject( collada.scene );
+						editor.select( collada.scene );
+
+					}, false );
+					reader.readAsArrayBuffer( file );
+
+					break;
+
 				case 'md2':
 
 					var reader = new FileReader();
@@ -213,11 +229,12 @@ var Loader = function ( editor ) {
 							morphNormals: true
 						} );
 
-						var object = new THREE.MorphAnimMesh( geometry, material );
-						object.name = filename;
+						var mesh = new THREE.Mesh( geometry, material );
+						mesh.mixer = new THREE.AnimationMixer( mesh )
+						mesh.name = filename;
 
-						editor.addObject( object );
-						editor.select( object );
+						editor.addObject( mesh );
+						editor.select( mesh );
 
 					}, false );
 					reader.readAsArrayBuffer( file );

+ 21 - 21
editor/js/Menubar.File.js

@@ -86,8 +86,13 @@ Menubar.File = function ( editor ) {
 		}
 
 		var output = geometry.toJSON();
-		output = JSON.stringify( output, null, '\t' );
-		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+
+		try {
+			output = JSON.stringify( output, null, '\t' );
+			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+		} catch ( e ) {
+			output = JSON.stringify( output );
+		}
 
 		exportString( output, 'geometry.json' );
 
@@ -111,8 +116,13 @@ Menubar.File = function ( editor ) {
 		}
 
 		var output = object.toJSON();
-		output = JSON.stringify( output, null, '\t' );
-		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+
+		try {
+			output = JSON.stringify( output, null, '\t' );
+			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+		} catch ( e ) {
+			output = JSON.stringify( output );
+		}
 
 		exportString( output, 'model.json' );
 
@@ -127,8 +137,13 @@ Menubar.File = function ( editor ) {
 	option.onClick( function () {
 
 		var output = editor.scene.toJSON();
-		output = JSON.stringify( output, null, '\t' );
-		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+
+		try {
+			output = JSON.stringify( output, null, '\t' );
+			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+		} catch ( e ) {
+			output = JSON.stringify( output );
+		}
 
 		exportString( output, 'scene.json' );
 
@@ -260,21 +275,6 @@ Menubar.File = function ( editor ) {
 	} );
 	options.add( option );
 
-	/*
-	// Test
-
-	var option = new UI.Panel();
-	option.setClass( 'option' );
-	option.setTextContent( 'Test' );
-	option.onClick( function () {
-
-		var text = new UI.Text( 'blah' );
-		editor.showDialog( text );
-
-	} );
-	options.add( option );
-	*/
-
 
 	//
 

+ 10 - 6
editor/js/Menubar.Status.js

@@ -23,23 +23,27 @@ Menubar.Status = function ( editor ) {
 	} );
 	container.add( checkbox );
 
-	var title = new UI.Panel();
-	title.setClass( 'title' );
-	title.setTextContent( 'Autosave' );
-	container.add( title );
+	var text = new UI.Text( 'autosave' );
+	text.setClass( 'title' );
+	container.add( text );
 
 	editor.signals.savingStarted.add( function () {
 
-		title.setTextDecoration( 'underline' );
+		text.setTextDecoration( 'underline' );
 
 	} );
 
 	editor.signals.savingFinished.add( function () {
 
-		title.setTextDecoration( 'none' );
+		text.setTextDecoration( 'none' );
 
 	} );
 
+	var version = new UI.Text( 'r' + THREE.REVISION );
+	version.setClass( 'title' );
+	version.setOpacity( 0.5 );
+	container.add( version );
+
 	return container;
 
 };

+ 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;
 
 }

+ 23 - 3
editor/js/Sidebar.Geometry.CircleGeometry.js

@@ -28,6 +28,26 @@ Sidebar.Geometry.CircleGeometry = function ( signals, object ) {
 
 	container.add( segmentsRow );
 
+	// thetaStart
+
+	var thetaStartRow = new UI.Panel();
+	var thetaStart = new UI.Number( parameters.thetaStart ).onChange( update );
+
+	thetaStartRow.add( new UI.Text( 'Theta start' ).setWidth( '90px' ) );
+	thetaStartRow.add( thetaStart );
+
+	container.add( thetaStartRow );
+
+	// thetaLength
+
+	var thetaLengthRow = new UI.Panel();
+	var thetaLength = new UI.Number( parameters.thetaLength ).onChange( update );
+
+	thetaLengthRow.add( new UI.Text( 'Theta length' ).setWidth( '90px' ) );
+	thetaLengthRow.add( thetaLength );
+
+	container.add( thetaLengthRow );
+
 	//
 
 	function update() {
@@ -36,11 +56,11 @@ Sidebar.Geometry.CircleGeometry = function ( signals, object ) {
 
 		object.geometry = new THREE.CircleGeometry(
 			radius.getValue(),
-			segments.getValue()
+			segments.getValue(),
+			thetaStart.getValue(),
+			thetaLength.getValue()
 		);
 
-		object.geometry.computeBoundingSphere();
-
 		signals.geometryChanged.dispatch( object );
 
 	}

+ 1 - 1
editor/js/Sidebar.Material.js

@@ -353,7 +353,7 @@ Sidebar.Material = function ( editor ) {
 	// opacity
 
 	var materialOpacityRow = new UI.Panel();
-	var materialOpacity = new UI.Number().setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
+	var materialOpacity = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
 
 	materialOpacityRow.add( new UI.Text( 'Opacity' ).setWidth( '90px' ) );
 	materialOpacityRow.add( materialOpacity );

+ 67 - 2
editor/js/Sidebar.Object3D.js

@@ -95,6 +95,7 @@ Sidebar.Object3D = function ( editor ) {
 
 	container.add( objectNameRow );
 
+	/*
 	// parent
 
 	var objectParentRow = new UI.Panel();
@@ -104,6 +105,7 @@ Sidebar.Object3D = function ( editor ) {
 	objectParentRow.add( objectParent );
 
 	container.add( objectParentRow );
+	*/
 
 	// position
 
@@ -243,6 +245,30 @@ Sidebar.Object3D = function ( editor ) {
 
 	container.add( objectDecayRow );
 
+	// shadow
+
+	var objectShadowRow = new UI.Panel();
+
+	objectShadowRow.add( new UI.Text( 'Shadow' ).setWidth( '90px' ) );
+
+	var objectCastShadowSpan = new UI.Span().setMarginRight( '10px' );
+	var objectCastShadow = new UI.Checkbox().onChange( update );
+
+	objectCastShadowSpan.add( objectCastShadow );
+	objectCastShadowSpan.add( new UI.Text( 'cast' ).setMarginLeft( '3px' ) );
+
+	objectShadowRow.add( objectCastShadowSpan );
+
+	var objectReceiveShadowSpan = new UI.Span();
+	var objectReceiveShadow = new UI.Checkbox().onChange( update );
+
+	objectReceiveShadowSpan.add( objectReceiveShadow );
+	objectReceiveShadowSpan.add( new UI.Text( 'receive' ).setMarginLeft( '3px' ) );
+
+	objectShadowRow.add( objectReceiveShadowSpan );
+
+	container.add( objectShadowRow );
+
 	// visible
 
 	var objectVisibleRow = new UI.Panel();
@@ -342,6 +368,7 @@ Sidebar.Object3D = function ( editor ) {
 
 		if ( object !== null ) {
 
+			/*
 			if ( object.parent !== null ) {
 
 				var newParentId = parseInt( objectParent.getValue() );
@@ -353,6 +380,7 @@ Sidebar.Object3D = function ( editor ) {
 				}
 
 			}
+			*/
 
 			object.position.x = objectPositionX.getValue();
 			object.position.y = objectPositionY.getValue();
@@ -427,6 +455,25 @@ Sidebar.Object3D = function ( editor ) {
 
 			}
 
+			if ( object.castShadow !== undefined ) {
+
+				object.castShadow = objectCastShadow.getValue();
+
+			}
+
+			if ( object.receiveShadow !== undefined ) {
+
+				var value = objectReceiveShadow.getValue();
+
+				if ( value !== object.receiveShadow ) {
+
+					object.receiveShadow = value;
+					object.material.needsUpdate = true;
+
+				}
+
+			}
+
 			object.visible = objectVisible.getValue();
 
 			try {
@@ -448,7 +495,7 @@ Sidebar.Object3D = function ( editor ) {
 	function updateRows( object ) {
 
 		var properties = {
-			'parent': objectParentRow,
+			// 'parent': objectParentRow,
 			'fov': objectFovRow,
 			'near': objectNearRow,
 			'far': objectFarRow,
@@ -458,7 +505,9 @@ Sidebar.Object3D = function ( editor ) {
 			'distance' : objectDistanceRow,
 			'angle' : objectAngleRow,
 			'exponent' : objectExponentRow,
-			'decay' : objectDecayRow
+			'decay' : objectDecayRow,
+			'castShadow' : objectShadowRow,
+			'receiveShadow' : objectReceiveShadowSpan
 		};
 
 		for ( var property in properties ) {
@@ -505,6 +554,7 @@ Sidebar.Object3D = function ( editor ) {
 
 	} );
 
+	/*
 	signals.sceneGraphChanged.add( function () {
 
 		var scene = editor.scene;
@@ -519,6 +569,7 @@ Sidebar.Object3D = function ( editor ) {
 		objectParent.setOptions( options );
 
 	} );
+	*/
 
 	signals.objectChanged.add( function ( object ) {
 
@@ -535,11 +586,13 @@ Sidebar.Object3D = function ( editor ) {
 		objectUUID.setValue( object.uuid );
 		objectName.setValue( object.name );
 
+		/*
 		if ( object.parent !== null ) {
 
 			objectParent.setValue( object.parent.id );
 
 		}
+		*/
 
 		objectPositionX.setValue( object.position.x );
 		objectPositionY.setValue( object.position.y );
@@ -613,6 +666,18 @@ Sidebar.Object3D = function ( editor ) {
 
 		}
 
+		if ( object.castShadow !== undefined ) {
+
+			objectCastShadow.setValue( object.castShadow );
+
+		}
+
+		if ( object.receiveShadow !== undefined ) {
+
+			objectReceiveShadow.setValue( object.receiveShadow );
+
+		}
+
 		objectVisible.setValue( object.visible );
 
 		try {

+ 43 - 16
editor/js/Sidebar.Project.js

@@ -4,6 +4,7 @@
 
 Sidebar.Project = function ( editor ) {
 
+	var config = editor.config;
 	var signals = editor.signals;
 
 	var rendererTypes = {
@@ -17,10 +18,10 @@ Sidebar.Project = function ( editor ) {
 	};
 
 	var container = new UI.CollapsiblePanel();
-	container.setCollapsed( editor.config.getKey( 'ui/sidebar/project/collapsed' ) );
+	container.setCollapsed( config.getKey( 'ui/sidebar/project/collapsed' ) );
 	container.onCollapsedChange( function ( boolean ) {
 
-		editor.config.setKey( 'ui/sidebar/project/collapsed', boolean );
+		config.setKey( 'ui/sidebar/project/collapsed', boolean );
 
 	} );
 
@@ -42,7 +43,10 @@ Sidebar.Project = function ( editor ) {
 	var rendererTypeRow = new UI.Panel();
 	var rendererType = new UI.Select().setOptions( options ).setWidth( '150px' ).onChange( function () {
 
-		editor.config.setKey( 'project/renderer', this.getValue() );
+		var value = this.getValue();
+
+		config.setKey( 'project/renderer', value );
+
 		updateRenderer();
 
 	} );
@@ -52,33 +56,53 @@ Sidebar.Project = function ( editor ) {
 
 	container.add( rendererTypeRow );
 
-	if ( editor.config.getKey( 'project/renderer' ) !== undefined ) {
+	if ( config.getKey( 'project/renderer' ) !== undefined ) {
 
-		rendererType.setValue( editor.config.getKey( 'project/renderer' ) );
+		rendererType.setValue( config.getKey( 'project/renderer' ) );
 
 	}
 
 	// antialiasing
 
-	var rendererAntialiasRow = new UI.Panel();
-	var rendererAntialias = new UI.Checkbox( editor.config.getKey( 'project/renderer/antialias' ) ).setLeft( '100px' ).onChange( function () {
+	var rendererPropertiesRow = new UI.Panel();
+	rendererPropertiesRow.add( new UI.Text( '' ).setWidth( '90px' ) );
 
-		editor.config.setKey( 'project/renderer/antialias', this.getValue() );
+	var rendererAntialiasSpan = new UI.Span().setMarginRight( '10px' );
+	var rendererAntialias = new UI.Checkbox( config.getKey( 'project/renderer/antialias' ) ).setLeft( '100px' ).onChange( function () {
+
+		config.setKey( 'project/renderer/antialias', this.getValue() );
 		updateRenderer();
 
 	} );
 
-	rendererAntialiasRow.add( new UI.Text( 'Antialias' ).setWidth( '90px' ) );
-	rendererAntialiasRow.add( rendererAntialias );
+	rendererAntialiasSpan.add( rendererAntialias );
+	rendererAntialiasSpan.add( new UI.Text( 'antialias' ).setMarginLeft( '3px' ) );
+
+	rendererPropertiesRow.add( rendererAntialiasSpan );
 
-	container.add( rendererAntialiasRow );
+	// shadow
+
+	var rendererShadowsSpan = new UI.Span();
+	var rendererShadows = new UI.Checkbox( config.getKey( 'project/renderer/shadows' ) ).setLeft( '100px' ).onChange( function () {
+
+		config.setKey( 'project/renderer/shadows', this.getValue() );
+		updateRenderer();
+
+	} );
+
+	rendererShadowsSpan.add( rendererShadows );
+	rendererShadowsSpan.add( new UI.Text( 'shadows' ).setMarginLeft( '3px' ) );
+
+	rendererPropertiesRow.add( rendererShadowsSpan );
+
+	container.add( rendererPropertiesRow );
 
 	// VR
 
 	var vrRow = new UI.Panel();
-	var vr = new UI.Checkbox( editor.config.getKey( 'project/vr' ) ).setLeft( '100px' ).onChange( function () {
+	var vr = new UI.Checkbox( config.getKey( 'project/vr' ) ).setLeft( '100px' ).onChange( function () {
 
-		editor.config.setKey( 'project/vr', this.getValue() );
+		config.setKey( 'project/vr', this.getValue() );
 		// updateRenderer();
 
 	} );
@@ -92,11 +116,11 @@ Sidebar.Project = function ( editor ) {
 
 	function updateRenderer() {
 
-		createRenderer( rendererType.getValue(), rendererAntialias.getValue() );
+		createRenderer( rendererType.getValue(), rendererAntialias.getValue(), rendererShadows.getValue() );
 
 	}
 
-	function createRenderer( type, antialias ) {
+	function createRenderer( type, antialias, shadows ) {
 
 		if ( type === 'WebGLRenderer' && System.support.webgl === false ) {
 
@@ -104,12 +128,15 @@ Sidebar.Project = function ( editor ) {
 
 		}
 
+		rendererPropertiesRow.setDisplay( type === 'WebGLRenderer' ? '' : 'none' );
+
 		var renderer = new rendererTypes[ type ]( { antialias: antialias } );
+		if ( shadows && renderer.shadowMap ) renderer.shadowMap.enabled = true;
 		signals.rendererChanged.dispatch( renderer );
 
 	}
 
-	createRenderer( editor.config.getKey( 'project/renderer' ), editor.config.getKey( 'project/renderer/antialias' ) );
+	createRenderer( config.getKey( 'project/renderer' ), config.getKey( 'project/renderer/antialias' ), config.getKey( 'project/renderer/shadows' ) );
 
 	return container;
 

+ 2 - 2
editor/js/Storage.js

@@ -76,14 +76,14 @@ var Storage = function () {
 
 		},
 
-		clear: function ( callback ) {
+		clear: function () {
 
 			var transaction = database.transaction( [ 'states' ], 'readwrite' );
 			var objectStore = transaction.objectStore( 'states' );
 			var request = objectStore.clear();
 			request.onsuccess = function ( event ) {
 
-				callback();
+				console.log( '[' + /\d\d\:\d\d\:\d\d/.exec( new Date() )[ 0 ] + ']', 'Cleared IndexedDB.' );
 
 			};
 

+ 7 - 8
editor/js/Toolbar.js

@@ -37,22 +37,21 @@ var Toolbar = function ( editor ) {
 
 	// grid
 
-	var grid = new UI.Number( 25 ).onChange( update );
-	grid.dom.style.width = '42px';
+	var grid = new UI.Number( 25 ).setWidth( '40px' ).onChange( update );
 	buttons.add( new UI.Text( 'Grid: ' ) );
 	buttons.add( grid );
 
-	var snap = new UI.Checkbox( false ).onChange( update );
+	var snap = new UI.Checkbox( false ).onChange( update ).setMarginLeft( '10px' );
 	buttons.add( snap );
-	buttons.add( new UI.Text( 'snap' ) );
+	buttons.add( new UI.Text( 'snap' ).setMarginLeft( '3px' ) );
 
-	var local = new UI.Checkbox( false ).onChange( update );
+	var local = new UI.Checkbox( false ).onChange( update ).setMarginLeft( '10px' );
 	buttons.add( local );
-	buttons.add( new UI.Text( 'local' ) );
+	buttons.add( new UI.Text( 'local' ).setMarginLeft( '3px' ) );
 
-	var showGrid = new UI.Checkbox().onChange( update ).setValue( true );
+	var showGrid = new UI.Checkbox().onChange( update ).setValue( true ).setMarginLeft( '10px' );
 	buttons.add( showGrid );
-	buttons.add( new UI.Text( 'show' ) );
+	buttons.add( new UI.Text( 'show' ).setMarginLeft( '3px' ) );
 
 	function update() {
 

+ 4 - 0
editor/js/Viewport.js

@@ -555,6 +555,8 @@ var Viewport = function ( editor ) {
 
 		requestAnimationFrame( animate );
 
+		/*
+
 		// animations
 
 		if ( THREE.AnimationHandler.animations.length > 0 ) {
@@ -577,6 +579,8 @@ var Viewport = function ( editor ) {
 
 		}
 
+		*/
+
 	}
 
 	function render() {

+ 21 - 21
editor/js/libs/app.js

@@ -27,6 +27,7 @@ var APP = {
 			renderer = new THREE.WebGLRenderer( { antialias: true } );
 			renderer.setClearColor( 0x000000 );
 			renderer.setPixelRatio( window.devicePixelRatio );
+			if ( json.project.shadows ) renderer.shadowMap.enabled = true;
 			this.dom = renderer.domElement;
 
 			this.setScene( loader.parse( json.scene ) );
@@ -98,7 +99,6 @@ var APP = {
 			camera.aspect = this.width / this.height;
 			camera.updateProjectionMatrix();
 
-
 			if ( vr === true ) {
 
 				if ( camera.parent === null ) {
@@ -157,7 +157,7 @@ var APP = {
 
 		};
 
-		var dispatch = function ( array, event ) {
+		function dispatch( array, event ) {
 
 			for ( var i = 0, l = array.length; i < l; i ++ ) {
 
@@ -173,11 +173,11 @@ var APP = {
 
 			}
 
-		};
+		}
 
 		var prevTime, request;
 
-		var animate = function ( time ) {
+		function animate( time ) {
 
 			request = requestAnimationFrame( animate );
 
@@ -196,7 +196,7 @@ var APP = {
 
 			prevTime = time;
 
-		};
+		}
 
 		this.play = function () {
 
@@ -233,53 +233,53 @@ var APP = {
 
 		//
 
-		var onDocumentKeyDown = function ( event ) {
+		function onDocumentKeyDown( event ) {
 
 			dispatch( events.keydown, event );
 
-		};
+		}
 
-		var onDocumentKeyUp = function ( event ) {
+		function onDocumentKeyUp( event ) {
 
 			dispatch( events.keyup, event );
 
-		};
+		}
 
-		var onDocumentMouseDown = function ( event ) {
+		function onDocumentMouseDown( event ) {
 
 			dispatch( events.mousedown, event );
 
-		};
+		}
 
-		var onDocumentMouseUp = function ( event ) {
+		function onDocumentMouseUp( event ) {
 
 			dispatch( events.mouseup, event );
 
-		};
+		}
 
-		var onDocumentMouseMove = function ( event ) {
+		function onDocumentMouseMove( event ) {
 
 			dispatch( events.mousemove, event );
 
-		};
+		}
 
-		var onDocumentTouchStart = function ( event ) {
+		function onDocumentTouchStart( event ) {
 
 			dispatch( events.touchstart, event );
 
-		};
+		}
 
-		var onDocumentTouchEnd = function ( event ) {
+		function onDocumentTouchEnd( event ) {
 
 			dispatch( events.touchend, event );
 
-		};
+		}
 
-		var onDocumentTouchMove = function ( event ) {
+		function onDocumentTouchMove( event ) {
 
 			dispatch( events.touchmove, event );
 
-		};
+		}
 
 	}
 

+ 0 - 160
editor/js/libs/tern-threejs/threejs.js

@@ -409,10 +409,6 @@
           "!type": "[]",
           "!doc": "Array of morph targets. Each morph target is a Javascript object:\n\t\t<code>{ name: \"targetName\", vertices: [ new THREE.Vector3(), ... ] }</code>\n\t\tMorph vertices match number and order of primary vertices."
         },
-        "morphColors": {
-          "!type": "[]",
-          "!doc": "Array of morph colors. Morph colors have similar structure as morph targets, each color set is a Javascript object:\n\t\t<code>morphColor = { name: \"colorName\", colors: [ new THREE.Color(), ... ] }</code>\n\t\tMorph colors can match either the number and order of faces (face colors) or the number of vertices (vertex colors)."
-        },
         "morphNormals": {
           "!type": "[]",
           "!doc": "Array of morph normals. Morph normals have similar structure as morph targets, each normal set is a Javascript object:\n\t\t<code>morphNormal = { name: \"NormalName\", normals: [ new THREE.Vector3(), ... ] }</code>"
@@ -2088,106 +2084,6 @@
         "intensity": {
           "!type": "number",
           "!doc": "Light's intensity.<br>\n\t\t\tDefault — *1.0*."
-        },
-        "onlyShadow": {
-          "!type": "bool",
-          "!doc": "If set to *true* light will only cast shadow but not contribute any lighting (as if *intensity* was 0 but cheaper to compute).<br>\n\t\t\tDefault — *false*."
-        },
-        "shadowCameraNear": {
-          "!type": "number",
-          "!doc": "Orthographic shadow camera frustum parameter.<br>\n\t\t\tDefault — *50*."
-        },
-        "shadowCameraFar": {
-          "!type": "number",
-          "!doc": "Orthographic shadow camera frustum parameter.<br>\n\t\t\tDefault — *5000*."
-        },
-        "shadowCameraLeft": {
-          "!type": "number",
-          "!doc": "Orthographic shadow camera frustum parameter.<br>\n\t\t\tDefault — *-500*."
-        },
-        "shadowCameraRight": {
-          "!type": "number",
-          "!doc": "Orthographic shadow camera frustum parameter.<br>\n\t\t\tDefault — *500*."
-        },
-        "shadowCameraTop": {
-          "!type": "number",
-          "!doc": "Orthographic shadow camera frustum parameter.<br>\n\t\t\tDefault — *500*."
-        },
-        "shadowCameraBottom": {
-          "!type": "number",
-          "!doc": "Orthographic shadow camera frustum parameter.<br>\n\t\t\tDefault — *-500*."
-        },
-        "shadowCameraVisible": {
-          "!type": "bool",
-          "!doc": "Show debug shadow camera frustum.<br>\n\t\t\tDefault — *false*."
-        },
-        "shadowBias": {
-          "!type": "number",
-          "!doc": "Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow.<br>\n\t\t\tDefault — *0*."
-        },
-        "shadowDarkness": {
-          "!type": "number",
-          "!doc": "Darkness of shadow casted by this light (from *0* to *1*).<br>\n\t\t\tDefault — *0.5*."
-        },
-        "shadowMapWidth": {
-          "!type": "number",
-          "!doc": "Shadow map texture width in pixels.<br>\n\t\t\tDefault — *512*."
-        },
-        "shadowMapHeight": {
-          "!type": "number",
-          "!doc": "Shadow map texture height in pixels.<br>\n\t\t\tDefault — *512*."
-        },
-        "shadowCascade": {
-          "!type": "bool",
-          "!doc": "**Experimental** If true, use a series of shadow maps in a cascade. This can give better z-depth resolution for a directional light. <br>\n\t\t\tDefault — *false*."
-        },
-        "shadowCascadeCount": {
-          "!type": "number",
-          "!doc": "Number of shadow maps to allocate in a cascade (one after another). <br>\n\t\t\tDefault — *2*."
-        },
-        "shadowCascadeOffset": {
-          "!type": "+THREE.Vector3",
-          "!doc": "A relative position to real camera where virtual shadow cameras are attached. A magic vector; scene and light orientation dependent. <br>\n\t\t\tDefault — *Three.Vector3( 0, 0, -1000 )*."
-        },
-        "shadowCascadeBias": {
-          "!type": "[]",
-          "!doc": "An array of shadowMapBias values for the corresponding shadow map in the cascade, near to far. <br>\n\t\t\tDefault — <strong>[ 0, 0, 0 ]</strong>."
-        },
-        "shadowCascadeWidth": {
-          "!type": "[]",
-          "!doc": "An array of shadowMapWidth values for the corresponding shadow map in the cascade, near to far. <br>\n\t\t\tDefault — <strong>[ 512, 512, 512 ]</strong>."
-        },
-        "shadowCascadeHeight": {
-          "!type": "[]",
-          "!doc": "An array of shadowMapHeight values for the corresponding shadow map in the cascade, near to far. <br>\n\t\t\tDefault — <strong>[ 512, 512, 512 ]</strong>."
-        },
-        "shadowCascadeNearZ": {
-          "!type": "[]",
-          "!doc": "An array of shadowMapNear values for the corresponding shadow map in the cascade, near to far. These typically start with -1.0 (near plane) and match with the previous shadowCascadeFarZ array value.<br>\n\t\t\tDefault — <strong>[ -1.000, 0.990, 0.998 ]</strong>."
-        },
-        "shadowCascadeFarZ": {
-          "!type": "[]",
-          "!doc": "An array of shadowMapFar values for the corresponding shadow map in the cascade, near to far. These typically match with the next shadowCascadeNearZ array value, ending in 1.0.<br>\n\t\t\tDefault — <strong>[ 0.990, 0.998, 1.000 ]</strong>."
-        },
-        "shadowCascadeArray": {
-          "!type": "[]",
-          "!doc": "Array of size shadowCascadeCount of [page:DirectionalLight THREE.DirectionalLight] objects. This holds the series of separate shadow maps in a cascade, near to far. Created internally."
-        },
-        "shadowMapSize": {
-          "!type": "+THREE.Vector2",
-          "!doc": "The shadowMapWidth and shadowMapHeight stored in a [page:Vector2 THREE.Vector2]. Set internally during rendering."
-        },
-        "shadowCamera": {
-          "!type": "+THREE.OrthographicCamera",
-          "!doc": "The shadow's view of the world. Computed internally during rendering from the shadowCamera* settings."
-        },
-        "shadowMatrix": {
-          "!type": "+THREE.Matrix4",
-          "!doc": "Model to shadow camera space, to compute location and depth in shadow map. Computed internally during rendering."
-        },
-        "shadowMap": {
-          "!type": "+THREE.WebGLRenderTarget",
-          "!doc": "The depth map generated using the shadowCamera; a location beyond a pixel's depth is in shadow. Computed internally during rendering."
         }
       },
       "!doc": "Affects objects using [page:MeshLambertMaterial] or [page:MeshPhongMaterial].",
@@ -2260,62 +2156,6 @@
         "exponent": {
           "!type": "number",
           "!doc": "Rapidity of the falloff of light from its target direction.<br>\n\t\t\tDefault — *10.0*."
-        },
-        "castShadow": {
-          "!type": "bool",
-          "!doc": "If set to *true* light will cast dynamic shadows. *Warning*: This is expensive and requires tweaking to get shadows looking right.<br>\n\t\t\tDefault — *false*."
-        },
-        "onlyShadow": {
-          "!type": "bool",
-          "!doc": "If set to *true* light will only cast shadow but not contribute any lighting (as if *intensity* was 0 but cheaper to compute).<br>\n\t\t\tDefault — *false*."
-        },
-        "shadowCameraNear": {
-          "!type": "number",
-          "!doc": "Perspective shadow camera frustum <em>near</em> parameter.<br>\n\t\t\tDefault — *50*."
-        },
-        "shadowCameraFar": {
-          "!type": "number",
-          "!doc": "Perspective shadow camera frustum <em>far</em> parameter.<br>\n\t\t\tDefault — *5000*."
-        },
-        "shadowCameraFov": {
-          "!type": "number",
-          "!doc": "Perspective shadow camera frustum <em>field of view</em> parameter.<br>\n\t\t\tDefault — *50*."
-        },
-        "shadowCameraVisible": {
-          "!type": "bool",
-          "!doc": "Show debug shadow camera frustum.<br>\n\t\t\tDefault — *false*."
-        },
-        "shadowBias": {
-          "!type": "number",
-          "!doc": "Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow.<br>\n\t\t\tDefault — *0*."
-        },
-        "shadowDarkness": {
-          "!type": "number",
-          "!doc": "Darkness of shadow casted by this light (from *0* to *1*).<br>\n\t\t\tDefault — *0.5*."
-        },
-        "shadowMapWidth": {
-          "!type": "number",
-          "!doc": "Shadow map texture width in pixels.<br>\n\t\t\tDefault — *512*."
-        },
-        "shadowMapHeight": {
-          "!type": "number",
-          "!doc": "Shadow map texture height in pixels.<br>\n\t\t\tDefault — *512*."
-        },
-        "shadowMapSize": {
-          "!type": "+THREE.Vector2",
-          "!doc": "The shadowMapWidth and shadowMapHeight stored in a [page:Vector2 THREE.Vector2]. Set internally during rendering."
-        },
-        "shadowCamera": {
-          "!type": "+THREE.PerspectiveCamera",
-          "!doc": "The shadow's view of the world. Computed internally during rendering from the shadowCamera* settings."
-        },
-        "shadowMatrix": {
-          "!type": "+THREE.Matrix4",
-          "!doc": "Model to shadow camera space, to compute location and depth in shadow map. Computed internally during rendering."
-        },
-        "shadowMap": {
-          "!type": "+THREE.WebGLRenderTarget",
-          "!doc": "The depth map generated using the shadowCamera; a location beyond a pixel's depth is in shadow. Computed internally during rendering."
         }
       },
       "!doc": "A point light that can cast shadow in one direction.",

+ 103 - 74
editor/js/libs/ui.js

@@ -12,6 +12,60 @@ UI.Element = function ( dom ) {
 
 UI.Element.prototype = {
 
+	add: function () {
+
+		for ( var i = 0; i < arguments.length; i ++ ) {
+
+			var argument = arguments[ i ];
+
+			if ( argument instanceof UI.Element ) {
+
+				this.dom.appendChild( argument.dom );
+
+			} else {
+
+				console.error( 'UI.Element:', argument, 'is not an instance of UI.Element.' )
+
+			}
+
+		}
+
+		return this;
+
+	},
+
+	remove: function () {
+
+		for ( var i = 0; i < arguments.length; i ++ ) {
+
+			var argument = arguments[ i ];
+
+			if ( argument instanceof UI.Element ) {
+
+				this.dom.removeChild( argument.dom );
+
+			} else {
+
+				console.error( 'UI.Element:', argument, 'is not an instance of UI.Element.' )
+
+			}
+
+		}
+
+		return this;
+
+	},
+
+	clear: function () {
+
+		while ( this.dom.children.length ) {
+
+			this.dom.removeChild( this.dom.lastChild );
+
+		}
+
+	},
+
 	setId: function ( id ) {
 
 		this.dom.id = id;
@@ -36,6 +90,8 @@ UI.Element.prototype = {
 
 		}
 
+		return this;
+
 	},
 
 	setDisabled: function ( value ) {
@@ -69,6 +125,7 @@ properties.forEach( function ( property ) {
 	UI.Element.prototype[ method ] = function () {
 
 		this.setStyle( property, arguments );
+
 		return this;
 
 	};
@@ -93,78 +150,39 @@ events.forEach( function ( event ) {
 
 } );
 
+// Span
 
-// Panel
-
-UI.Panel = function () {
+UI.Span = function () {
 
 	UI.Element.call( this );
 
-	var dom = document.createElement( 'div' );
-	dom.className = 'Panel';
-
-	this.dom = dom;
-
-	return this;
-};
-
-UI.Panel.prototype = Object.create( UI.Element.prototype );
-UI.Panel.prototype.constructor = UI.Panel;
-
-UI.Panel.prototype.add = function () {
-
-	for ( var i = 0; i < arguments.length; i ++ ) {
-
-		var argument = arguments[ i ];
-
-		if ( argument instanceof UI.Element ) {
-
-			this.dom.appendChild( argument.dom );
-
-		} else {
-
-			console.error( 'UI.Panel:', argument, 'is not an instance of UI.Element.' )
-
-		}
-
-	}
+	this.dom = document.createElement( 'span' );
 
 	return this;
 
 };
 
+UI.Span.prototype = Object.create( UI.Element.prototype );
+UI.Span.prototype.constructor = UI.Span;
 
-UI.Panel.prototype.remove = function () {
-
-	for ( var i = 0; i < arguments.length; i ++ ) {
-
-		var argument = arguments[ i ];
 
-		if ( argument instanceof UI.Element ) {
-
-			this.dom.removeChild( argument.dom );
+// Panel
 
-		} else {
+UI.Panel = function () {
 
-			console.error( 'UI.Panel:', argument, 'is not an instance of UI.Element.' )
+	UI.Element.call( this );
 
-		}
+	var dom = document.createElement( 'div' );
+	dom.className = 'Panel';
 
-	}
+	this.dom = dom;
 
 	return this;
 
 };
 
-UI.Panel.prototype.clear = function () {
-
-	while ( this.dom.children.length ) {
-
-		this.dom.removeChild( this.dom.lastChild );
-
-	}
-
-};
+UI.Panel.prototype = Object.create( UI.Element.prototype );
+UI.Panel.prototype.constructor = UI.Panel;
 
 
 // Collapsible Panel
@@ -996,47 +1014,58 @@ UI.Button.prototype.setLabel = function ( value ) {
 };
 
 
-// Dialog
+// Modal
 
-UI.Dialog = function ( value ) {
+UI.Modal = function ( value ) {
 
 	var scope = this;
 
-	var dom = document.createElement( 'dialog' );
+	var dom = document.createElement( 'div' );
 
-	if ( dom.showModal === undefined ) {
+	dom.style.position = 'absolute';
+	dom.style.width = '100%';
+	dom.style.height = '100%';
+	dom.style.backgroundColor = 'rgba(0,0,0,0.5)';
+	dom.style.display = 'none';
+	dom.style.alignItems = 'center';
+	dom.style.justifyContent = 'center';
+	dom.addEventListener( 'click', function ( event ) {
 
-		// fallback
+		scope.hide();
 
-		dom = document.createElement( 'div' );
-		dom.style.display = 'none';
+	} );
 
-		dom.showModal = function () {
+	this.dom = dom;
 
-			dom.style.position = 'absolute';
-			dom.style.left = '100px';
-			dom.style.top = '100px';
-			dom.style.zIndex = 1;
-			dom.style.display = '';
+	this.container = new UI.Panel();
+	this.container.dom.style.width = '200px';
+	this.container.dom.style.padding = '20px';
+	this.container.dom.style.backgroundColor = '#ffffff';
+	this.container.dom.style.boxShadow = '0px 5px 10px rgba(0,0,0,0.5)';
 
-		};
+	this.add( this.container );
 
-	}
+	return this;
 
-	dom.className = 'Dialog';
+};
 
-	this.dom = dom;
+UI.Modal.prototype = Object.create( UI.Element.prototype );
+UI.Modal.prototype.constructor = UI.Modal;
+
+UI.Modal.prototype.show = function ( content ) {
+
+	this.container.clear();
+	this.container.add( content );
+
+	this.dom.style.display = 'flex';
 
 	return this;
 
 };
 
-UI.Dialog.prototype = Object.create( UI.Panel.prototype );
-UI.Dialog.prototype.constructor = UI.Dialog;
-
-UI.Dialog.prototype.showModal = function () {
+UI.Modal.prototype.hide = function () {
 
-	this.dom.showModal();
+	this.dom.style.display = 'none';
 
 	return this;
 

+ 1 - 1
examples/canvas_geometry_panorama_fisheye.html

@@ -103,7 +103,7 @@
 				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 				document.addEventListener( 'mouseup', onDocumentMouseUp, false );
 				document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
-				document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false);
+				document.addEventListener( 'MozMousePixelScroll', onDocumentMouseWheel, false);
 
 				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
 				document.addEventListener( 'touchmove', onDocumentTouchMove, false );

+ 8 - 4
examples/canvas_geometry_text.html

@@ -23,8 +23,8 @@
 
 		<script src="js/libs/stats.min.js"></script>
 
-		<!-- load the font file from canvas-text -->
-
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_regular.typeface.js"></script>
 
 
@@ -90,8 +90,12 @@
 				text3d.computeBoundingBox();
 				var centerOffset = -0.5 * ( text3d.boundingBox.max.x - text3d.boundingBox.min.x );
 
-				var textMaterial = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } );
-				text = new THREE.Mesh( text3d, textMaterial );
+				var material = new THREE.MeshFaceMaterial( [
+					new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
+					new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
+				] );
+
+				text = new THREE.Mesh( text3d, material );
 
 				text.position.x = centerOffset;
 				text.position.y = 100;

+ 2 - 2
examples/canvas_interactive_cubes.html

@@ -139,8 +139,8 @@
 
 				event.preventDefault();
 
-				mouse.x = ( event.clientX / renderer.domElement.width ) * 2 - 1;
-				mouse.y = - ( event.clientY / renderer.domElement.height ) * 2 + 1;
+				mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
+				mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
 
 				raycaster.setFromCamera( mouse, camera );
 

+ 2 - 2
examples/canvas_interactive_cubes_tween.html

@@ -119,8 +119,8 @@
 
 				event.preventDefault();
 
-				mouse.x = ( event.clientX / renderer.domElement.width ) * 2 - 1;
-				mouse.y = - ( event.clientY / renderer.domElement.height ) * 2 + 1;
+				mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
+				mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
 
 				raycaster.setFromCamera( mouse, camera );
 

+ 2 - 2
examples/canvas_interactive_voxelpainter.html

@@ -141,8 +141,8 @@
 
 				event.preventDefault();
 
-				mouse.x = ( event.clientX / renderer.domElement.width ) * 2 - 1;
-				mouse.y = - ( event.clientY / renderer.domElement.height ) * 2 + 1;
+				mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
+				mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
 
 				raycaster.setFromCamera( mouse, camera );
 

+ 0 - 1
examples/canvas_materials.html

@@ -73,7 +73,6 @@
 					new THREE.MeshBasicMaterial( { color: 0xff0000, blending: THREE.AdditiveBlending } ),
 					new THREE.MeshLambertMaterial( { color: 0xffffff, shading: THREE.FlatShading, overdraw: 0.5 } ),
 					new THREE.MeshLambertMaterial( { color: 0xffffff, shading: THREE.SmoothShading, overdraw: 0.5 } ),
-					new THREE.MeshDepthMaterial( { overdraw: 0.5 } ),
 					new THREE.MeshNormalMaterial( { overdraw: 0.5 } ),
 					new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'textures/land_ocean_ice_cloud_2048.jpg' ) } ),
 					new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'textures/envmap.png', THREE.SphericalReflectionMapping ), overdraw: 0.5 } )

+ 0 - 238
examples/canvas_materials_depth.html

@@ -1,238 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js canvas - depth material</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				font-family: Monospace;
-				background-color: #000000;
-				margin: 0px;
-				overflow: hidden;
-			}
-		</style>
-	</head>
-	<body>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/renderers/Projector.js"></script>
-		<script src="js/renderers/CanvasRenderer.js"></script>
-
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			var container, stats;
-
-			var camera, scene, renderer;
-
-			var cube, plane, objects = [];
-
-			var targetRotation = 0;
-			var targetRotationOnMouseDown = 0;
-
-			var mouseX = 0;
-			var mouseXOnMouseDown = 0;
-
-			var moveForward = false;
-			var moveBackwards = false;
-			var moveLeft = false;
-			var moveRight = false;
-			var moveUp = false;
-			var moveDown = false;
-
-			var targetMoveLeft = false;
-			var targetMoveRight = false;
-
-			var debugContext;
-
-			init();
-			animate();
-
-			function init() {
-
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
-				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
-				camera.position.set( 1000, 1000, 1000 );
-				camera.target = new THREE.Vector3( 0, 150, 0 );
-
-				scene = new THREE.Scene();
-
-				// Plane
-
-				var material = new THREE.MeshDepthMaterial( { side: THREE.DoubleSide, overdraw: 0.5 } );
-
-				plane = new THREE.Mesh( new THREE.PlaneBufferGeometry( 1000, 1000, 10, 10 ), material );
-				plane.position.y = - 100;
-				plane.rotation.x = - Math.PI / 2;
-				scene.add( plane );
-
-				// Cubes
-
-				geometry = new THREE.BoxGeometry( 100, 100, 100 );
-				material = new THREE.MeshDepthMaterial( { overdraw: 0.5 } );
-
-				for ( var i = 0; i < 20; i ++ ) {
-
-					cube = new THREE.Mesh( geometry, material );
-
-					cube.position.x = ( i % 5 ) * 200 - 400;
-					cube.position.z = Math.floor( i / 5 ) * 200 - 350;
-
-					cube.rotation.x = Math.random() * 200 - 100;
-					cube.rotation.y = Math.random() * 200 - 100;
-					cube.rotation.z = Math.random() * 200 - 100;
-
-					scene.add( cube );
-
-					objects.push( cube );
-
-				}
-
-				renderer = new THREE.CanvasRenderer();
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
-
-				var debugCanvas = document.createElement( 'canvas' );
-				debugCanvas.width = 512;
-				debugCanvas.height = 512;
-				debugCanvas.style.position = 'absolute';
-				debugCanvas.style.top = '0px';
-				debugCanvas.style.left = '0px';
-
-				container.appendChild( debugCanvas );
-
-				debugContext = debugCanvas.getContext( '2d' );
-				debugContext.setTransform( 1, 0, 0, 1, 256, 256 );
-				debugContext.strokeStyle = '#808080';
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '0px';
-				container.appendChild(stats.domElement);
-
-				document.addEventListener( 'keydown', onDocumentKeyDown, false );
-				document.addEventListener( 'keyup', onDocumentKeyUp, false );
-
-				//
-
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			function onWindowResize() {
-
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
-
-				renderer.setSize( window.innerWidth, window.innerHeight );
-
-			}
-
-			function onDocumentKeyDown( event ) {
-
-				switch ( event.keyCode ) {
-
-					case 38: moveForward = true; break; // up
-					case 40: moveBackwards = true; break; // down
-					case 37: moveLeft = true; break; // left
-					case 39: moveRight = true; break; // right
-					case 87: moveUp = true; break; // w
-					case 83: moveDown = true; break; // s
-					case 65: targetMoveLeft = true; break; // a
-					case 68: targetMoveRight = true; break; // d
-
-				}
-
-			}
-
-			function onDocumentKeyUp( event ) {
-
-				switch ( event.keyCode ) {
-
-					case 38: moveForward = false; break; // up
-					case 40: moveBackwards = false; break; // down
-					case 37: moveLeft = false; break; // left
-					case 39: moveRight = false; break; // right
-					case 87: moveUp = false; break; // w
-					case 83: moveDown = false; break; // s
-					case 65: targetMoveLeft = false; break; // a
-					case 68: targetMoveRight = false; break; // d
-
-				}
-
-			}
-
-			//
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				if ( moveForward ) camera.position.z -= 10;
-				if ( moveBackwards ) camera.position.z += 10;
-
-				if ( moveLeft ) camera.position.x -= 10;
-				if ( moveRight ) camera.position.x += 10;
-
-				if ( moveUp ) camera.position.y += 10;
-				if ( moveDown ) camera.position.y -= 10;
-
-				if ( targetMoveLeft ) camera.target.x -= 10;
-				if ( targetMoveRight ) camera.target.x += 10;
-
-				camera.lookAt( camera.target );
-
-				debugContext.clearRect( - 256, - 256, 512, 512 );
-
-				debugContext.beginPath();
-
-				// center
-				debugContext.moveTo( - 10, 0 );
-				debugContext.lineTo( 10, 0 );
-				debugContext.moveTo( 0, - 10 );
-				debugContext.lineTo( 0, 10 );
-
-				// camera
-
-				debugContext.moveTo( camera.position.x * 0.1, camera.position.z * 0.1 );
-				debugContext.lineTo( camera.target.x * 0.1, camera.target.z * 0.1 );
-				debugContext.rect( camera.position.x * 0.1 - 5, camera.position.z * 0.1 - 5, 10, 10 );
-				debugContext.rect( camera.target.x * 0.1 - 5, camera.target.z * 0.1 - 5, 10, 10 );
-				debugContext.rect( - 50, - 50, 100, 100 );
-
-				for ( var i = 0; i < objects.length; i++ ) {
-
-					var object = objects[ i ];
-
-					object.rotation.x += 0.01;
-					object.rotation.y += 0.005;
-					object.position.y = Math.sin( object.rotation.x ) * 200 + 200;
-
-					debugContext.rect( object.position.x * 0.1 - 5, object.position.z * 0.1 - 5, 10, 10 );
-
-				}
-
-				debugContext.closePath();
-				debugContext.stroke();
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-
-	</body>
-</html>

+ 10 - 4
examples/canvas_morphtargets_horse.html

@@ -54,25 +54,31 @@
 
 				//
 
-				var light = new THREE.DirectionalLight( 0xefefff, 2 );
+				var light = new THREE.DirectionalLight( 0xefefff, 1.5 );
 				light.position.set( 1, 1, 1 ).normalize();
 				scene.add( light );
 
-				var light = new THREE.DirectionalLight( 0xffefef, 2 );
+				var light = new THREE.DirectionalLight( 0xffefef, 1.5 );
 				light.position.set( -1, -1, -1 ).normalize();
 				scene.add( light );
 
 				var loader = new THREE.JSONLoader();
 				loader.load( "models/animated/horse.js", function ( geometry ) {
 
-					mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0x606060, morphTargets: true, overdraw: 0.5 } ) );
+					var material = new THREE.MeshLambertMaterial( {
+						vertexColors: THREE.FaceColors,
+						morphTargets: true,
+						overdraw: 0.5
+					} );
+
+					mesh = new THREE.Mesh( geometry, material );
 					mesh.scale.set( 1.5, 1.5, 1.5 );
 					scene.add( mesh );
 
 					mixer = new THREE.AnimationMixer( mesh );
 
 					var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
-					mixer.addAction( new THREE.AnimationAction( clip ).warpToDuration( 1.5 ) );
+					mixer.addAction( new THREE.AnimationAction( clip ).warpToDuration( 1 ) );
 
 				} );
 

+ 8 - 3
examples/index.html

@@ -13,7 +13,7 @@
 				font-style: normal;
 			}
 
-			*{
+			* {
 				box-sizing: border-box;
 			}
 
@@ -190,6 +190,7 @@
 		var files = {
 			"webgl": [
 				"webgl_animation_cloth",
+				"webgl_animation_scene",
 				"webgl_animation_skinning_blending",
 				"webgl_animation_skinning_morph",
 				"webgl_camera",
@@ -224,7 +225,8 @@
 				"webgl_geometry_terrain_fog",
 				"webgl_geometry_terrain_raycast",
 				"webgl_geometry_text",
-				"webgl_geometry_text2",
+				"webgl_geometry_text_earcut",
+				"webgl_geometry_text_pnltri",
 				"webgl_gpgpu_birds",
 				"webgl_gpu_particle_system",
 				"webgl_hdr",
@@ -248,6 +250,7 @@
 				"webgl_lines_dashed",
 				"webgl_lines_sphere",
 				"webgl_lines_splines",
+				"webgl_loader_amf",
 				"webgl_loader_assimp2json",
 				"webgl_loader_awd",
 				"webgl_loader_babylon",
@@ -347,6 +350,7 @@
 				"webgl_postprocessing_godrays",
 				"webgl_postprocessing_ssao",
 				"webgl_raycast_texture",
+				"webgl_read_float_buffer",
 				"webgl_rtt",
 				"webgl_sandbox",
 				"webgl_shader",
@@ -360,6 +364,7 @@
 				"webgl_shading_physical",
 				"webgl_shadowmap",
 				"webgl_shadowmap_performance",
+				"webgl_shadowmap_pointlight",
 				"webgl_shadowmap_viewer",
 				"webgl_shadowmesh",
 				"webgl_skinning_simple",
@@ -383,6 +388,7 @@
 				"webgl_buffergeometry_lines_indexed",
 				"webgl_buffergeometry_points",
 				"webgl_buffergeometry_rawshader",
+				"webgl_buffergeometry_selective_draw",
 				"webgl_buffergeometry_uint",
 				"webgl_custom_attributes",
 				"webgl_custom_attributes_lines",
@@ -448,7 +454,6 @@
 				"canvas_lines_dashed",
 				"canvas_lines_sphere",
 				"canvas_materials",
-				"canvas_materials_depth",
 				"canvas_materials_normal",
 				"canvas_materials_reflection",
 				"canvas_materials_video",

+ 6 - 5
examples/js/ShaderSkin.js

@@ -80,8 +80,6 @@ THREE.ShaderSkin = {
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
-			"uniform vec3 ambientLightColor;",
-
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
@@ -138,6 +136,7 @@ THREE.ShaderSkin = {
 
 				"vec3 outgoingLight = vec3( 0.0 );",	// outgoing light does not have an alpha, the surface does
 				"vec4 diffuseColor = vec4( diffuse, opacity );",
+				"vec3 shadowMask = vec3( 1.0 );",
 
 				"vec4 colDiffuse = texture2D( tDiffuse, vUv );",
 				"colDiffuse.rgb *= colDiffuse.rgb;",
@@ -246,9 +245,13 @@ THREE.ShaderSkin = {
 
 				"#endif",
 
+				THREE.ShaderChunk[ "shadowmap_fragment" ],
+
+				"totalDiffuseLight *= shadowMask;",
+				"totalSpecularLight *= shadowMask;",
+
 				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;",
 
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 
@@ -367,8 +370,6 @@ THREE.ShaderSkin = {
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
-			"uniform vec3 ambientLightColor;",
-
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],

+ 2 - 2
examples/js/controls/EditorControls.js

@@ -214,7 +214,7 @@ THREE.EditorControls = function ( object, domElement ) {
 		domElement.removeEventListener( 'contextmenu', contextmenu, false );
 		domElement.removeEventListener( 'mousedown', onMouseDown, false );
 		domElement.removeEventListener( 'mousewheel', onMouseWheel, false );
-		domElement.removeEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
+		domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox
 
 		domElement.removeEventListener( 'mousemove', onMouseMove, false );
 		domElement.removeEventListener( 'mouseup', onMouseUp, false );
@@ -229,7 +229,7 @@ THREE.EditorControls = function ( object, domElement ) {
 	domElement.addEventListener( 'contextmenu', contextmenu, false );
 	domElement.addEventListener( 'mousedown', onMouseDown, false );
 	domElement.addEventListener( 'mousewheel', onMouseWheel, false );
-	domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
+	domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox
 
 	// touch
 

+ 2 - 2
examples/js/controls/OrbitControls.js

@@ -778,7 +778,7 @@
 			this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
 			this.domElement.removeEventListener( 'mousedown', onMouseDown, false );
 			this.domElement.removeEventListener( 'mousewheel', onMouseWheel, false );
-			this.domElement.removeEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
+			this.domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox
 
 			this.domElement.removeEventListener( 'touchstart', touchstart, false );
 			this.domElement.removeEventListener( 'touchend', touchend, false );
@@ -795,7 +795,7 @@
 
 		this.domElement.addEventListener( 'mousedown', onMouseDown, false );
 		this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
-		this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
+		this.domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox
 
 		this.domElement.addEventListener( 'touchstart', touchstart, false );
 		this.domElement.addEventListener( 'touchend', touchend, false );

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

@@ -617,7 +617,7 @@ THREE.OrthographicTrackballControls = function ( object, domElement ) {
 		this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
 		this.domElement.removeEventListener( 'mousedown', mousedown, false );
 		this.domElement.removeEventListener( 'mousewheel', mousewheel, false );
-		this.domElement.removeEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
+		this.domElement.removeEventListener( 'MozMousePixelScroll', mousewheel, false ); // firefox
 
 		this.domElement.removeEventListener( 'touchstart', touchstart, false );
 		this.domElement.removeEventListener( 'touchend', touchend, false );
@@ -635,7 +635,7 @@ THREE.OrthographicTrackballControls = function ( object, domElement ) {
 	this.domElement.addEventListener( 'contextmenu', contextmenu, false );
 	this.domElement.addEventListener( 'mousedown', mousedown, false );
 	this.domElement.addEventListener( 'mousewheel', mousewheel, false );
-	this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
+	this.domElement.addEventListener( 'MozMousePixelScroll', mousewheel, false ); // firefox
 
 	this.domElement.addEventListener( 'touchstart', touchstart, false );
 	this.domElement.addEventListener( 'touchend', touchend, false );

+ 2 - 2
examples/js/controls/TrackballControls.js

@@ -597,7 +597,7 @@ THREE.TrackballControls = function ( object, domElement ) {
 		this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
 		this.domElement.removeEventListener( 'mousedown', mousedown, false );
 		this.domElement.removeEventListener( 'mousewheel', mousewheel, false );
-		this.domElement.removeEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
+		this.domElement.removeEventListener( 'MozMousePixelScroll', mousewheel, false ); // firefox
 
 		this.domElement.removeEventListener( 'touchstart', touchstart, false );
 		this.domElement.removeEventListener( 'touchend', touchend, false );
@@ -614,7 +614,7 @@ THREE.TrackballControls = function ( object, domElement ) {
 	this.domElement.addEventListener( 'contextmenu', contextmenu, false );
 	this.domElement.addEventListener( 'mousedown', mousedown, false );
 	this.domElement.addEventListener( 'mousewheel', mousewheel, false );
-	this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
+	this.domElement.addEventListener( 'MozMousePixelScroll', mousewheel, false ); // firefox
 
 	this.domElement.addEventListener( 'touchstart', touchstart, false );
 	this.domElement.addEventListener( 'touchend', touchend, false );

+ 0 - 0
src/extras/geometries/TextGeometry.js → examples/js/geometries/TextGeometry.js


+ 674 - 0
examples/js/libs/earcut.js

@@ -0,0 +1,674 @@
+/**
+ *
+ * Earcut https://github.com/mapbox/earcut
+ *
+ * Copyright (c) 2015, Mapbox
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose
+ * with or without fee is hereby granted, provided that the above copyright notice
+ * and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+'use strict';
+
+//module.exports = earcut;
+
+function earcut(data, holeIndices, dim) {
+
+    dim = dim || 2;
+
+    var hasHoles = holeIndices && holeIndices.length,
+        outerLen = hasHoles ? holeIndices[0] * dim : data.length,
+        outerNode = filterPoints(data, linkedList(data, 0, outerLen, dim, true)),
+        triangles = [];
+
+    if (!outerNode) return triangles;
+
+    var minX, minY, maxX, maxY, x, y, size;
+
+    if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
+
+    // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
+    if (data.length > 80 * dim) {
+        minX = maxX = data[0];
+        minY = maxY = data[1];
+
+        for (var i = dim; i < outerLen; i += dim) {
+            x = data[i];
+            y = data[i + 1];
+            if (x < minX) minX = x;
+            if (y < minY) minY = y;
+            if (x > maxX) maxX = x;
+            if (y > maxY) maxY = y;
+        }
+
+        // minX, minY and size are later used to transform coords into integers for z-order calculation
+        size = Math.max(maxX - minX, maxY - minY);
+    }
+
+    earcutLinked(data, outerNode, triangles, dim, minX, minY, size);
+
+    return triangles;
+}
+
+// create a circular doubly linked list from polygon points in the specified winding order
+function linkedList(data, start, end, dim, clockwise) {
+    var sum = 0,
+        i, j, last;
+
+    // calculate original winding order of a polygon ring
+    for (i = start, j = end - dim; i < end; i += dim) {
+        sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
+        j = i;
+    }
+
+    // link points into circular doubly-linked list in the specified winding order
+    if (clockwise === (sum > 0)) {
+        for (i = start; i < end; i += dim) last = insertNode(i, last);
+    } else {
+        for (i = end - dim; i >= start; i -= dim) last = insertNode(i, last);
+    }
+
+    return last;
+}
+
+// eliminate colinear or duplicate points
+function filterPoints(data, start, end) {
+    if (!start) return start;
+    if (!end) end = start;
+
+    var node = start,
+        again;
+    do {
+        again = false;
+
+        if (!node.steiner && (equals(data, node.i, node.next.i) || orient(data, node.prev.i, node.i, node.next.i) === 0)) {
+            removeNode(node);
+            node = end = node.prev;
+            if (node === node.next) return null;
+            again = true;
+
+        } else {
+            node = node.next;
+        }
+    } while (again || node !== end);
+
+    return end;
+}
+
+// main ear slicing loop which triangulates a polygon (given as a linked list)
+function earcutLinked(data, ear, triangles, dim, minX, minY, size, pass) {
+    if (!ear) return;
+
+    // interlink polygon nodes in z-order
+    if (!pass && minX !== undefined) indexCurve(data, ear, minX, minY, size);
+
+    var stop = ear,
+        prev, next;
+
+    // iterate through ears, slicing them one by one
+    while (ear.prev !== ear.next) {
+        prev = ear.prev;
+        next = ear.next;
+
+        if (isEar(data, ear, minX, minY, size)) {
+            // cut off the triangle
+            triangles.push(prev.i / dim);
+            triangles.push(ear.i / dim);
+            triangles.push(next.i / dim);
+
+            removeNode(ear);
+
+            // skipping the next vertice leads to less sliver triangles
+            ear = next.next;
+            stop = next.next;
+
+            continue;
+        }
+
+        ear = next;
+
+        // if we looped through the whole remaining polygon and can't find any more ears
+        if (ear === stop) {
+            // try filtering points and slicing again
+            if (!pass) {
+                earcutLinked(data, filterPoints(data, ear), triangles, dim, minX, minY, size, 1);
+
+            // if this didn't work, try curing all small self-intersections locally
+            } else if (pass === 1) {
+                ear = cureLocalIntersections(data, ear, triangles, dim);
+                earcutLinked(data, ear, triangles, dim, minX, minY, size, 2);
+
+            // as a last resort, try splitting the remaining polygon into two
+            } else if (pass === 2) {
+                splitEarcut(data, ear, triangles, dim, minX, minY, size);
+            }
+
+            break;
+        }
+    }
+}
+
+// check whether a polygon node forms a valid ear with adjacent nodes
+function isEar(data, ear, minX, minY, size) {
+
+    var a = ear.prev.i,
+        b = ear.i,
+        c = ear.next.i,
+
+        ax = data[a], ay = data[a + 1],
+        bx = data[b], by = data[b + 1],
+        cx = data[c], cy = data[c + 1],
+
+        abd = ax * by - ay * bx,
+        acd = ax * cy - ay * cx,
+        cbd = cx * by - cy * bx,
+        A = abd - acd - cbd;
+
+    if (A <= 0) return false; // reflex, can't be an ear
+
+    // now make sure we don't have other points inside the potential ear;
+    // the code below is a bit verbose and repetitive but this is done for performance
+
+    var cay = cy - ay,
+        acx = ax - cx,
+        aby = ay - by,
+        bax = bx - ax,
+        i, px, py, s, t, k, node;
+
+    // if we use z-order curve hashing, iterate through the curve
+    if (minX !== undefined) {
+
+        // triangle bbox; min & max are calculated like this for speed
+        var minTX = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
+            minTY = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy),
+            maxTX = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx),
+            maxTY = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy),
+
+            // z-order range for the current triangle bbox;
+            minZ = zOrder(minTX, minTY, minX, minY, size),
+            maxZ = zOrder(maxTX, maxTY, minX, minY, size);
+
+        // first look for points inside the triangle in increasing z-order
+        node = ear.nextZ;
+
+        while (node && node.z <= maxZ) {
+            i = node.i;
+            node = node.nextZ;
+            if (i === a || i === c) continue;
+
+            px = data[i];
+            py = data[i + 1];
+
+            s = cay * px + acx * py - acd;
+            if (s >= 0) {
+                t = aby * px + bax * py + abd;
+                if (t >= 0) {
+                    k = A - s - t;
+                    if ((k >= 0) && ((s && t) || (s && k) || (t && k))) return false;
+                }
+            }
+        }
+
+        // then look for points in decreasing z-order
+        node = ear.prevZ;
+
+        while (node && node.z >= minZ) {
+            i = node.i;
+            node = node.prevZ;
+            if (i === a || i === c) continue;
+
+            px = data[i];
+            py = data[i + 1];
+
+            s = cay * px + acx * py - acd;
+            if (s >= 0) {
+                t = aby * px + bax * py + abd;
+                if (t >= 0) {
+                    k = A - s - t;
+                    if ((k >= 0) && ((s && t) || (s && k) || (t && k))) return false;
+                }
+            }
+        }
+
+    // if we don't use z-order curve hash, simply iterate through all other points
+    } else {
+        node = ear.next.next;
+
+        while (node !== ear.prev) {
+            i = node.i;
+            node = node.next;
+
+            px = data[i];
+            py = data[i + 1];
+
+            s = cay * px + acx * py - acd;
+            if (s >= 0) {
+                t = aby * px + bax * py + abd;
+                if (t >= 0) {
+                    k = A - s - t;
+                    if ((k >= 0) && ((s && t) || (s && k) || (t && k))) return false;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+// go through all polygon nodes and cure small local self-intersections
+function cureLocalIntersections(data, start, triangles, dim) {
+    var node = start;
+    do {
+        var a = node.prev,
+            b = node.next.next;
+
+        // a self-intersection where edge (v[i-1],v[i]) intersects (v[i+1],v[i+2])
+        if (a.i !== b.i && intersects(data, a.i, node.i, node.next.i, b.i) &&
+                locallyInside(data, a, b) && locallyInside(data, b, a) &&
+                orient(data, a.i, node.i, b.i) && orient(data, a.i, node.next.i, b.i)) {
+
+            triangles.push(a.i / dim);
+            triangles.push(node.i / dim);
+            triangles.push(b.i / dim);
+
+            // remove two nodes involved
+            removeNode(node);
+            removeNode(node.next);
+
+            node = start = b;
+        }
+        node = node.next;
+    } while (node !== start);
+
+    return node;
+}
+
+// try splitting polygon into two and triangulate them independently
+function splitEarcut(data, start, triangles, dim, minX, minY, size) {
+    // look for a valid diagonal that divides the polygon into two
+    var a = start;
+    do {
+        var b = a.next.next;
+        while (b !== a.prev) {
+            if (a.i !== b.i && isValidDiagonal(data, a, b)) {
+                // split the polygon in two by the diagonal
+                var c = splitPolygon(a, b);
+
+                // filter colinear points around the cuts
+                a = filterPoints(data, a, a.next);
+                c = filterPoints(data, c, c.next);
+
+                // run earcut on each half
+                earcutLinked(data, a, triangles, dim, minX, minY, size);
+                earcutLinked(data, c, triangles, dim, minX, minY, size);
+                return;
+            }
+            b = b.next;
+        }
+        a = a.next;
+    } while (a !== start);
+}
+
+// link every hole into the outer loop, producing a single-ring polygon without holes
+function eliminateHoles(data, holeIndices, outerNode, dim) {
+    var queue = [],
+        i, len, start, end, list;
+
+    for (i = 0, len = holeIndices.length; i < len; i++) {
+        start = holeIndices[i] * dim;
+        end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
+        list = linkedList(data, start, end, dim, false);
+        if (list === list.next) list.steiner = true;
+        list = filterPoints(data, list);
+        if (list) queue.push(getLeftmost(data, list));
+    }
+
+    queue.sort(function (a, b) {
+        return data[a.i] - data[b.i];
+    });
+
+    // process holes from left to right
+    for (i = 0; i < queue.length; i++) {
+        eliminateHole(data, queue[i], outerNode);
+        outerNode = filterPoints(data, outerNode, outerNode.next);
+    }
+
+    return outerNode;
+}
+
+// find a bridge between vertices that connects hole with an outer ring and and link it
+function eliminateHole(data, holeNode, outerNode) {
+    outerNode = findHoleBridge(data, holeNode, outerNode);
+    if (outerNode) {
+        var b = splitPolygon(outerNode, holeNode);
+        filterPoints(data, b, b.next);
+    }
+}
+
+// David Eberly's algorithm for finding a bridge between hole and outer polygon
+function findHoleBridge(data, holeNode, outerNode) {
+    var node = outerNode,
+        i = holeNode.i,
+        px = data[i],
+        py = data[i + 1],
+        qMax = -Infinity,
+        mNode, a, b;
+
+    // find a segment intersected by a ray from the hole's leftmost point to the left;
+    // segment's endpoint with lesser x will be potential connection point
+    do {
+        a = node.i;
+        b = node.next.i;
+
+        if (py <= data[a + 1] && py >= data[b + 1]) {
+            var qx = data[a] + (py - data[a + 1]) * (data[b] - data[a]) / (data[b + 1] - data[a + 1]);
+            if (qx <= px && qx > qMax) {
+                qMax = qx;
+                mNode = data[a] < data[b] ? node : node.next;
+            }
+        }
+        node = node.next;
+    } while (node !== outerNode);
+
+    if (!mNode) return null;
+
+    // look for points strictly inside the triangle of hole point, segment intersection and endpoint;
+    // if there are no points found, we have a valid connection;
+    // otherwise choose the point of the minimum angle with the ray as connection point
+
+    var bx = data[mNode.i],
+        by = data[mNode.i + 1],
+        pbd = px * by - py * bx,
+        pcd = px * py - py * qMax,
+        cpy = py - py,
+        pcx = px - qMax,
+        pby = py - by,
+        bpx = bx - px,
+        A = pbd - pcd - (qMax * by - py * bx),
+        sign = A <= 0 ? -1 : 1,
+        stop = mNode,
+        tanMin = Infinity,
+        mx, my, amx, s, t, tan;
+
+    node = mNode.next;
+
+    while (node !== stop) {
+
+        mx = data[node.i];
+        my = data[node.i + 1];
+        amx = px - mx;
+
+        if (amx >= 0 && mx >= bx) {
+            s = (cpy * mx + pcx * my - pcd) * sign;
+            if (s >= 0) {
+                t = (pby * mx + bpx * my + pbd) * sign;
+
+                if (t >= 0 && A * sign - s - t >= 0) {
+                    tan = Math.abs(py - my) / amx; // tangential
+                    if ((tan < tanMin || (tan === tanMin && mx > bx)) &&
+                            locallyInside(data, node, holeNode)) {
+                        mNode = node;
+                        tanMin = tan;
+                    }
+                }
+            }
+        }
+
+        node = node.next;
+    }
+
+    return mNode;
+}
+
+// interlink polygon nodes in z-order
+function indexCurve(data, start, minX, minY, size) {
+    var node = start;
+
+    do {
+        if (node.z === null) node.z = zOrder(data[node.i], data[node.i + 1], minX, minY, size);
+        node.prevZ = node.prev;
+        node.nextZ = node.next;
+        node = node.next;
+    } while (node !== start);
+
+    node.prevZ.nextZ = null;
+    node.prevZ = null;
+
+    sortLinked(node);
+}
+
+// Simon Tatham's linked list merge sort algorithm
+// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
+function sortLinked(list) {
+    var i, p, q, e, tail, numMerges, pSize, qSize,
+        inSize = 1;
+
+    do {
+        p = list;
+        list = null;
+        tail = null;
+        numMerges = 0;
+
+        while (p) {
+            numMerges++;
+            q = p;
+            pSize = 0;
+            for (i = 0; i < inSize; i++) {
+                pSize++;
+                q = q.nextZ;
+                if (!q) break;
+            }
+
+            qSize = inSize;
+
+            while (pSize > 0 || (qSize > 0 && q)) {
+
+                if (pSize === 0) {
+                    e = q;
+                    q = q.nextZ;
+                    qSize--;
+                } else if (qSize === 0 || !q) {
+                    e = p;
+                    p = p.nextZ;
+                    pSize--;
+                } else if (p.z <= q.z) {
+                    e = p;
+                    p = p.nextZ;
+                    pSize--;
+                } else {
+                    e = q;
+                    q = q.nextZ;
+                    qSize--;
+                }
+
+                if (tail) tail.nextZ = e;
+                else list = e;
+
+                e.prevZ = tail;
+                tail = e;
+            }
+
+            p = q;
+        }
+
+        tail.nextZ = null;
+        inSize *= 2;
+
+    } while (numMerges > 1);
+
+    return list;
+}
+
+// z-order of a point given coords and size of the data bounding box
+function zOrder(x, y, minX, minY, size) {
+    // coords are transformed into non-negative 15-bit integer range
+    x = 32767 * (x - minX) / size;
+    y = 32767 * (y - minY) / size;
+
+    x = (x | (x << 8)) & 0x00FF00FF;
+    x = (x | (x << 4)) & 0x0F0F0F0F;
+    x = (x | (x << 2)) & 0x33333333;
+    x = (x | (x << 1)) & 0x55555555;
+
+    y = (y | (y << 8)) & 0x00FF00FF;
+    y = (y | (y << 4)) & 0x0F0F0F0F;
+    y = (y | (y << 2)) & 0x33333333;
+    y = (y | (y << 1)) & 0x55555555;
+
+    return x | (y << 1);
+}
+
+// find the leftmost node of a polygon ring
+function getLeftmost(data, start) {
+    var node = start,
+        leftmost = start;
+    do {
+        if (data[node.i] < data[leftmost.i]) leftmost = node;
+        node = node.next;
+    } while (node !== start);
+
+    return leftmost;
+}
+
+// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
+function isValidDiagonal(data, a, b) {
+    return a.next.i !== b.i && a.prev.i !== b.i &&
+           !intersectsPolygon(data, a, a.i, b.i) &&
+           locallyInside(data, a, b) && locallyInside(data, b, a) &&
+           middleInside(data, a, a.i, b.i);
+}
+
+// winding order of triangle formed by 3 given points
+function orient(data, p, q, r) {
+    var o = (data[q + 1] - data[p + 1]) * (data[r] - data[q]) - (data[q] - data[p]) * (data[r + 1] - data[q + 1]);
+    return o > 0 ? 1 :
+           o < 0 ? -1 : 0;
+}
+
+// check if two points are equal
+function equals(data, p1, p2) {
+    return data[p1] === data[p2] && data[p1 + 1] === data[p2 + 1];
+}
+
+// check if two segments intersect
+function intersects(data, p1, q1, p2, q2) {
+    return orient(data, p1, q1, p2) !== orient(data, p1, q1, q2) &&
+           orient(data, p2, q2, p1) !== orient(data, p2, q2, q1);
+}
+
+// check if a polygon diagonal intersects any polygon segments
+function intersectsPolygon(data, start, a, b) {
+    var node = start;
+    do {
+        var p1 = node.i,
+            p2 = node.next.i;
+
+        if (p1 !== a && p2 !== a && p1 !== b && p2 !== b && intersects(data, p1, p2, a, b)) return true;
+
+        node = node.next;
+    } while (node !== start);
+
+    return false;
+}
+
+// check if a polygon diagonal is locally inside the polygon
+function locallyInside(data, a, b) {
+    return orient(data, a.prev.i, a.i, a.next.i) === -1 ?
+        orient(data, a.i, b.i, a.next.i) !== -1 && orient(data, a.i, a.prev.i, b.i) !== -1 :
+        orient(data, a.i, b.i, a.prev.i) === -1 || orient(data, a.i, a.next.i, b.i) === -1;
+}
+
+// check if the middle point of a polygon diagonal is inside the polygon
+function middleInside(data, start, a, b) {
+    var node = start,
+        inside = false,
+        px = (data[a] + data[b]) / 2,
+        py = (data[a + 1] + data[b + 1]) / 2;
+    do {
+        var p1 = node.i,
+            p2 = node.next.i;
+
+        if (((data[p1 + 1] > py) !== (data[p2 + 1] > py)) &&
+                (px < (data[p2] - data[p1]) * (py - data[p1 + 1]) / (data[p2 + 1] - data[p1 + 1]) + data[p1]))
+            inside = !inside;
+
+        node = node.next;
+    } while (node !== start);
+
+    return inside;
+}
+
+// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
+// if one belongs to the outer ring and another to a hole, it merges it into a single ring
+function splitPolygon(a, b) {
+    var a2 = new Node(a.i),
+        b2 = new Node(b.i),
+        an = a.next,
+        bp = b.prev;
+
+    a.next = b;
+    b.prev = a;
+
+    a2.next = an;
+    an.prev = a2;
+
+    b2.next = a2;
+    a2.prev = b2;
+
+    bp.next = b2;
+    b2.prev = bp;
+
+    return b2;
+}
+
+// create a node and optionally link it with previous one (in a circular doubly linked list)
+function insertNode(i, last) {
+    var node = new Node(i);
+
+    if (!last) {
+        node.prev = node;
+        node.next = node;
+
+    } else {
+        node.next = last.next;
+        node.prev = last;
+        last.next.prev = node;
+        last.next = node;
+    }
+    return node;
+}
+
+function removeNode(node) {
+    node.next.prev = node.prev;
+    node.prev.next = node.next;
+
+    if (node.prevZ) node.prevZ.nextZ = node.nextZ;
+    if (node.nextZ) node.nextZ.prevZ = node.prevZ;
+}
+
+function Node(i) {
+    // vertex coordinates
+    this.i = i;
+
+    // previous and next vertice nodes in a polygon ring
+    this.prev = null;
+    this.next = null;
+
+    // z-order curve value
+    this.z = null;
+
+    // previous and next nodes in z-order
+    this.prevZ = null;
+    this.nextZ = null;
+
+    // indicates whether this is a steiner point
+    this.steiner = false;
+}

+ 475 - 328
examples/js/loaders/AMFLoader.js

@@ -7,10 +7,10 @@
  * 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);
- *  });
+ *	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
@@ -19,337 +19,484 @@
  *
  */
 
-THREE.AMFLoader = function( manager ) {
-  this.manager = (manager !== undefined) ? manager : THREE.DefaultLoadingManager;
+THREE.AMFLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
 };
 
 THREE.AMFLoader.prototype = {
 
-  constructor: THREE.AMFLoader,
+	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 ) {
+
+			onLoad( scope.parse( text ) );
+
+		}, 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().substr( - 4 ) === '.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 = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
+
+			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.a !== 1.0 ) {
+
+				loadedMaterial.transparent = true;
+				loadedMaterial.opacity = color.a;
+
+			}
+
+			return { 'id': matId, 'material': loadedMaterial };
+
+		}
+
+		function loadColor( node ) {
+
+			var color = { 'r': 1.0, 'g': 1.0, 'b': 1.0, 'a': 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.a = 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 v1 = currVolumeNode.getElementsByTagName("v1")[0].textContent;
+					var v2 = currVolumeNode.getElementsByTagName("v2")[0].textContent;
+					var v3 = currVolumeNode.getElementsByTagName("v3")[0].textContent;
+
+					volume.triangles.push( v1 );
+					volume.triangles.push( v2 );
+					volume.triangles.push( v3 );
+
+				}
+
+				currVolumeNode = currVolumeNode.nextElementSibling;
+
+			}
+
+			return volume;
+
+		}
+
+		function loadMeshVertices( node ) {
+
+			var vertArray = [];
+			var normalArray = [];
+			var currVerticesNode = node.firstElementChild;
+
+			while ( currVerticesNode ) {
+
+				if ( currVerticesNode.nodeName === "vertex" ) {
+
+					var vNode = currVerticesNode.firstElementChild;
+
+					while ( vNode ) {
+
+						if ( vNode.nodeName === "coordinates" ) {
+
+							var x = vNode.getElementsByTagName("x")[0].textContent;
+							var y = vNode.getElementsByTagName("y")[0].textContent;
+							var z = vNode.getElementsByTagName("z")[0].textContent;
+
+							vertArray.push(x);
+							vertArray.push(y);
+							vertArray.push(z);
+
+						} else if ( vNode.nodeName === "normal" ) {
+
+							var nx = vNode.getElementsByTagName("nx")[0].textContent;
+							var ny = vNode.getElementsByTagName("ny")[0].textContent;
+							var nz = vNode.getElementsByTagName("nz")[0].textContent;
+
+							normalArray.push(nx);
+							normalArray.push(ny);
+							normalArray.push(nz);
+
+						}
+
+						vNode = vNode.nextElementSibling;
+
+					}
+
+				}
+				currVerticesNode = currVerticesNode.nextElementSibling;
+
+			}
+
+			return { "vertices": vertArray, "normals": normalArray };
+
+		}
+
+		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": [], "normals": [], "volumes": [], "color": currColor };
+
+					while ( currMeshNode ) {
+
+						if ( currMeshNode.nodeName === "vertices" ) {
+
+							var loadedVertices = loadMeshVertices( currMeshNode );
+
+							mesh.normals = mesh.normals.concat( loadedVertices.normals );
+							mesh.vertices = mesh.vertices.concat( loadedVertices.vertices );
+
+						} 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 objDefaultMaterial = defaultMaterial;
+				var mesh = meshes[ i ];
+				var meshVertices = Float32Array.from( mesh.vertices );
+				var vertices = new THREE.BufferAttribute( Float32Array.from( meshVertices ), 3 );
+				var meshNormals = null;
+				var normals = null;
+
+				if ( mesh.normals.length ) {
+
+					meshNormals = Float32Array.from( mesh.normals );
+					normals = new THREE.BufferAttribute( Float32Array.from( meshNormals ), 3 );
+
+				}
+
+				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 material = objDefaultMaterial;
+
+					newGeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );
+					newGeometry.addAttribute( 'position', vertices.clone() );
+
+					if( normals ) {
+
+						newGeometry.addAttribute( 'normal', normals.clone() );
+
+					}
+
+					if ( amfMaterials[ volume.materialId ] !== undefined ) {
+
+						material = amfMaterials[ volume.materialId ];
+
+					}
+
+					newGeometry.scale( amfScale, amfScale, amfScale );
+					newObject.add( new THREE.Mesh( newGeometry, material.clone() ) );
+
+				}
+
+			}
 
-  load: function(url, onLoad, onProgress, onError) {
-    var scope = this;
+			sceneObject.add( newObject );
 
-    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) {
-    var amfName = "";
-    var amfAuthor = "";
-    var amfScale = 1.0;
-    var amfMaterials = {};
-    var amfObjects = {};
-
-    var xmldata = this.loaddocument(data);
-
-    amfScale = this.loaddocumentscale(xmldata);
-
-    var documentchildren = xmldata.documentElement.children;
-
-    for(var i = 0; i < documentchildren.length; i++) {
-      if(documentchildren[i].nodeName === 'metadata') {
-        if(documentchildren[i].attributes['type'] !== undefined) {
-          if(documentchildren[i].attributes['type'].value === 'name') {
-            amfName = documentchildren[i].textContent;
-          } else if(documentchildren[i].attributes['type'].value === 'author') {
-            amfAuthor = documentchildren[i].textContent;
-          }
-        }
-      } else if(documentchildren[i].nodeName === 'material') {
-        var loadedmaterial = this.loadmaterials(documentchildren[i]);
-        amfMaterials[loadedmaterial.id] = loadedmaterial.material;
-      } else if(documentchildren[i].nodeName === 'object') {
-        var loadedobject = this.loadobject(documentchildren[i]);
-        amfObjects[loadedobject.id] = loadedobject.obj;
-      }
-    }
-
-    var sceneobject = new THREE.Object3D();
-
-    sceneobject.name = amfName;
-    sceneobject.userData.author = amfAuthor;
-    sceneobject.userData.loader = "AMF";
+		return sceneObject;
 
-    var defaultmaterial = new THREE.MeshPhongMaterial({shading: THREE.FlatShading, color: 0xaaaaff});
+	}
 
-    for(var objid in amfObjects) {
-      var newobject = new THREE.Object3D();
-
-      for(var meshi = 0; meshi < amfObjects[objid].meshes.length; meshi++) {
-        var meshvertices = Float32Array.from(amfObjects[objid].meshes[meshi].vertices);
-        var vertices = new THREE.BufferAttribute(Float32Array.from(meshvertices), 3);
-        var objdefaultmaterial = defaultmaterial;
-
-        if(amfObjects[objid].meshes[meshi].color) {
-          var color = amfObjects[objid].meshes[meshi].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;
-          }
-        }
-
-        for(var voli = 0; voli < amfObjects[objid].meshes[meshi].volumes.length; voli++) {
-          var currvolume = amfObjects[objid].meshes[meshi].volumes[voli];
-          var newgeometry = new THREE.BufferGeometry();
-          var indexes = Uint32Array.from(currvolume.triangles);
-          var normals = new Uint32Array(vertices.length);
-
-          var material = objdefaultmaterial;
-
-          newgeometry.addAttribute('position', vertices.clone());
-          newgeometry.addAttribute('index', new THREE.BufferAttribute(indexes, 1));
-
-          if(amfMaterials[currvolume.materialid] !== undefined) {
-            material = amfMaterials[currvolume.materialid];
-          }
-
-          newgeometry.scale(amfScale, amfScale, amfScale);
-
-          var newmesh = new THREE.Mesh(newgeometry, material.clone());
-
-          newobject.add(newmesh);
-        }
-      }
-      sceneobject.add(newobject);
-    }
-
-    return sceneobject;
-  },
-
-  loaddocument: function ( data ) {
-    var view = new DataView(data);
-
-    var magic = String.fromCharCode(view.getUint8(0), view.getUint8(1));
-
-    if(magic === "PK") {
-      console.log("Loading Zip");
-      var zip = null;
-      var file = null;
-
-      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;
-  },
-
-  loaddocumentscale: function ( xmldata ) {
-    var scale = 1.0;
-
-    var unit = xmldata.documentElement.attributes['unit'].value.toLowerCase();
-
-    var scale_units = {
-      'millimeter': 1.0,
-      'inch': 25.4,
-      'feet': 304.8,
-      'meter': 1000.0,
-      'micron': 0.001
-    };
-
-    if(scale_units[unit] !== undefined) {
-      scale = scale_units[unit];
-    }
-
-    console.log("  Unit scale: " + scale);
-    return scale;
-  },
-
-  loadmaterials: function ( node ) {
-    var mat = node;
-
-    var loadedmaterial = null;
-    var matname = "AMF Material";
-    var matid = mat.attributes['id'].textContent;
-    var color;
-
-    for(var i = 0; i < mat.children.length; i++) {
-      var matchildel = mat.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 = this.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 };
-  },
-
-  loadcolor: function ( 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;
-  },
-
-  loadmeshvolume: function( 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;
-  },
-
-  loadmeshvertices: function( node ) {
-    var vert_array = [];
-
-    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") {
-                vert_array.push(coordnode.textContent);
-              }
-
-              coordnode = coordnode.nextElementSibling;
-            }
-          }
-          vnode = vnode.nextElementSibling;
-        }
-      }
-      currverticesnode = currverticesnode.nextElementSibling;
-    }
-
-    return vert_array;
-  },
-
-  loadobject: function ( node ) {
-    "use strict";
-    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 = this.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(this.loadmeshvertices(currmeshnode));
-          } else if(currmeshnode.nodeName === "volume") {
-            mesh.volumes.push(this.loadmeshvolume(currmeshnode));
-          }
-          currmeshnode = currmeshnode.nextElementSibling;
-        }
-
-        loadedobject.meshes.push(mesh);
-      }
-      currobjnode = currobjnode.nextElementSibling;
-    }
-
-    return { 'id': objid, 'obj': loadedobject };
-  }
 };

+ 3 - 5
examples/js/loaders/ColladaLoader.js

@@ -100,9 +100,7 @@
 					parts.pop();
 					baseUrl = ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
 
-					var xmlParser = new DOMParser();
-					var responseXML = xmlParser.parseFromString( text, "application/xml" );
-					onLoad( scope.parse( responseXML, url ) );
+					onLoad( scope.parse( text, url ) );
 
 				}, onProgress, onError );
 
@@ -120,9 +118,9 @@
 
 		},
 
-		parse: function( doc ) {
+		parse: function( text ) {
 
-			COLLADA = doc;
+			COLLADA = new DOMParser().parseFromString( text, 'application/xml' );
 
 			this.parseAsset();
 			this.setUpConversion();

+ 865 - 0
examples/js/loaders/ColladaLoader2.js

@@ -0,0 +1,865 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.ColladaLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
+
+THREE.ColladaLoader.prototype = {
+
+	constructor: THREE.ColladaLoader,
+
+	load: function ( url, onLoad, onProgress, onError ) {
+
+		function getBaseUrl( url ) {
+
+			var parts = url.split( '/' );
+			parts.pop();
+			return ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
+
+		}
+
+		var scope = this;
+
+		var loader = new THREE.XHRLoader( scope.manager );
+		loader.setCrossOrigin( scope.crossOrigin );
+		loader.load( url, function ( text ) {
+
+			onLoad( scope.parse( text, getBaseUrl( url ) ) );
+
+		}, onProgress, onError );
+
+	},
+
+	options: {
+
+		set convertUpAxis ( value ) {
+			console.log( 'ColladaLoder.options.convertUpAxis: TODO' );
+		}
+
+	},
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	},
+
+	parse: function ( text, baseUrl ) {
+
+		function parseFloats( text ) {
+
+			var parts = text.trim().split( /\s+/ );
+			var array = new Array( parts.length );
+
+			for ( var i = 0, l = parts.length; i < l; i ++ ) {
+				array[ i ] = parseFloat( parts[ i ] );
+			}
+
+			return array;
+
+		}
+
+		function parseInts( text ) {
+
+			var parts = text.trim().split( /\s+/ );
+			var array = new Array( parts.length );
+
+			for ( var i = 0, l = parts.length; i < l; i ++ ) {
+				array[ i ] = parseInt( parts[ i ] );
+			}
+
+			return array;
+
+		}
+
+		function parseId( text ) {
+
+			return text.substring( 1 );
+
+		}
+
+		// asset
+
+		function parseAsset( xml ) {
+
+			return {
+				upAxis: parseAssetUpAxis( xml.getElementsByTagName( 'up_axis' )[ 0 ] )
+			};
+
+		}
+
+		function parseAssetUpAxis( xml ) {
+
+			return xml !== undefined ? xml.textContent : 'Y_UP';
+
+		}
+
+		// library
+
+		function parseLibrary( data, libraryName, nodeName, parser ) {
+
+			var library = xml.getElementsByTagName( libraryName )[ 0 ];
+
+			if ( library !== undefined ) {
+
+				var elements = library.getElementsByTagName( nodeName );
+
+				for ( var i = 0; i < elements.length; i ++ ) {
+
+					parser( elements[ i ] );
+
+				}
+
+			}
+
+		}
+
+		function buildLibrary( data, builder ) {
+
+			for ( var name in data ) {
+
+				var object = data[ name ];
+				object.build = builder( data[ name ] );
+
+			}
+
+		}
+
+		// get
+
+		function getBuild( data, builder ) {
+
+			if ( data.build !== undefined ) return data.build;
+
+			data.build = builder( data );
+
+			return data.build;
+
+		}
+
+		// image
+
+		var imageLoader = new THREE.ImageLoader();
+
+		function parseImage( xml ) {
+
+			var data = {
+				url: xml.getElementsByTagName( 'init_from' )[ 0 ].textContent
+			};
+
+			library.images[ xml.getAttribute( 'id' ) ] = data;
+
+		}
+
+		function buildImage( data ) {
+
+			if ( data.build !== undefined ) return data.build;
+
+			var url = data.url;
+
+			if ( baseUrl !== undefined ) url = baseUrl + url;
+
+			return imageLoader.load( url );
+
+		}
+
+		function getImage( id ) {
+
+			return getBuild( library.images[ id ], buildImage );
+
+		}
+
+		// effect
+
+		function parseEffect( xml ) {
+
+		}
+
+		function buildEffect( data ) {
+
+		}
+
+		function getEffect( id ) {
+
+			return getBuild( library.effects[ id ], buildEffect );
+
+		}
+
+		// camera
+
+		function parseCamera( xml ) {
+
+			var data = {
+				name: xml.getAttribute( 'name' )
+			};
+
+			library.cameras[ xml.getAttribute( 'id' ) ] = {};
+
+		}
+
+		function buildCamera( data ) {
+
+			var camera = new THREE.PerspectiveCamera();
+			camera.name = data.name;
+
+			return camera;
+
+		}
+
+		function getCamera( id ) {
+
+			return getBuild( library.cameras[ id ], buildCamera );
+
+		}
+
+		// light
+
+		function parseLight( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'technique_common':
+						data = parseLightTechnique( child );
+						break;
+
+				}
+
+			}
+
+			library.lights[ xml.getAttribute( 'id' ) ] = data;
+
+		}
+
+		function parseLightTechnique( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'directional':
+					case 'point':
+					case 'spot':
+					case 'ambient':
+
+						data.technique = child.nodeName;
+						data.parameters = parseLightParameters( child );
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function parseLightParameters( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'color':
+						var array = parseFloats( child.textContent );
+						data.color = new THREE.Color().fromArray( array );
+						break;
+
+					case 'falloff_angle':
+						data.falloffAngle = parseFloat( child.textContent );
+						break;
+
+					case 'quadratic_attenuation':
+						var f = parseFloat( child.textContent );
+						data.distance = f ? Math.sqrt( 1 / f ) : 0;
+						break;
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function buildLight( data ) {
+
+			var light;
+
+			switch ( data.technique ) {
+
+				case 'directional':
+					light = new THREE.DirectionalLight();
+					break;
+
+				case 'point':
+					light = new THREE.PointLight();
+					break;
+
+				case 'spot':
+					light = new THREE.SpotLight();
+					break;
+
+				case 'ambient':
+					light = new THREE.AmbientLight();
+					break;
+
+			}
+
+			if ( data.parameters.color ) light.color.copy( data.parameters.color );
+			if ( data.parameters.distance ) light.distance = data.parameters.distance;
+
+			return light;
+
+		}
+
+		function getLight( id ) {
+
+			return getBuild( library.lights[ id ], buildLight );
+
+		}
+
+		// geometry
+
+		function parseGeometry( xml ) {
+
+			var data = {
+				name: xml.getAttribute( 'name' ),
+				sources: {},
+				primitives: []
+			};
+
+			var mesh = xml.getElementsByTagName( 'mesh' )[ 0 ];
+
+			for ( var i = 0; i < mesh.childNodes.length; i ++ ) {
+
+				var child = mesh.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'source':
+						data.sources[ child.getAttribute( 'id' ) ] = parseFloats( child.getElementsByTagName( 'float_array' )[ 0 ].textContent );
+						break;
+
+					case 'vertices':
+						data.sources[ child.getAttribute( 'id' ) ] = data.sources[ parseId( child.getElementsByTagName( 'input' )[ 0 ].getAttribute( 'source' ) ) ];
+						break;
+
+					case 'polygons':
+						console.log( 'ColladaLoader: Unsupported primitive type: ', child.nodeName );
+						break;
+
+					case 'lines':
+					case 'linestrips':
+					case 'polylist':
+					case 'triangles':
+						data.primitives.push( parseGeometryPrimitive( child ) );
+						break;
+
+					default:
+						console.log( child );
+
+				}
+
+			}
+
+			library.geometries[ xml.getAttribute( 'id' ) ] = data;
+
+		}
+
+		function parseGeometryPrimitive( xml ) {
+
+			var primitive = {
+				type: xml.nodeName,
+				inputs: {},
+				stride: 0
+			};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'input':
+						var id = parseId( child.getAttribute( 'source' ) );
+						var semantic = child.getAttribute( 'semantic' );
+						var offset = parseInt( child.getAttribute( 'offset' ) );
+						primitive.inputs[ semantic ] = { id: id, offset: offset };
+						primitive.stride = Math.max( primitive.stride, offset + 1 );
+						break;
+
+					case 'vcount':
+						primitive.vcount = parseInts( child.textContent );
+						break;
+
+					case 'p':
+						primitive.p = parseInts( child.textContent );
+						break;
+
+				}
+
+			}
+
+			return primitive;
+
+		}
+
+		function buildGeometry( data ) {
+
+			var group = new THREE.Group();
+
+			var sources = data.sources;
+			var primitives = data.primitives;
+
+			if ( primitives.length === 0 ) return group;
+
+			for ( var p = 0; p < primitives.length; p ++ ) {
+
+				var primitive = primitives[ p ];
+
+				var inputs = primitive.inputs;
+				var stride = primitive.stride;
+				var vcount = primitive.vcount;
+
+				var indices = primitive.p;
+				var vcount = primitive.vcount;
+
+				var maxcount = 0;
+
+				var geometry = new THREE.BufferGeometry();
+				if ( data.name ) geometry.name = data.name;
+
+				for ( var name in inputs ) {
+
+					var input = inputs[ name ];
+
+					var source = sources[ input.id ];
+					var offset = input.offset;
+
+					var array = [];
+
+					function pushVector( i ) {
+
+						var index = indices[ i + offset ] * 3;
+
+						if ( asset.upAxis === 'Z_UP' ) {
+							array.push( source[ index + 0 ], source[ index + 2 ], - source[ index + 1 ] );
+						} else {
+							array.push( source[ index + 0 ], source[ index + 1 ], source[ index + 2 ] );
+						}
+
+					}
+
+					if ( primitive.vcount !== undefined ) {
+
+						var index = 0;
+
+						for ( var i = 0, l = vcount.length; i < l; i ++ ) {
+
+							var count = vcount[ i ];
+
+							if ( count === 4 ) {
+
+								var a = index + stride * 0;
+								var b = index + stride * 1;
+								var c = index + stride * 2;
+								var d = index + stride * 3;
+
+								pushVector( a ); pushVector( b ); pushVector( d );
+								pushVector( b ); pushVector( c ); pushVector( d );
+
+							} else if ( count === 3 ) {
+
+								var a = index + stride * 0;
+								var b = index + stride * 1;
+								var c = index + stride * 2;
+
+								pushVector( a ); pushVector( b ); pushVector( c );
+
+							} else {
+
+								maxcount = Math.max( maxcount, count );
+
+							}
+
+							index += stride * count;
+
+						}
+
+					} else {
+
+						for ( var i = 0, l = indices.length; i < l; i += stride ) {
+
+							pushVector( i );
+
+						}
+
+					}
+
+					switch ( name )	{
+
+						case 'VERTEX':
+							geometry.addAttribute( 'position', new THREE.Float32Attribute( array, 3 ) );
+							break;
+
+						case 'NORMAL':
+							geometry.addAttribute( 'normal', new THREE.Float32Attribute( array, 3 ) );
+							break;
+
+					}
+
+				}
+
+				if ( maxcount > 0 ) {
+
+					console.log( 'ColladaLoader: Geometry', data.id, 'has faces with more than 4 vertices.' );
+
+				}
+
+				switch ( primitive.type ) {
+
+					case 'lines':
+						group.add( new THREE.LineSegments( geometry ) );
+						break;
+
+					case 'linestrips':
+						group.add( new THREE.Line( geometry ) );
+						break;
+
+					case 'triangles':
+					case 'polylist':
+						group.add( new THREE.Mesh( geometry ) );
+						break;
+
+				}
+
+			}
+
+			// flatten
+
+			if ( group.children.length === 1 ) {
+
+				return group.children[ 0 ];
+
+			}
+
+			return group;
+
+		}
+
+		function getGeometry( id ) {
+
+			return getBuild( library.geometries[ id ], buildGeometry );
+
+		}
+
+		// nodes
+
+		var matrix = new THREE.Matrix4();
+		var vector = new THREE.Vector3();
+
+		function parseNode( xml ) {
+
+			var data = {
+				name: xml.getAttribute( 'name' ),
+				matrix: new THREE.Matrix4(),
+				nodes: [],
+				instanceCameras: [],
+				instanceLights: [],
+				instanceGeometries: [],
+				instanceNodes: []
+			};
+
+			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'node':
+						parseNode( child );
+						data.nodes.push( child.getAttribute( 'id' ) );
+						break;
+
+					case 'instance_camera':
+						data.instanceCameras.push( parseId( child.getAttribute( 'url' ) ) );
+						break;
+
+					case 'instance_light':
+						data.instanceLights.push( parseId( child.getAttribute( 'url' ) ) );
+						break;
+
+					case 'instance_geometry':
+						data.instanceGeometries.push( parseId( child.getAttribute( 'url' ) ) );
+						break;
+
+					case 'instance_node':
+						data.instanceNodes.push( parseId( child.getAttribute( 'url' ) ) );
+						break;
+
+					case 'matrix':
+						var array = parseFloats( child.textContent );
+						data.matrix.multiply( matrix.fromArray( array ).transpose() ); // .transpose() when Z_UP?
+						break;
+
+					case 'translate':
+						var array = parseFloats( child.textContent );
+						vector.fromArray( array );
+						data.matrix.multiply( matrix.makeTranslation( vector.x, vector.y, vector.z ) );
+						break;
+
+					case 'rotate':
+						var array = parseFloats( child.textContent );
+						var angle = THREE.Math.degToRad( array[ 3 ] );
+						data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) );
+						break;
+
+					case 'scale':
+						var array = parseFloats( child.textContent );
+						data.matrix.scale( vector.fromArray( array ) );
+						break;
+
+					case 'extra':
+						break;
+
+					default:
+						console.log( child );
+						break;
+
+				}
+
+			}
+
+			if ( xml.getAttribute( 'id' ) !== null ) {
+
+				library.nodes[ xml.getAttribute( 'id' ) ] = data;
+
+			}
+
+			return data;
+
+		}
+
+		function buildNode( data ) {
+
+			var objects = [];
+
+			var matrix = data.matrix;
+			var nodes = data.nodes;
+			var instanceCameras = data.instanceCameras;
+			var instanceLights = data.instanceLights;
+			var instanceGeometries = data.instanceGeometries;
+			var instanceNodes = data.instanceNodes;
+
+			for ( var i = 0, l = nodes.length; i < l; i ++ ) {
+
+				objects.push( getNode( nodes[ i ] ).clone() );
+
+			}
+
+			for ( var i = 0, l = instanceCameras.length; i < l; i ++ ) {
+
+				objects.push( getCamera( instanceCameras[ i ] ).clone() );
+
+			}
+
+			for ( var i = 0, l = instanceLights.length; i < l; i ++ ) {
+
+				objects.push( getLight( instanceLights[ i ] ).clone() );
+
+			}
+
+			for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) {
+
+				objects.push( getGeometry( instanceGeometries[ i ] ).clone() );
+
+			}
+
+			for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) {
+
+				objects.push( getNode( instanceNodes[ i ] ).clone() );
+
+			}
+
+			var object;
+
+			if ( objects.length === 1 ) {
+
+				object = objects[ 0 ];
+
+			} else {
+
+				object = new THREE.Group();
+
+				for ( var i = 0; i < objects.length; i ++ ) {
+
+					object.add( objects[ i ] );
+
+				}
+
+			}
+
+			object.name = data.name;
+			matrix.decompose( object.position, object.quaternion, object.scale );
+
+			return object;
+
+		}
+
+		function getNode( id ) {
+
+			return getBuild( library.nodes[ id ], buildNode );
+
+		}
+
+		// visual scenes
+
+		function parseVisualScene( xml ) {
+
+			var data = {
+				name: xml.getAttribute( 'name' ),
+				children: []
+			};
+
+			var elements = xml.getElementsByTagName( 'node' );
+
+			for ( var i = 0; i < elements.length; i ++ ) {
+
+				data.children.push( parseNode( elements[ i ] ) );
+
+			}
+
+			library.visualScenes[ xml.getAttribute( 'id' ) ] = data;
+
+		}
+
+		function buildVisualScene( data ) {
+
+			var group = new THREE.Group();
+			group.name = data.name;
+
+			var children = data.children;
+
+			for ( var i = 0; i < children.length; i ++ ) {
+
+				group.add( buildNode( children[ i ] ) );
+
+			}
+
+			return group;
+
+		}
+
+		function getVisualScene( id ) {
+
+			return getBuild( library.visualScenes[ id ], buildVisualScene );
+
+		}
+
+		// scenes
+
+		function parseScene( xml ) {
+
+			var scene = xml.getElementsByTagName( 'scene' )[ 0 ];
+			var instance = scene.getElementsByTagName( 'instance_visual_scene' )[ 0 ];
+			return getVisualScene( parseId( instance.getAttribute( 'url' ) ) );
+
+		}
+
+		console.time( 'ColladaLoader' );
+
+		console.time( 'ColladaLoader: DOMParser' );
+
+		var xml = new DOMParser().parseFromString( text, 'application/xml' );
+
+		console.timeEnd( 'ColladaLoader: DOMParser' );
+
+		// metadata
+
+		var version = xml.getElementsByTagName( 'COLLADA' )[ 0 ].getAttribute( 'version' );
+		console.log( 'ColladaLoader: File version', version );
+
+		var asset = parseAsset( xml.getElementsByTagName( 'asset' )[ 0 ] );
+
+		//
+
+		var library = {
+			images: {},
+			// effects: {},
+			cameras: {},
+			lights: {},
+			geometries: {},
+			nodes: {},
+			visualScenes: {}
+		};
+
+		console.time( 'ColladaLoader: Parse' );
+
+		parseLibrary( library.images, 'library_images', 'image', parseImage );
+		// parseLibrary( library.effects, 'library_effects', 'effect', parseEffect );
+		parseLibrary( library.cameras, 'library_cameras', 'camera', parseCamera );
+		parseLibrary( library.lights, 'library_lights', 'light', parseLight );
+		parseLibrary( library.geometries, 'library_geometries', 'geometry', parseGeometry );
+		parseLibrary( library.nodes, 'library_nodes', 'node', parseNode );
+		parseLibrary( library.visualScenes, 'library_visual_scenes', 'visual_scene', parseVisualScene );
+
+		console.timeEnd( 'ColladaLoader: Parse' );
+
+		console.time( 'ColladaLoader: Build' );
+
+		// buildLibrary( library.images, buildImage );
+		// buildLibrary( library.effects, buildEffect );
+		buildLibrary( library.cameras, buildCamera );
+		buildLibrary( library.lights, buildLight );
+		buildLibrary( library.geometries, buildGeometry );
+		buildLibrary( library.nodes, buildNode );
+		buildLibrary( library.visualScenes, buildVisualScene );
+
+		console.timeEnd( 'ColladaLoader: Build' );
+
+		// console.log( library );
+
+		var scene = parseScene( xml );
+
+		console.timeEnd( 'ColladaLoader' );
+
+		// console.log( scene );
+
+		return {
+			animations: [],
+			kinematics: { joints: [] },
+			scene: scene
+		};
+
+	}
+
+};

+ 54 - 0
examples/js/loaders/KMZLoader.js

@@ -0,0 +1,54 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.KMZLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
+
+THREE.KMZLoader.prototype = {
+
+	constructor: THREE.KMZLoader,
+
+	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 ) {
+
+			onLoad( scope.parse( text ) );
+
+		}, onProgress, onError );
+
+	},
+
+	parse: function ( data ) {
+
+		var zip = new JSZip( data );
+
+		// console.log( zip );
+
+		for ( var name in zip.files ) {
+
+			if ( name.toLowerCase().substr( - 4 ) === '.dae' ) {
+
+				return new THREE.ColladaLoader().parse( zip.file( name ).asText() );
+
+			}
+
+		}
+
+		console.error( 'KZMLoader: Couldn\'t find .dae file.' );
+
+		return {
+			scene: new THREE.Group()
+		}
+
+	}
+
+};

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

@@ -351,7 +351,7 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 					// The specular exponent (defines the focus of the specular highlight)
 					// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
 
-					params[ 'shininess' ] = value;
+					params[ 'shininess' ] = parseFloat( value );
 
 					break;
 

+ 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 );
 

+ 146 - 32
examples/js/loaders/VRMLLoader.js

@@ -44,10 +44,14 @@ THREE.VRMLLoader.prototype = {
 
 		this.crossOrigin = value;
 
+		THREE.ImageUtils.crossOrigin = value;
+
 	},
 
 	parse: function ( data ) {
 
+		var texturePath = this.texturePath || '';
+
 		var parseV1 = function ( lines, scene ) {
 
 			console.warn( 'VRML V1.0 not supported yet' );
@@ -58,6 +62,7 @@ THREE.VRMLLoader.prototype = {
 
 			var defines = {};
 			var float_pattern = /(\b|\-|\+)([\d\.e]+)/;
+			var float2_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
 			var float3_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
 
 			/**
@@ -239,10 +244,10 @@ THREE.VRMLLoader.prototype = {
 						this.points = [];
 						break;
 					case 'coordIndex':
+					case 'texCoordIndex':
 						this.recordingFieldname = fieldName;
 						this.isRecordingFaces = true;
 						this.indexes = [];
-						break;
 				}
 
 				if ( this.isRecordingFaces ) {
@@ -287,12 +292,14 @@ THREE.VRMLLoader.prototype = {
 					if ( /]/.exec( line ) ) {
 
 						this.isRecordingFaces = false;
-						node.coordIndex = this.indexes;
+						node[this.recordingFieldname] = this.indexes;
 
 					}
 
 				} else if ( this.isRecordingPoints ) {
 
+					if ( node.nodeType == 'Coordinate' )
+
 					while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
 
 						point = {
@@ -305,6 +312,19 @@ THREE.VRMLLoader.prototype = {
 
 					}
 
+					if ( node.nodeType == 'TextureCoordinate' )
+
+					while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
+
+						point = {
+							x: parseFloat( parts[ 1 ] ),
+							y: parseFloat( parts[ 2 ] )
+						};
+
+						this.points.push( point );
+
+					}
+
 					// end
 					if ( /]/.exec( line ) ) {
 
@@ -505,7 +525,7 @@ THREE.VRMLLoader.prototype = {
 
 					}
 
-					if ( matches = /([^\s]*){1}\s?{/.exec( line ) ) {
+					if ( matches = /([^\s]*){1}(?:\s+)?{/.exec( line ) ) {
 
 						// first subpattern should match the Node name
 
@@ -637,7 +657,7 @@ THREE.VRMLLoader.prototype = {
 
 					if ( /DEF/.exec( data.string ) ) {
 
-						object.name = /DEF (\w+)/.exec( data.string )[ 1 ];
+						object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
 
 						defines[ object.name ] = object;
 
@@ -710,7 +730,7 @@ THREE.VRMLLoader.prototype = {
 
 						var geometry = new THREE.Geometry();
 
-						var indexes;
+						var indexes, uvIndexes, uvs;
 
 						for ( var i = 0, j = data.children.length; i < j; i ++ ) {
 
@@ -718,53 +738,102 @@ THREE.VRMLLoader.prototype = {
 
 							var vec;
 
+							if ( 'TextureCoordinate' === child.nodeType ) {
+
+								uvs = child.points;
+
+							}
+
+
 							if ( 'Coordinate' === child.nodeType ) {
 
-								for ( var k = 0, l = child.points.length; k < l; k ++ ) {
+								if ( child.points ) {
+
+									for ( var k = 0, l = child.points.length; k < l; k ++ ) {
 
-									var point = child.points[ k ];
+										var point = child.points[ k ];
 
-									vec = new THREE.Vector3( point.x, point.y, point.z );
+										vec = new THREE.Vector3( point.x, point.y, point.z );
 
-									geometry.vertices.push( vec );
+										geometry.vertices.push( vec );
+
+									}
 
 								}
 
-								break;
+								if ( child.string.indexOf ( 'DEF' ) > -1 ) {
 
-							}
+									var name = /DEF\s+(\w+)/.exec( child.string )[ 1 ];
 
-						}
+									defines[ name ] = geometry.vertices;
 
-						var skip = 0;
+								}
+
+								if ( child.string.indexOf ( 'USE' ) > -1 ) {
 
-						// read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
-						for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
+									var defineKey = /USE\s+(\w+)/.exec( child.string )[ 1 ];
 
-							indexes = data.coordIndex[ i ];
+									geometry.vertices = defines[ defineKey ];
+								}
 
-							// vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
-							skip = 0;
+							}
 
-							// todo: this is the time to check if the faces are ordered ccw or not (cw)
+						}
 
-							// Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
-							while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
+						var skip = 0;
 
-								var face = new THREE.Face3(
-									indexes[ 0 ],
-									indexes[ skip + 1 ],
-									indexes[ skip + 2 ],
-									null // normal, will be added later
-									// todo: pass in the color, if a color index is present
-								);
+						// some shapes only have vertices for use in other shapes
+						if ( data.coordIndex ) {
+
+							// read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
+							for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
+
+								indexes = data.coordIndex[ i ]; if ( data.texCoordIndex ) uvIndexes = data.texCoordIndex[ i ];
+
+								// vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
+								skip = 0;
+
+								// Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
+								while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
+
+									var face = new THREE.Face3(
+										indexes[ 0 ],
+										indexes[ skip + (data.ccw ? 1 : 2) ],
+										indexes[ skip + (data.ccw ? 2 : 1) ],
+										null // normal, will be added later
+										// todo: pass in the color, if a color index is present
+									);
+
+									if ( uvs && uvIndexes ) {
+										geometry.faceVertexUvs [0].push( [
+											new THREE.Vector2 (
+												uvs[ uvIndexes[ 0 ] ].x ,
+												uvs[ uvIndexes[ 0 ] ].y
+											) ,
+											new THREE.Vector2 (
+												uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].x ,
+												uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].y
+											) ,
+											new THREE.Vector2 (
+												uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].x ,
+												uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].y
+											)
+										] );
+									}
+
+									skip ++;
+
+									geometry.faces.push( face );
 
-								skip ++;
+								}
 
-								geometry.faces.push( face );
 
 							}
 
+						} else {
+
+							// do not add dummy mesh to the scene
+							parent.parent.remove( parent );
 
 						}
 
@@ -850,8 +919,19 @@ THREE.VRMLLoader.prototype = {
 
 							parent.material = material;
 
-							// material found, stop looping
-							break;
+						}
+
+						if ( 'ImageTexture' === child.nodeType ) {
+
+							var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);
+
+							if (textureName) {
+
+								parent.material.name = textureName[ 1 ];
+
+								parent.material.map = THREE.ImageUtils.loadTexture (texturePath + textureName[ 1 ]);
+
+							}
 
 						}
 
@@ -879,6 +959,40 @@ THREE.VRMLLoader.prototype = {
 
 		var lines = data.split( '\n' );
 
+		// some lines do not have breaks
+		for (var i = lines.length -1; i > -1; i--) {
+
+			// split lines with {..{ or {..[ - some have both
+			if (/{.*[{\[]/.test (lines[i])) {
+				var parts = lines[i].split ('{').join ('{\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			} else
+
+			// split lines with ]..}
+			if (/\].*}/.test (lines[i])) {
+				var parts = lines[i].split (']').join (']\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			}
+
+			// split lines with }..}
+			if (/}.*}/.test (lines[i])) {
+				var parts = lines[i].split ('}').join ('}\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			}
+
+			// force the parser to create Coordinate node for empty coords
+			// coord USE something -> coord USE something Coordinate {}
+			if((lines[i].indexOf ('coord') > -1) && (lines[i].indexOf ('[') < 0) && (lines[i].indexOf ('{') < 0)) {
+				lines[i] += ' Coordinate {}';
+			}
+		}
+
 		var header = lines.shift();
 
 		if ( /V1.0/.exec( header ) ) {

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 716 - 258
examples/js/loaders/sea3d/SEA3D.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 244 - 152
examples/js/loaders/sea3d/SEA3DLoader.js


+ 0 - 5
examples/js/postprocessing/GlitchPass.js

@@ -21,8 +21,6 @@ THREE.GlitchPass = function ( dt_size ) {
 		fragmentShader: shader.fragmentShader
 	} );
 
-	console.log( this.material );
-	
 	this.enabled = true;
 	this.renderToScreen = false;
 	this.needsSwap = true;
@@ -95,7 +93,6 @@ THREE.GlitchPass.prototype = {
 	generateHeightmap: function( dt_size ) {
 
 		var data_arr = new Float32Array( dt_size * dt_size * 3 );
-		console.log( dt_size );
 		var length = dt_size * dt_size;
 		
 		for ( var i = 0; i < length; i ++ ) {
@@ -108,8 +105,6 @@ THREE.GlitchPass.prototype = {
 		}
 		
 		var texture = new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType );
-		console.log( texture );
-		console.log( dt_size );
 		texture.needsUpdate = true;
 		return texture;
 

+ 1 - 1
examples/js/renderers/CSS3DRenderer.js

@@ -98,7 +98,7 @@ THREE.CSS3DRenderer = function () {
 
 	var epsilon = function ( value ) {
 
-		return Math.abs( value ) < 0.000001 ? 0 : value;
+		return Math.abs( value ) < Number.EPSILON ? 0 : value;
 
 	};
 

+ 1 - 1
examples/js/renderers/CSS3DStereoRenderer.js

@@ -145,7 +145,7 @@ THREE.CSS3DStereoRenderer = function () {
 
 	var epsilon = function ( value ) {
 
-		return Math.abs( value ) < 0.000001 ? 0 : value;
+		return Math.abs( value ) < Number.EPSILON ? 0 : value;
 
 	};
 

+ 14 - 15
examples/js/renderers/CanvasRenderer.js

@@ -36,8 +36,6 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 	console.log( 'THREE.CanvasRenderer', THREE.REVISION );
 
-	var smoothstep = THREE.Math.smoothstep;
-
 	parameters = parameters || {};
 
 	var _this = this,
@@ -365,7 +363,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 					_v2.positionScreen
 				] );
 
-				if ( _clipBox.isIntersectionBox( _elemBox ) === true ) {
+				if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
 					renderLine( _v1, _v2, element, material );
 
@@ -397,7 +395,7 @@ THREE.CanvasRenderer = function ( parameters ) {
 					_v3.positionScreen
 				] );
 
-				if ( _clipBox.isIntersectionBox( _elemBox ) === true ) {
+				if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
 					renderFace3( _v1, _v2, _v3, 0, 1, 2, element, material );
 
@@ -760,14 +758,6 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 			}
 
-		} else if ( material instanceof THREE.MeshDepthMaterial ) {
-
-			_color.r = _color.g = _color.b = 1 - smoothstep( v1.positionScreen.z * v1.positionScreen.w, _camera.near, _camera.far );
-
-			material.wireframe === true
-					 ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
-					 : fillPath( _color );
-
 		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
 			_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix );
@@ -829,14 +819,23 @@ THREE.CanvasRenderer = function ( parameters ) {
 			texture instanceof THREE.DataTexture ) {
 
 			return {
-					canvas: undefined,
-					version: texture.version
-				}
+				canvas: undefined,
+				version: texture.version
+			}
 
 		}
 
 		var image = texture.image;
 
+		if ( image.complete === false ) {
+
+			return {
+				canvas: undefined,
+				version: 0
+			}
+
+		}
+
 		var canvas = document.createElement( 'canvas' );
 		canvas.width = image.width;
 		canvas.height = image.height;

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

@@ -161,7 +161,7 @@ THREE.Projector = function () {
 
 		var normalMatrix = new THREE.Matrix3();
 
-		var setObject = function ( value ) {
+		function setObject( value ) {
 
 			object = value;
 			material = object.material;
@@ -171,9 +171,9 @@ THREE.Projector = function () {
 			normals.length = 0;
 			uvs.length = 0;
 
-		};
+		}
 
-		var projectVertex = function ( vertex ) {
+		function projectVertex( vertex ) {
 
 			var position = vertex.position;
 			var positionWorld = vertex.positionWorld;
@@ -192,30 +192,30 @@ THREE.Projector = function () {
 					 positionScreen.y >= - 1 && positionScreen.y <= 1 &&
 					 positionScreen.z >= - 1 && positionScreen.z <= 1;
 
-		};
+		}
 
-		var pushVertex = function ( x, y, z ) {
+		function pushVertex( x, y, z ) {
 
 			_vertex = getNextVertexInPool();
 			_vertex.position.set( x, y, z );
 
 			projectVertex( _vertex );
 
-		};
+		}
 
-		var pushNormal = function ( x, y, z ) {
+		function pushNormal( x, y, z ) {
 
 			normals.push( x, y, z );
 
-		};
+		}
 
-		var pushUv = function ( x, y ) {
+		function pushUv( x, y ) {
 
 			uvs.push( x, y );
 
-		};
+		}
 
-		var checkTriangleVisibility = function ( v1, v2, v3 ) {
+		function checkTriangleVisibility( v1, v2, v3 ) {
 
 			if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true;
 
@@ -223,20 +223,20 @@ THREE.Projector = function () {
 			_points3[ 1 ] = v2.positionScreen;
 			_points3[ 2 ] = v3.positionScreen;
 
-			return _clipBox.isIntersectionBox( _boundingBox.setFromPoints( _points3 ) );
+			return _clipBox.intersectsBox( _boundingBox.setFromPoints( _points3 ) );
 
-		};
+		}
 
-		var checkBackfaceCulling = function ( v1, v2, v3 ) {
+		function checkBackfaceCulling( v1, v2, v3 ) {
 
 			return ( ( v3.positionScreen.x - v1.positionScreen.x ) *
 				    ( v2.positionScreen.y - v1.positionScreen.y ) -
 				    ( v3.positionScreen.y - v1.positionScreen.y ) *
 				    ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
 
-		};
+		}
 
-		var pushLine = function ( a, b ) {
+		function pushLine( a, b ) {
 
 			var v1 = _vertexPool[ a ];
 			var v2 = _vertexPool[ b ];
@@ -253,9 +253,9 @@ THREE.Projector = function () {
 
 			_renderData.elements.push( _line );
 
-		};
+		}
 
-		var pushTriangle = function ( a, b, c ) {
+		function pushTriangle( a, b, c ) {
 
 			var v1 = _vertexPool[ a ];
 			var v2 = _vertexPool[ b ];
@@ -298,7 +298,7 @@ THREE.Projector = function () {
 
 			}
 
-		};
+		}
 
 		return {
 			setObject: setObject,

+ 2 - 8
examples/js/renderers/SVGRenderer.js

@@ -36,7 +36,6 @@ THREE.SVGRenderer = function () {
 	_clearColor = new THREE.Color(),
 	_clearAlpha = 1,
 
-	_w, // z-buffer to w-buffer
 	_vector3 = new THREE.Vector3(), // Needed for PointLight
 	_centroid = new THREE.Vector3(),
 	_normal = new THREE.Vector3(),
@@ -171,7 +170,7 @@ THREE.SVGRenderer = function () {
 
 				_elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen ] );
 
-				if ( _clipBox.isIntersectionBox( _elemBox ) === true ) {
+				if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
 					renderLine( _v1, _v2, element, material );
 
@@ -195,7 +194,7 @@ THREE.SVGRenderer = function () {
 					_v3.positionScreen
 				] );
 
-				if ( _clipBox.isIntersectionBox( _elemBox ) === true ) {
+				if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
 					renderFace3( _v1, _v2, _v3, element, material );
 
@@ -383,11 +382,6 @@ THREE.SVGRenderer = function () {
 
 			_color.multiply( _diffuseColor ).add( material.emissive );
 
-		} else if ( material instanceof THREE.MeshDepthMaterial ) {
-
-			_w = 1 - ( material.__2near / ( material.__farPlusNear - element.z * material.__farMinusNear ) );
-			_color.setRGB( _w, _w, _w );
-
 		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
 			_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix );

+ 13 - 205
src/extras/FontUtils.js → examples/js/utils/FontUtils.js

@@ -109,6 +109,9 @@ THREE.FontUtils = {
 
 		var pts = [];
 
+		var b2 = THREE.ShapeUtils.b2;
+		var b3 = THREE.ShapeUtils.b3;
+
 		var i, i2, divisions,
 			outline, action, length,
 			scaleX, scaleY,
@@ -174,8 +177,8 @@ THREE.FontUtils = {
 						for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
 
 							var t = i2 / divisions;
-							THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx );
-							THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy );
+							b2( t, cpx0, cpx1, cpx );
+							b2( t, cpy0, cpy1, cpy );
 
 						}
 
@@ -187,12 +190,12 @@ THREE.FontUtils = {
 
 					// Cubic Bezier Curve
 
-					cpx  = outline[ i ++ ] *  scaleX + offset;
-					cpy  = outline[ i ++ ] *  scaleY;
-					cpx1 = outline[ i ++ ] *  scaleX + offset;
-					cpy1 = outline[ i ++ ] *  scaleY;
-					cpx2 = outline[ i ++ ] *  scaleX + offset;
-					cpy2 = outline[ i ++ ] *  scaleY;
+					cpx  = outline[ i ++ ] * scaleX + offset;
+					cpy  = outline[ i ++ ] * scaleY;
+					cpx1 = outline[ i ++ ] * scaleX + offset;
+					cpy1 = outline[ i ++ ] * scaleY;
+					cpx2 = outline[ i ++ ] * scaleX + offset;
+					cpy2 = outline[ i ++ ] * scaleY;
 
 					path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
 
@@ -206,8 +209,8 @@ THREE.FontUtils = {
 						for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
 
 							var t = i2 / divisions;
-							THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx );
-							THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy );
+							b3( t, cpx0, cpx1, cpx2, cpx );
+							b3( t, cpy0, cpy1, cpy2, cpy );
 
 						}
 
@@ -267,201 +270,6 @@ THREE.FontUtils.generateShapes = function ( text, parameters ) {
 
 };
 
-
-/**
- * This code is a quick port of code written in C++ which was submitted to
- * flipcode.com by John W. Ratcliff  // July 22, 2000
- * See original code and more information here:
- * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
- *
- * ported to actionscript by Zevan Rosser
- * www.actionsnippet.com
- *
- * ported to javascript by Joshua Koo
- * http://www.lab4games.net/zz85/blog
- *
- */
-
-
-( function ( namespace ) {
-
-	var EPSILON = 0.0000000001;
-
-	// takes in an contour array and returns
-
-	var process = function ( contour, indices ) {
-
-		var n = contour.length;
-
-		if ( n < 3 ) return null;
-
-		var result = [],
-			verts = [],
-			vertIndices = [];
-
-		/* we want a counter-clockwise polygon in verts */
-
-		var u, v, w;
-
-		if ( area( contour ) > 0.0 ) {
-
-			for ( v = 0; v < n; v ++ ) verts[ v ] = v;
-
-		} else {
-
-			for ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;
-
-		}
-
-		var nv = n;
-
-		/*  remove nv - 2 vertices, creating 1 triangle every time */
-
-		var count = 2 * nv;   /* error detection */
-
-		for ( v = nv - 1; nv > 2; ) {
-
-			/* if we loop, it is probably a non-simple polygon */
-
-			if ( ( count -- ) <= 0 ) {
-
-				//** Triangulate: ERROR - probable bad polygon!
-
-				//throw ( "Warning, unable to triangulate polygon!" );
-				//return null;
-				// Sometimes warning is fine, especially polygons are triangulated in reverse.
-				console.warn( 'THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()' );
-
-				if ( indices ) return vertIndices;
-				return result;
-
-			}
-
-			/* three consecutive vertices in current polygon, <u,v,w> */
-
-			u = v; 	 	if ( nv <= u ) u = 0;     /* previous */
-			v = u + 1;  if ( nv <= v ) v = 0;     /* new v    */
-			w = v + 1;  if ( nv <= w ) w = 0;     /* next     */
-
-			if ( snip( contour, u, v, w, nv, verts ) ) {
-
-				var a, b, c, s, t;
-
-				/* true names of the vertices */
-
-				a = verts[ u ];
-				b = verts[ v ];
-				c = verts[ w ];
-
-				/* output Triangle */
-
-				result.push( [ contour[ a ],
-					contour[ b ],
-					contour[ c ] ] );
-
-
-				vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
-
-				/* remove v from the remaining polygon */
-
-				for ( s = v, t = v + 1; t < nv; s ++, t ++ ) {
-
-					verts[ s ] = verts[ t ];
-
-				}
-
-				nv --;
-
-				/* reset error detection counter */
-
-				count = 2 * nv;
-
-			}
-
-		}
-
-		if ( indices ) return vertIndices;
-		return result;
-
-	};
-
-	// calculate area of the contour polygon
-
-	var area = function ( contour ) {
-
-		var n = contour.length;
-		var a = 0.0;
-
-		for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
-
-			a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
-
-		}
-
-		return a * 0.5;
-
-	};
-
-	var snip = function ( contour, u, v, w, n, verts ) {
-
-		var p;
-		var ax, ay, bx, by;
-		var cx, cy, px, py;
-
-		ax = contour[ verts[ u ] ].x;
-		ay = contour[ verts[ u ] ].y;
-
-		bx = contour[ verts[ v ] ].x;
-		by = contour[ verts[ v ] ].y;
-
-		cx = contour[ verts[ w ] ].x;
-		cy = contour[ verts[ w ] ].y;
-
-		if ( EPSILON > ( ( ( bx - ax ) * ( cy - ay ) ) - ( ( by - ay ) * ( cx - ax ) ) ) ) return false;
-
-		var aX, aY, bX, bY, cX, cY;
-		var apx, apy, bpx, bpy, cpx, cpy;
-		var cCROSSap, bCROSScp, aCROSSbp;
-
-		aX = cx - bx;  aY = cy - by;
-		bX = ax - cx;  bY = ay - cy;
-		cX = bx - ax;  cY = by - ay;
-
-		for ( p = 0; p < n; p ++ ) {
-
-			px = contour[ verts[ p ] ].x;
-			py = contour[ verts[ p ] ].y;
-
-			if ( ( ( px === ax ) && ( py === ay ) ) ||
-				 ( ( px === bx ) && ( py === by ) ) ||
-				 ( ( px === cx ) && ( py === cy ) ) )	continue;
-
-			apx = px - ax;  apy = py - ay;
-			bpx = px - bx;  bpy = py - by;
-			cpx = px - cx;  cpy = py - cy;
-
-			// see if p is inside triangle abc
-
-			aCROSSbp = aX * bpy - aY * bpx;
-			cCROSSap = cX * apy - cY * apx;
-			bCROSScp = bX * cpy - bY * cpx;
-
-			if ( ( aCROSSbp >= - EPSILON ) && ( bCROSScp >= - EPSILON ) && ( cCROSSap >= - EPSILON ) ) return false;
-
-		}
-
-		return true;
-
-	};
-
-
-	namespace.Triangulate = process;
-	namespace.Triangulate.area = area;
-
-	return namespace;
-
-} )( THREE.FontUtils );
-
 // To use the typeface.js face files, hook up the API
 
 THREE.typeface_js = { faces: THREE.FontUtils.faces, loadFace: THREE.FontUtils.loadFace };

+ 136 - 0
examples/js/utils/ImageUtils.js

@@ -0,0 +1,136 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ * @author mrdoob / http://mrdoob.com/
+ * @author Daosheng Mu / https://github.com/DaoshengMu/
+ */
+
+THREE.ImageUtils = {
+
+	getNormalMap: function ( image, depth ) {
+
+		// Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
+
+		function cross( a, b ) {
+
+			return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
+
+		}
+
+		function subtract( a, b ) {
+
+			return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
+
+		}
+
+		function normalize( a ) {
+
+			var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
+			return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
+
+		}
+
+		depth = depth | 1;
+
+		var width = image.width;
+		var height = image.height;
+
+		var canvas = document.createElement( 'canvas' );
+		canvas.width = width;
+		canvas.height = height;
+
+		var context = canvas.getContext( '2d' );
+		context.drawImage( image, 0, 0 );
+
+		var data = context.getImageData( 0, 0, width, height ).data;
+		var imageData = context.createImageData( width, height );
+		var output = imageData.data;
+
+		for ( var x = 0; x < width; x ++ ) {
+
+			for ( var y = 0; y < height; y ++ ) {
+
+				var ly = y - 1 < 0 ? 0 : y - 1;
+				var uy = y + 1 > height - 1 ? height - 1 : y + 1;
+				var lx = x - 1 < 0 ? 0 : x - 1;
+				var ux = x + 1 > width - 1 ? width - 1 : x + 1;
+
+				var points = [];
+				var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
+				points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
+				points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
+				points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
+				points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
+				points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
+				points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
+				points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
+				points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
+
+				var normals = [];
+				var num_points = points.length;
+
+				for ( var i = 0; i < num_points; i ++ ) {
+
+					var v1 = points[ i ];
+					var v2 = points[ ( i + 1 ) % num_points ];
+					v1 = subtract( v1, origin );
+					v2 = subtract( v2, origin );
+					normals.push( normalize( cross( v1, v2 ) ) );
+
+				}
+
+				var normal = [ 0, 0, 0 ];
+
+				for ( var i = 0; i < normals.length; i ++ ) {
+
+					normal[ 0 ] += normals[ i ][ 0 ];
+					normal[ 1 ] += normals[ i ][ 1 ];
+					normal[ 2 ] += normals[ i ][ 2 ];
+
+				}
+
+				normal[ 0 ] /= normals.length;
+				normal[ 1 ] /= normals.length;
+				normal[ 2 ] /= normals.length;
+
+				var idx = ( y * width + x ) * 4;
+
+				output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
+				output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
+				output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
+				output[ idx + 3 ] = 255;
+
+			}
+
+		}
+
+		context.putImageData( imageData, 0, 0 );
+
+		return canvas;
+
+	},
+
+	generateDataTexture: function ( width, height, color ) {
+
+		var size = width * height;
+		var data = new Uint8Array( 3 * size );
+
+		var r = Math.floor( color.r * 255 );
+		var g = Math.floor( color.g * 255 );
+		var b = Math.floor( color.b * 255 );
+
+		for ( var i = 0; i < size; i ++ ) {
+
+			data[ i * 3 ] 	   = r;
+			data[ i * 3 + 1 ] = g;
+			data[ i * 3 + 2 ] = b;
+
+		}
+
+		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
+		texture.needsUpdate = true;
+
+		return texture;
+
+	}
+
+};

+ 3 - 3
examples/js/utils/ShadowMapViewer.js

@@ -35,7 +35,7 @@ THREE.ShadowMapViewer = function ( light ) {
 	var userAutoClearSetting;
 
 	//Holds the initial position and dimension of the HUD
-	var frame = { 
+	var frame = {
 		x: 10,
 		y: 10,
 		width: 256,
@@ -103,7 +103,7 @@ THREE.ShadowMapViewer = function ( light ) {
 
 	//- API
 	// Set to false to disable displaying this shadow map
-	this.enabled = true; 
+	this.enabled = true;
 
 	// Set the size of the displayed shadow map on the HUD
 	this.size = {
@@ -150,7 +150,7 @@ THREE.ShadowMapViewer = function ( light ) {
 			//always end up with the scene's first added shadow casting light's shadowMap
 			//in the shader
 			//See: https://github.com/mrdoob/three.js/issues/5932
-			uniforms.tDiffuse.value = light.shadowMap;
+			uniforms.tDiffuse.value = light.shadow.map;
 
 			userAutoClearSetting = renderer.autoClear;
 			renderer.autoClear = false; // To allow render overlay

+ 1 - 0
examples/misc_controls_pointerlock.html

@@ -181,6 +181,7 @@
 			var moveBackward = false;
 			var moveLeft = false;
 			var moveRight = false;
+			var canJump = false;
 
 			var prevTime = performance.now();
 			var velocity = new THREE.Vector3();

+ 1 - 1
examples/misc_lookat.html

@@ -64,7 +64,7 @@
 
 				scene = new THREE.Scene();
 
-				sphere = new THREE.Mesh( new THREE.SphereGeometry( 100, 20, 20 ), new THREE.MeshNormalMaterial( { shading: THREE.SmoothShading } ) );
+				sphere = new THREE.Mesh( new THREE.SphereGeometry( 100, 20, 20 ), new THREE.MeshNormalMaterial() );
 				scene.add( sphere );
 
 				var geometry = new THREE.CylinderGeometry( 0, 10, 100, 3 );

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 0
examples/models/amf/rook.amf


+ 0 - 1
examples/models/animated/horse.js

@@ -11,7 +11,6 @@
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgName" : "comp_horse_rig:blinn9SG",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.41999999999999998, 0.56999999999999995, 0.45000000000000001],
 	"colorSpecular" : [1.0, 0.42999999999999999, 0.35999999999999999],
 	"illumination" : 4,

+ 0 - 1
examples/models/animated/monster/monster.js

@@ -19,7 +19,6 @@
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgName" : "monster",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
 	"colorSpecular" : [0.37434511778136503, 0.37434511778136503, 0.37434511778136503],
 	"mapDiffuse" : "monster.jpg",

+ 0 - 2
examples/models/animated/sittingBox.js

@@ -26,7 +26,6 @@
 	"DbgColor" : 15597568,
 	"DbgIndex" : 1,
 	"DbgName" : "Material",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.434594637671033, 0.434594637671033, 0.434594637671033],
 	"colorSpecular" : [0.10135135054588318, 0.10135135054588318, 0.10135135054588318],
 	"shading" : "Lambert",
@@ -39,7 +38,6 @@
 	"DbgColor" : 15597568,
 	"DbgIndex" : 1,
 	"DbgName" : "Material",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.434594637671033, 0.434594637671033, 0.434594637671033],
 	"colorSpecular" : [0.10135135054588318, 0.10135135054588318, 0.10135135054588318],
 	"shading" : "Lambert",

+ 0 - 1
examples/models/animated/stork.js

@@ -11,7 +11,6 @@
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgName" : "initialShadingGroup",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5, 0.5, 0.5],
 	"illumination" : 4,
 	"opticalDensity" : 1.0

+ 0 - 8
examples/models/ctm/camaro/camaro.js

@@ -9,7 +9,6 @@
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgName" : "Body_car-ao",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.1816, 0.3264, 0.3704],
 	"colorSpecular" : [2.0, 2.0, 2.0],
 	"illumination" : 2,
@@ -23,7 +22,6 @@
 	"DbgColor" : 15597568,
 	"DbgIndex" : 1,
 	"DbgName" : "tire_car-ao",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.2168, 0.2168, 0.2104],
 	"colorSpecular" : [0.1, 0.1, 0.1],
 	"illumination" : 2,
@@ -37,7 +35,6 @@
 	"DbgColor" : 60928,
 	"DbgIndex" : 2,
 	"DbgName" : "black2_car-ao",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.0, 0.0, 0.0],
 	"colorSpecular" : [0.0, 0.0, 0.0],
 	"illumination" : 2,
@@ -51,7 +48,6 @@
 	"DbgColor" : 238,
 	"DbgIndex" : 3,
 	"DbgName" : "tireling_car-ao",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.4, 0.4, 0.4],
 	"colorSpecular" : [0.2, 0.2, 0.2],
 	"illumination" : 2,
@@ -65,7 +61,6 @@
 	"DbgColor" : 15658496,
 	"DbgIndex" : 4,
 	"DbgName" : "glass_car-ao",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.16, 0.248, 0.2448],
 	"colorSpecular" : [2.0, 2.0, 2.0],
 	"illumination" : 2,
@@ -79,7 +74,6 @@
 	"DbgColor" : 61166,
 	"DbgIndex" : 5,
 	"DbgName" : "black_car-ao",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.0816, 0.0816, 0.0816],
 	"colorSpecular" : [0.2, 0.2, 0.2],
 	"illumination" : 2,
@@ -93,7 +87,6 @@
 	"DbgColor" : 15597806,
 	"DbgIndex" : 6,
 	"DbgName" : "mirror_car-ao",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.24, 0.24, 0.24],
 	"colorSpecular" : [2.0, 2.0, 2.0],
 	"illumination" : 2,
@@ -108,7 +101,6 @@
 	"DbgColor" : 3744854,
 	"DbgIndex" : 8,
 	"DbgName" : "Material.001_plane-ao-256",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.798635, 0.776149, 0.8],
 	"colorSpecular" : [0.5, 0.5, 0.5],
 	"illumination" : 2,

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

@@ -60,7 +60,6 @@
         },
         "materials": [{
             "opacity": 1,
-            "colorAmbient": [0.8,0.8,0.8],
             "doubleSided": true,
             "depthWrite": true,
             "depthTest": true,

+ 0 - 0
examples/models/md2/ratamahatta/w_chaingun.MD2 → examples/models/md2/ratamahatta/w_chaingun.md2


+ 0 - 0
examples/obj/tree/tree.obj → examples/models/obj/tree.obj


+ 0 - 1
examples/models/skinned/UCS/umich_ucs.js

@@ -18,7 +18,6 @@
 "DbgIndex" : 0,
 "DbgName"  : "Material #0",
 "colorDiffuse"  : [0.5880, 0.5880, 0.5880],
-"colorAmbient"  : [0.5880, 0.5880, 0.5880],
 "colorSpecular"  : [0.9000, 0.9000, 0.9000],
 "opacity"  : 1.0,
 "specularCoef"  : 10.0,

+ 0 - 1
examples/models/skinned/knight.js

@@ -21,7 +21,6 @@
 	"DbgIndex" : 0,
 	"DbgName" : "WHITE",
 	"blending" : "NormalBlending",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
 	"colorSpecular" : [0.1, 0.1, 0.1],
 	"depthTest" : true,

+ 0 - 1
examples/models/skinned/marine/m4.js

@@ -21,7 +21,6 @@
 		"DbgIndex" : 0,
 		"DbgName" : "M4",
 		"blending" : "NormalBlending",
-		"colorAmbient" : [0.5351081581544648, 0.5351081581544648, 0.5351081581544648],
 		"colorDiffuse" : [0.5351081581544648, 0.5351081581544648, 0.5351081581544648],
 		"colorSpecular" : [1.0, 1.0, 1.0],
 		"depthTest" : true,

+ 0 - 1
examples/models/skinned/marine/marine.js

@@ -21,7 +21,6 @@
     "DbgIndex" : 0,
     "DbgName" : "MaleMarineC",
     "blending" : "NormalBlending",
-    "colorAmbient" : [0.5364704212020399, 0.5364704212020399, 0.5364704212020399],
     "colorDiffuse" : [0.5364704212020399, 0.5364704212020399, 0.5364704212020399],
     "colorSpecular" : [0.19372500479221344, 0.19372500479221344, 0.19372500479221344],
     "depthTest" : true,

+ 0 - 1
examples/models/skinned/marine/marine_anims.js

@@ -21,7 +21,6 @@
 		"DbgIndex" : 0,
 		"DbgName" : "MaleMarineC",
 		"blending" : "NormalBlending",
-		"colorAmbient" : [0.5364704212020399, 0.5364704212020399, 0.5364704212020399],
 		"colorDiffuse" : [0.5364704212020399, 0.5364704212020399, 0.5364704212020399],
 		"colorSpecular" : [0.19372500479221344, 0.19372500479221344, 0.19372500479221344],
 		"depthTest" : true,

+ 0 - 1
examples/models/skinned/marine/marine_ikrig.js

@@ -21,7 +21,6 @@
 		"DbgIndex" : 0,
 		"DbgName" : "MaleMarineC",
 		"blending" : "NormalBlending",
-		"colorAmbient" : [0.5364704212020399, 0.5364704212020399, 0.5364704212020399],
 		"colorDiffuse" : [0.5364704212020399, 0.5364704212020399, 0.5364704212020399],
 		"colorSpecular" : [0.19372500479221344, 0.19372500479221344, 0.19372500479221344],
 		"depthTest" : true,

+ 0 - 1
examples/models/skinned/simple/simple.js

@@ -21,7 +21,6 @@
 		"DbgIndex" : 0,
 		"DbgName" : "Material",
 		"blending" : "NormalBlending",
-		"colorAmbient" : [0.1569801711586143, 0.17312412519937936, 0.6400000190734865],
 		"colorDiffuse" : [0.1569801711586143, 0.17312412519937936, 0.6400000190734865],
 		"colorEmissive" : [0.0, 0.0, 0.0],
 		"colorSpecular" : [0.2535329759120941, 0.0, 0.007157782092690468],

+ 0 - 1
examples/obj/blenderscene/scene.Cube.js

@@ -21,7 +21,6 @@
 		"DbgIndex" : 0,
 		"DbgName" : "Material",
 		"blending" : "NormalBlending",
-		"colorAmbient" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746],
 		"colorDiffuse" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746],
 		"colorSpecular" : [0.5, 0.5, 0.5],
 		"depthTest" : true,

+ 0 - 1
examples/obj/blenderscene/scene.Monkey.js

@@ -21,7 +21,6 @@
 		"DbgIndex" : 0,
 		"DbgName" : "Material.002",
 		"blending" : "NormalBlending",
-		"colorAmbient" : [0.6400000190734865, 0.44102483452893537, 0.14499310471107218],
 		"colorDiffuse" : [0.6400000190734865, 0.44102483452893537, 0.14499310471107218],
 		"colorSpecular" : [0.5, 0.5, 0.5],
 		"depthTest" : true,

+ 0 - 1
examples/obj/blenderscene/scene.Plane.js

@@ -21,7 +21,6 @@
 		"DbgIndex" : 0,
 		"DbgName" : "Material.001",
 		"blending" : "NormalBlending",
-		"colorAmbient" : [0.14462547517754842, 0.6400000190734865, 0.24541190036254967],
 		"colorDiffuse" : [0.14462547517754842, 0.6400000190734865, 0.24541190036254967],
 		"colorSpecular" : [0.5, 0.5, 0.5],
 		"depthTest" : true,

+ 0 - 9
examples/obj/camaro/CamaroNoUv_bin.js

@@ -16,7 +16,6 @@
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgName" : "Body",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.227, 0.408, 0.463],
 	"colorSpecular" : [2.0, 2.0, 2.0],
 	"illumination" : 2,
@@ -29,7 +28,6 @@
 	"DbgColor" : 15597568,
 	"DbgIndex" : 1,
 	"DbgName" : "mirror",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.3, 0.3, 0.3],
 	"colorSpecular" : [2.0, 2.0, 2.0],
 	"illumination" : 2,
@@ -42,7 +40,6 @@
 	"DbgColor" : 60928,
 	"DbgIndex" : 2,
 	"DbgName" : "black",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.102, 0.102, 0.102],
 	"colorSpecular" : [0.2, 0.2, 0.2],
 	"illumination" : 2,
@@ -55,7 +52,6 @@
 	"DbgColor" : 238,
 	"DbgIndex" : 3,
 	"DbgName" : "mizo",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.0, 0.0, 0.0],
 	"colorSpecular" : [0.0, 0.0, 0.0],
 	"illumination" : 1,
@@ -68,7 +64,6 @@
 	"DbgColor" : 15658496,
 	"DbgIndex" : 4,
 	"DbgName" : "glass",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.2, 0.31, 0.306],
 	"colorSpecular" : [2.0, 2.0, 2.0],
 	"illumination" : 2,
@@ -81,7 +76,6 @@
 	"DbgColor" : 61166,
 	"DbgIndex" : 5,
 	"DbgName" : "Interieur",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.102, 0.102, 0.102],
 	"colorSpecular" : [0.44, 0.44, 0.44],
 	"illumination" : 2,
@@ -94,7 +88,6 @@
 	"DbgColor" : 15597806,
 	"DbgIndex" : 6,
 	"DbgName" : "tire",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.271, 0.271, 0.263],
 	"colorSpecular" : [0.1, 0.1, 0.1],
 	"illumination" : 2,
@@ -107,7 +100,6 @@
 	"DbgColor" : 3744854,
 	"DbgIndex" : 7,
 	"DbgName" : "tireling",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5, 0.5, 0.5],
 	"colorSpecular" : [0.2, 0.2, 0.2],
 	"illumination" : 2,
@@ -120,7 +112,6 @@
 	"DbgColor" : 4614226,
 	"DbgIndex" : 8,
 	"DbgName" : "black2",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.0, 0.0, 0.0],
 	"colorSpecular" : [0.0, 0.0, 0.0],
 	"illumination" : 1,

+ 0 - 1
examples/obj/cubecolors/cube_fvc.js

@@ -20,7 +20,6 @@
 	"DbgIndex" : 0,
 	"DbgName" : "Material",
 	"blending" : "NormalBlending",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.800000011920929, 0.800000011920929, 0.800000011920929],
 	"colorSpecular" : [0.5, 0.5, 0.5],
 	"depthTest" : true,

+ 0 - 1
examples/obj/cubecolors/cubecolors.js

@@ -20,7 +20,6 @@
 	"DbgIndex" : 0,
 	"DbgName" : "Material",
 	"blending" : "NormalBlending",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [1.0, 1.0, 1.0],
 	"colorSpecular" : [0.0, 0.0, 0.0],
 	"depthTest" : true,

+ 0 - 25
examples/obj/f50/F50NoUv_bin.js

@@ -16,7 +16,6 @@
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgName" : "F50NEGRO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -28,7 +27,6 @@
 	"DbgColor" : 15597568,
 	"DbgIndex" : 1,
 	"DbgName" : "F50CROMO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.1004, 0.10352, 0.06272],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -40,7 +38,6 @@
 	"DbgColor" : 60928,
 	"DbgIndex" : 2,
 	"DbgName" : "F50CRIST",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.0408, 0.15688, 0.00312],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -53,7 +50,6 @@
 	"DbgColor" : 238,
 	"DbgIndex" : 3,
 	"DbgName" : "F50ROJO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -65,7 +61,6 @@
 	"DbgColor" : 15658496,
 	"DbgIndex" : 4,
 	"DbgName" : "F50NEGRO1",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -77,7 +72,6 @@
 	"DbgColor" : 61166,
 	"DbgIndex" : 5,
 	"DbgName" : "F50ALFO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -89,7 +83,6 @@
 	"DbgColor" : 15597806,
 	"DbgIndex" : 6,
 	"DbgName" : "F50REJIL",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -101,7 +94,6 @@
 	"DbgColor" : 13579988,
 	"DbgIndex" : 7,
 	"DbgName" : "F50RIGHT",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -113,7 +105,6 @@
 	"DbgColor" : 5708456,
 	"DbgIndex" : 8,
 	"DbgName" : "F50CAPO1",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -125,7 +116,6 @@
 	"DbgColor" : 16326172,
 	"DbgIndex" : 9,
 	"DbgName" : "F50CAPO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -137,7 +127,6 @@
 	"DbgColor" : 5647119,
 	"DbgIndex" : 10,
 	"DbgName" : "F50LEFT",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -149,7 +138,6 @@
 	"DbgColor" : 1556016,
 	"DbgIndex" : 11,
 	"DbgName" : "F50MOTOR",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.1004, 0.10352, 0.06272],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -161,7 +149,6 @@
 	"DbgColor" : 2608512,
 	"DbgIndex" : 12,
 	"DbgName" : "F50GOOD",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -173,7 +160,6 @@
 	"DbgColor" : 13541364,
 	"DbgIndex" : 13,
 	"DbgName" : "F50RUEDA",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -185,7 +171,6 @@
 	"DbgColor" : 16059369,
 	"DbgIndex" : 14,
 	"DbgName" : "F50SUELO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -197,7 +182,6 @@
 	"DbgColor" : 109031,
 	"DbgIndex" : 15,
 	"DbgName" : "F50DISCO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.41096, 0.3608, 0.25728],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -209,7 +193,6 @@
 	"DbgColor" : 10128841,
 	"DbgIndex" : 16,
 	"DbgName" : "F50FARYE",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.79056, 0.41096, 0.00624],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -222,7 +205,6 @@
 	"DbgColor" : 6350752,
 	"DbgIndex" : 17,
 	"DbgName" : "F5OLOGO",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.41096, 0.3608, 0.25728],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -234,7 +216,6 @@
 	"DbgColor" : 9261704,
 	"DbgIndex" : 18,
 	"DbgName" : "F50FARED",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.63056, 0.07528, 0.05016],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -247,7 +228,6 @@
 	"DbgColor" : 1622631,
 	"DbgIndex" : 19,
 	"DbgName" : "F50FARWD",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.40472, 0.40472, 0.40472],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -260,7 +240,6 @@
 	"DbgColor" : 12242867,
 	"DbgIndex" : 20,
 	"DbgName" : "F50ASIEN",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -272,7 +251,6 @@
 	"DbgColor" : 13519402,
 	"DbgIndex" : 21,
 	"DbgName" : "F50MATR",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5992, 0.58984, 0.56472],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -284,7 +262,6 @@
 	"DbgColor" : 8996413,
 	"DbgIndex" : 22,
 	"DbgName" : "F50AIRE",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.15376, 0.10984, 0.03768],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -296,7 +273,6 @@
 	"DbgColor" : 11712834,
 	"DbgIndex" : 23,
 	"DbgName" : "F50TOPAL",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,
@@ -308,7 +284,6 @@
 	"DbgColor" : 14218595,
 	"DbgIndex" : 24,
 	"DbgName" : "F50TOPAL1",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.5616, 0.04392, 0.06904],
 	"colorSpecular" : [0.025, 0.025, 0.025],
 	"illumination" : 2,

+ 0 - 6
examples/obj/female02/Female02_bin.js

@@ -16,7 +16,6 @@
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgName" : "_03_-_Default1noCulli__03_-_Default1noCulli",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.64, 0.64, 0.64],
 	"colorSpecular" : [0.165, 0.165, 0.165],
 	"illumination" : 2,
@@ -30,7 +29,6 @@
 	"DbgColor" : 15597568,
 	"DbgIndex" : 1,
 	"DbgName" : "_02_-_Default1noCulli__02_-_Default1noCulli",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.64, 0.64, 0.64],
 	"colorSpecular" : [0.165, 0.165, 0.165],
 	"illumination" : 2,
@@ -44,7 +42,6 @@
 	"DbgColor" : 60928,
 	"DbgIndex" : 2,
 	"DbgName" : "FrontColorNoCullingID__02_-_Default1noCulli",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.8, 0.8, 0.8],
 	"colorSpecular" : [0.165, 0.165, 0.165],
 	"illumination" : 2,
@@ -58,7 +55,6 @@
 	"DbgColor" : 238,
 	"DbgIndex" : 3,
 	"DbgName" : "FrontColorNoCullingID__03_-_Default1noCulli",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.8, 0.8, 0.8],
 	"colorSpecular" : [0.165, 0.165, 0.165],
 	"illumination" : 2,
@@ -72,7 +68,6 @@
 	"DbgColor" : 15658496,
 	"DbgIndex" : 4,
 	"DbgName" : "_01_-_Default1noCulli__01_-_Default1noCulli",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.64, 0.64, 0.64],
 	"colorSpecular" : [0.165, 0.165, 0.165],
 	"illumination" : 2,
@@ -86,7 +81,6 @@
 	"DbgColor" : 61166,
 	"DbgIndex" : 5,
 	"DbgName" : "FrontColorNoCullingID__01_-_Default1noCulli",
-	"colorAmbient" : [0.0, 0.0, 0.0],
 	"colorDiffuse" : [0.8, 0.8, 0.8],
 	"colorSpecular" : [0.165, 0.165, 0.165],
 	"illumination" : 2,

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott