Browse Source

Merge remote-tracking branch 'mrdoob/dev'

Joshua Koo 13 years ago
parent
commit
99b235cf41
100 changed files with 4724 additions and 901 deletions
  1. 30 1
      README.md
  2. 151 146
      build/three.min.js
  3. 11 15
      docs/api/extras/geometries/CubeGeometry.html
  4. 57 8
      docs/api/materials/MeshBasicMaterial.html
  5. 1 1
      docs/index.html
  6. 104 52
      editor/index.html
  7. 48 22
      editor/js/UI.js
  8. 0 0
      editor/js/libs/signals.min.js
  9. 0 0
      editor/js/ui/Menubar.js
  10. 98 0
      editor/js/ui/Sidebar.Outliner.js
  11. 59 37
      editor/js/ui/Sidebar.Properties.Geometry.js
  12. 401 0
      editor/js/ui/Sidebar.Properties.Material.js
  13. 154 0
      editor/js/ui/Sidebar.Properties.Object3D.js
  14. 0 0
      editor/js/ui/Sidebar.Properties.js
  15. 0 0
      editor/js/ui/Sidebar.js
  16. 9 11
      editor/js/ui/Viewport.js
  17. 12 9
      examples/canvas_geometry_earth.html
  18. 408 0
      examples/canvas_geometry_shapes.html
  19. 4 1
      examples/canvas_geometry_terrain.html
  20. 1 1
      examples/canvas_materials_depth.html
  21. 8 9
      examples/js/effects/AnaglyphEffect.js
  22. 11 13
      examples/js/loaders/ColladaLoader.js
  23. 474 0
      examples/js/loaders/MTLLoader.js
  24. 6 6
      examples/js/loaders/OBJLoader.js
  25. 490 0
      examples/js/loaders/OBJMTLLoader.js
  26. 6 6
      examples/js/loaders/STLLoader.js
  27. 822 188
      examples/js/loaders/UTF8Loader.js
  28. 6 6
      examples/js/loaders/VTKLoader.js
  29. 8 7
      examples/js/loaders/ctm/CTMLoader.js
  30. 0 2
      examples/js/postprocessing/BloomPass.js
  31. 2 21
      examples/js/postprocessing/EffectComposer.js
  32. 164 0
      examples/js/renderers/CSS3DRenderer.js
  33. 1 1
      examples/js/renderers/DOMRenderer.js
  34. 14 8
      examples/js/renderers/SVGRenderer.js
  35. 1 1
      examples/js/renderers/SoftwareRenderer.js
  36. 1 1
      examples/js/renderers/SoftwareRenderer2.js
  37. 1 1
      examples/js/renderers/SoftwareRenderer3.js
  38. 1 1
      examples/misc_camera_fly.html
  39. 103 0
      examples/misc_css3d.html
  40. BIN
      examples/models/utf8/James_Body_Lores.jpg
  41. BIN
      examples/models/utf8/James_EyeLashBotTran.png
  42. BIN
      examples/models/utf8/James_EyeLashTopTran.png
  43. BIN
      examples/models/utf8/James_Eye_Green.jpg
  44. BIN
      examples/models/utf8/James_Eye_Inner_Green.jpg
  45. BIN
      examples/models/utf8/James_Face_Color_Hair_Lores.jpg
  46. BIN
      examples/models/utf8/James_Mouth_Gum_Lores.jpg
  47. BIN
      examples/models/utf8/James_Tongue_Lores.jpg
  48. BIN
      examples/models/utf8/MCasShoe1TEX_Lores.jpg
  49. BIN
      examples/models/utf8/MJeans1TEX_Lores.jpg
  50. BIN
      examples/models/utf8/MTshirt3TEX_Lores.jpg
  51. BIN
      examples/models/utf8/Nail_Hand_01_Lores.jpg
  52. 107 0
      examples/models/utf8/ben.js
  53. BIN
      examples/models/utf8/ben.utf8
  54. 107 0
      examples/models/utf8/ben_dds.js
  55. BIN
      examples/models/utf8/dds/James_Body_Lores.dds
  56. BIN
      examples/models/utf8/dds/James_EyeLashBotTran.dds
  57. BIN
      examples/models/utf8/dds/James_EyeLashTopTran.dds
  58. BIN
      examples/models/utf8/dds/James_Eye_Green.dds
  59. BIN
      examples/models/utf8/dds/James_Eye_Inner_Green.dds
  60. BIN
      examples/models/utf8/dds/James_Face_Color_Hair_Lores.dds
  61. BIN
      examples/models/utf8/dds/James_Mouth_Gum_Lores.dds
  62. BIN
      examples/models/utf8/dds/James_Tongue_Lores.dds
  63. BIN
      examples/models/utf8/dds/MCasShoe1TEX_Lores.dds
  64. BIN
      examples/models/utf8/dds/MJeans1TEX_Lores.dds
  65. BIN
      examples/models/utf8/dds/MTshirt3TEX_Lores.dds
  66. BIN
      examples/models/utf8/dds/Nail_Hand_01_Lores.dds
  67. BIN
      examples/models/utf8/hand.jpg
  68. 27 0
      examples/models/utf8/hand.js
  69. BIN
      examples/models/utf8/hand.utf8
  70. 20 8
      examples/obj/blenderscene/scene.Cube.js
  71. 10 5
      examples/obj/blenderscene/scene.Monkey.js
  72. 20 8
      examples/obj/blenderscene/scene.Plane.js
  73. 194 194
      examples/obj/blenderscene/scene.js
  74. BIN
      examples/obj/lightmap/lightmap-ao-shadow.png
  75. 123 0
      examples/obj/lightmap/lightmap.js
  76. 4 0
      examples/obj/lightmap/readme.txt
  77. BIN
      examples/obj/lightmap/rocks.jpg
  78. BIN
      examples/obj/lightmap/stone.jpg
  79. BIN
      examples/obj/male02/01_-_Default1noCulling.dds
  80. 87 0
      examples/obj/male02/Male02_dds.js
  81. BIN
      examples/obj/male02/male-02-1noCulling.dds
  82. 56 0
      examples/obj/male02/male02_dds.mtl
  83. BIN
      examples/obj/male02/orig_02_-_Defaul1noCulling.dds
  84. 225 30
      examples/scenes/test_scene.js
  85. BIN
      examples/textures/compressed/explosion_dxt5_mip.dds
  86. BIN
      examples/textures/compressed/hepatica_dxt3_mip.dds
  87. BIN
      examples/textures/cube/Escher/dds/nx.dds
  88. BIN
      examples/textures/cube/Escher/dds/ny.dds
  89. BIN
      examples/textures/cube/Escher/dds/nz.dds
  90. BIN
      examples/textures/cube/Escher/dds/px.dds
  91. BIN
      examples/textures/cube/Escher/dds/py.dds
  92. BIN
      examples/textures/cube/Escher/dds/pz.dds
  93. BIN
      examples/textures/shadow.png
  94. BIN
      examples/textures/shadowAlpha.png
  95. 0 3
      examples/webgl_buffergeometry.html
  96. 4 4
      examples/webgl_custom_attributes_lines.html
  97. 18 1
      examples/webgl_geometry_colors.html
  98. 44 60
      examples/webgl_geometry_shapes.html
  99. 10 9
      examples/webgl_loader_ctm.html
  100. 1 4
      examples/webgl_loader_ctm_materials.html

+ 30 - 1
README.md

@@ -5,7 +5,7 @@ three.js
 
 
 The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies. The library provides <canvas>, <svg> and WebGL renderers.
 The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies. The library provides <canvas>, <svg> and WebGL renderers.
 
 
-[Examples](http://mrdoob.github.com/three.js/) — [Documentation](http://mrdoob.github.com/three.js/docs/) — [Help](http://stackoverflow.com/questions/tagged/three.js)
+[Examples](http://mrdoob.github.com/three.js/) — [Documentation](http://mrdoob.github.com/three.js/docs/) — [Migrating](https://github.com/mrdoob/three.js/wiki/Migration) — [Help](http://stackoverflow.com/questions/tagged/three.js)
 
 
 
 
 ### Usage ###
 ### Usage ###
@@ -65,6 +65,35 @@ This code creates a scene, then creates a camera, adds the camera and cube to th
 
 
 ### Change log ###
 ### Change log ###
 
 
+2012 09 15 - **r51** (405,240 KB, gzip: 99,326 KB)
+
+* Added `STLLoader`. ([aleeper](http://github.com/aleeper) and [mrdoob](http://github.com/mrdoob))
+* Optimised `Ray` (2x faster). ([gero3](http://github.com/gero3))
+* Added `.getDescendants` method to `Object3D`. ([gero3](http://github.com/gero3) and [mrdoob](http://github.com/mrdoob))
+* `SkinnedMesh` can now work with `MorphAnimMesh`. ([apendua](http://github.com/apendua))
+* Changed `CameraHelper`. Now it matches the camera independently of where it's in the scene graph. ([mrdoob](http://github.com/mrdoob))
+* Removed the need for manually setting texture units with `ShaderMaterial`. ([alteredq](http://github.com/alteredq))
+* Added `HemisphereLight`. ([alteredq](http://github.com/alteredq))
+* Fixed `WebGLRenderer` handling of flip sided materials. ([WestLangley](http://github.com/WestLangley) and [alteredq](http://github.com/alteredq))
+* Added support to normals maps in `MeshPhongMaterial`. ([crobi](http://github.com/crobi) and [alteredq](http://github.com/alteredq))
+* Added handling of `BufferGeometry` for `ParticleSystems`. ([alteredq](http://github.com/alteredq))
+* Added support for compressed textures and cube maps to `WebGLRenderer`. ([alteredq](http://github.com/alteredq))
+* Outliner and Material panel improvements to the [editor](http://mrdoob.github.com/three.js/editor/). ([mrdoob](http://github.com/mrdoob))
+* Added material.emissive support to `CanvasRenderer` and `SVGRenderer`. ([mrdoob](http://github.com/mrdoob))
+* Added handling of multiple UV layers and anisotropy to Blender exporter. ([alteredq](http://github.com/alteredq))
+* Handling bump and anisotropy in `Loader` and `SceneLoader`. ([alteredq](http://github.com/alteredq))
+* Added mousewheel support to `TrackballControls`. ([jherrm](http://github.com/jherrm))
+* Added `MTLLoader` and `OBJMTLLoader`. ([angelxuanchang](http://github.com/angelxuanchang))
+* Updated `UTF8Loader` to latest version. ([angelxuanchang](http://github.com/angelxuanchang) and [alteredq](http://github.com/alteredq))
+* Pluginized `SceneLoader`. ([alteredq](http://github.com/alteredq))
+* Added support of `object.renderDepth` in `Projector`. ([mrdoob](http://github.com/mrdoob))
+* Made build system more flexible. ([mrdoob](http://github.com/mrdoob))
+* Many enhancements to `SceneLoader`. ([alteredq](http://github.com/alteredq))
+* Experimenting with `CSS3DRenderer`. ([mrdoob](http://github.com/mrdoob))
+* Added `ShapeGeometry`. ([jonobr1](http://github.com/jonobr1))
+* Fixes to `Vector3`'s `.setEulerFromRotationMatrix` method.([WestLangley](http://github.com/WestLangley))
+
+
 2012 08 15 - **r50** (391,250 KB, gzip: 96,143 KB)
 2012 08 15 - **r50** (391,250 KB, gzip: 96,143 KB)
 
 
 * Experimenting with [SoftwareRenderer](http://pouet.net/topic.php?which=8760&page=1). ([mrdoob](http://github.com/mrdoob) and [rygorous](http://github.com/rygorous))
 * Experimenting with [SoftwareRenderer](http://pouet.net/topic.php?which=8760&page=1). ([mrdoob](http://github.com/mrdoob) and [rygorous](http://github.com/rygorous))

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


+ 11 - 15
docs/api/extras/geometries/CubeGeometry.html

@@ -7,29 +7,25 @@
 		<link type="text/css" rel="stylesheet" href="../../../page.css" />
 		<link type="text/css" rel="stylesheet" href="../../../page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		<h1>[name]</h1>
+		<h1>CubeGeometry</h1>
 
 
-		<div class="desc">todo</div>
+		<div class="desc">CubeGeometry is the quadrilateral primitive geometry class. It is typically used for creating a cube or irregular quadrilateral of the dimensions provided within the (optional) 'width', 'height', & 'depth' constructor arguments.</div>
 
 
 
 
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
-		<h3>[name]()</h3>
-
-
-		<h2>Properties</h2>
-
-		<h3>.[page:Vector3 todo]</h3>
-
-
-		<h2>Methods</h2>
-
-		<h3>.todo( [page:Vector3 todo] )</h3>
+		<h3>[name]([page:Float width], [page:Float height], [page:Float depth], [page:Integer segmentsWidth], [page:Integer segmentsHeight], [page:Integer segmentsDepth], [page:Array materials], [page:Array sides])</h3>
 		<div>
 		<div>
-		todo — todo<br />
+		width — Width of the sides on the X axis.<br />
+		height — Height of the sides on the Y axis.<br />
+		depth — Depth of the sides on the Z axis.<br />
+		segmentsWidth — Number of segmented faces along the width of the sides.<br />
+		segmentsHeight — Number of segmented faces along the height of the sides.<br />
+		segmentsDepth — Number of segmented faces along the depth of the sides.<br />
+		materials — An array containing six [page:Material]s.<br />
+		sides — An array containig six [page:Boolean]s defining whether the side needs to be created.
 		</div>
 		</div>
 
 
-
 		<h2>Source</h2>
 		<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/src/[path].js src/[path].js]

+ 57 - 8
docs/api/materials/MeshBasicMaterial.html

@@ -11,26 +11,75 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">todo</div>
+		<div class="desc">A material for drawing geometries in a simple shaded (flat or wireframe) way.</div>
+		<div class="desc">The default will render as flat polygons. To draw the mesh as wireframe, simply set the 'wireframe' property to true.</div>
 
 
 
 
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
-		<h3>[name]()</h3>
+		<h3>[name]( [page:Object parameters] )</h3>
 
 
+		<div>parameters is an object with one or more properties defining the material's appearance.</div>
+		<div>
+		color — geometry color in hexadecimal. Default is 0xffffff.<br />
+		wireframe — render geometry as wireframe. Default is false.<br />
+		wireframeLinewidth — Line thickness. Default is 1.<br />
+		wireframeLinecap — Define appearance of line ends. Default is 'round'.<br />
+		wireframeLinejoin — Define appearance of line joints. Default is 'round'.<br />
+		shading — Define shading type. Default is THREE.SmoothShading.<br />
+		vertexColors — Define whether the material uses vertex colors, or not. Default is false.<br />
+		fog — Define whether the material color is affected by global fog settings. Default is false.<br />
+		lightMap — TODO. Default is null.<br />
+		specularMap — TODO. Default is null.<br />
+		envMap — TODO. Default is null.<br />
+		skinning — TODO. Default is false.<br />
+		morphTargets — TODO. Default is false.
+		</div>
 
 
 		<h2>Properties</h2>
 		<h2>Properties</h2>
 
 
-		<h3>.[page:Vector3 todo]</h3>
+		<h3>.[page:Integer color]</h3>
+		<div>Sets the color of the geometry. Default is 0xffffff.</div>
+		
+		<h3>.[page:Boolean wireframe]</h3>
+		<div>Render geometry as wireframe. Default is false (i.e. render as flat polygons).</div>
 
 
+		<h3>.[page:Float wireframeLinewidth]</h3>
+		<div>Controls wireframe thickness. Default is 1.</div>
+		
+		<h3>.[page:String wireframeLinecap]</h3>
+		<div>Define appearance of line ends. Possible values are "butt", "round" and "square". Default is 'round'.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:WebGLRenderer WebGL] renderer, but does work with the [page:CanvasRenderer Canvas] renderer.</div>
 
 
-		<h2>Methods</h2>
+		<h3>.[page:String wireframeLinejoin]</h3>
+		<div>Define appearance of line joints. Possible values are "round", "bevel" and "miter". Default is 'round'.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:WebGLRenderer WebGL] renderer, but does work with the [page:CanvasRenderer Canvas] renderer.</div>
+		
+		<h3>.[page:String shading]</h3>
+		<div>Define shading type. Default is THREE.SmoothShading.</div>
 
 
-		<h3>.todo( [page:Vector3 todo] )</h3>
-		<div>
-		todo — todo<br />
-		</div>
+		<h3>.[page:Boolean vertexColors]</h3>
+		<div>Define whether the material uses vertex colors, or not. Default is false.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>.[page:Boolean fog]</h3>
+		<div>Define whether the material color is affected by global fog settings.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>.[page:Texture lightMap]</h3>
+		<div>Set light map. Default is null.</div>
+
+		<h3>.[page:Texture specularMap]</h3>
+		<div>Set specular map. Default is null.</div>
+
+		<h3>.[page:TextureCube envMap]</h3>
+		<div>Set env map. Default is null.</div>
 
 
+		<h3>.[page:Boolean skinning]</h3>
+		<div>Define whether the material uses skinning. Default is false.</div>
+	
+		<h3>.[page:Boolean morphTargets]</h3>
+		<div>Define whether the material uses morphTargets. Default is false.</div>	
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 

+ 1 - 1
docs/index.html

@@ -84,7 +84,7 @@
 
 
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script>
 		<script>
-			var REVISION = '50';
+			var REVISION = '51';
 
 
 			var panel = document.getElementById( 'panel' );
 			var panel = document.getElementById( 'panel' );
 			var viewer = document.getElementById( 'viewer' );
 			var viewer = document.getElementById( 'viewer' );

+ 104 - 52
gui/index.html → editor/index.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
-		<title>three.js gui</title>
+		<title>three.js editor</title>
 		<style>
 		<style>
 			body {
 			body {
 				font-family: Arial, sans-serif;
 				font-family: Arial, sans-serif;
@@ -47,6 +47,8 @@
 
 
 			var signals = {
 			var signals = {
 
 
+				sceneCreated: new SIGNALS.Signal(),
+				sceneChanged: new SIGNALS.Signal(),
 				objectAdded: new SIGNALS.Signal(),
 				objectAdded: new SIGNALS.Signal(),
 				objectSelected: new SIGNALS.Signal(),
 				objectSelected: new SIGNALS.Signal(),
 				objectChanged: new SIGNALS.Signal(),
 				objectChanged: new SIGNALS.Signal(),
@@ -62,107 +64,159 @@
 			menubar.setHeight( '32px' );
 			menubar.setHeight( '32px' );
 			document.body.appendChild( menubar.dom );
 			document.body.appendChild( menubar.dom );
 
 
-			var viewport = new Viewport( signals );
-			viewport.setTop( '32px' );
-			viewport.setWidth( '-webkit-calc(100% - 300px)', '-moz-calc(100% - 300px)', 'calc(100% - 300px)' );
-			viewport.setHeight( '-webkit-calc(100% - 32px)', '-moz-calc(100% - 32px)', 'calc(100% - 32px)' );
-			document.body.appendChild( viewport.dom );
-
 			var sidebar = new Sidebar( signals );
 			var sidebar = new Sidebar( signals );
 			sidebar.setLeft( '-webkit-calc(100% - 300px)', '-moz-calc(100% - 300px)', 'calc(100% - 300px)' );
 			sidebar.setLeft( '-webkit-calc(100% - 300px)', '-moz-calc(100% - 300px)', 'calc(100% - 300px)' );
 			sidebar.setTop( '32px' );
 			sidebar.setTop( '32px' );
 			sidebar.setHeight( '-webkit-calc(100% - 32px)', '-moz-calc(100% - 32px)', 'calc(100% - 32px)' );
 			sidebar.setHeight( '-webkit-calc(100% - 32px)', '-moz-calc(100% - 32px)', 'calc(100% - 32px)' );
 			document.body.appendChild( sidebar.dom );
 			document.body.appendChild( sidebar.dom );
 
 
+			var viewport = new Viewport( signals );
+			viewport.setTop( '32px' );
+			viewport.setWidth( '-webkit-calc(100% - 300px)', '-moz-calc(100% - 300px)', 'calc(100% - 300px)' );
+			viewport.setHeight( '-webkit-calc(100% - 32px)', '-moz-calc(100% - 32px)', 'calc(100% - 32px)' );
+			document.body.appendChild( viewport.dom );
+
 			document.addEventListener( 'drop', function ( event ) {
 			document.addEventListener( 'drop', function ( event ) {
 
 
 				event.preventDefault();
 				event.preventDefault();
 
 
 				var file = event.dataTransfer.files[ 0 ];
 				var file = event.dataTransfer.files[ 0 ];
-				var extension = file.name.split( '.' )[1].toLowerCase();
+				var extension = file.name.split( '.' ).pop().toLowerCase();
 				var reader = new FileReader();
 				var reader = new FileReader();
 
 
 				reader.onload = function ( event ) {
 				reader.onload = function ( event ) {
 
 
-					var contents = event.target.result;
+					parseFile( event.target.result, extension );
 
 
-					switch ( extension ) {
+				};
 
 
-						case 'dae':
+				reader.readAsText( file );
 
 
-							var parser = new DOMParser();
-							var xml = parser.parseFromString( contents, 'text/xml' );
+			}, false );
 
 
-							// TODO: Update ColladaLoader
+			var parseFile = function ( contents, extension ) {
 
 
-							var loader = new THREE.ColladaLoader();
-							loader.parse( xml, function ( collada ) {
+				switch ( extension ) {
 
 
-								signals.objectAdded.dispatch( collada.scene );
-								signals.objectSelected.dispatch( collada.scene );
+					case 'dae':
 
 
-							} );
+						var parser = new DOMParser();
+						var xml = parser.parseFromString( contents, 'text/xml' );
 
 
-							break;
+						// TODO: Update ColladaLoader
 
 
-						case 'js':
+						var loader = new THREE.ColladaLoader();
+						loader.parse( xml, function ( collada ) {
 
 
-							var geometry = new THREE.GeometryLoader().parse( JSON.parse( contents ) );
-							var material = new THREE.MeshLambertMaterial( { color: 0xffffff } );
-							var mesh = new THREE.Mesh( geometry, material );
+							signals.objectAdded.dispatch( collada.scene );
+							signals.objectSelected.dispatch( collada.scene );
 
 
-							signals.objectAdded.dispatch( mesh );
-							signals.objectSelected.dispatch( mesh );
+						} );
 
 
-							break;
+						break;
 
 
-						case 'obj':
+					case 'js':
 
 
-							var object = new THREE.OBJLoader().parse( contents );
+						// 2.0
 
 
-							signals.objectAdded.dispatch( object );
-							signals.objectSelected.dispatch( object );
+						if ( contents.indexOf( 'postMessage' ) !== -1 ) {
 
 
-							break;
+							var blob = new Blob( [ contents ], { type: 'text/javascript' } );
+							var url = URL.createObjectURL( blob );
 
 
-						case 'stl':
+							var worker = new Worker( url );
 
 
-							var geometry = new THREE.STLLoader().parse( contents );
+							worker.onmessage = function ( event ) {
 
 
-							var mesh = new THREE.Mesh( geometry );
+								event.data.metadata = { 'format': 2 };
+								parseFile( JSON.stringify( event.data ), extension );
 
 
-							signals.objectAdded.dispatch( mesh );
-							signals.objectSelected.dispatch( mesh );
+							};
+
+							worker.postMessage( new Date().getTime() );
+
+							return;
 
 
-							break;
+						}
 
 
-						case 'utf8':
+						// 3.0
 
 
-							// TODO
+						var data = JSON.parse( contents );
 
 
-							break;
+						if ( data.metadata === undefined ) data.metadata = { type: 'geometry' }; // 2.0
+						if ( data.metadata.type === undefined ) data.metadata.type = 'geometry'; // 3.0
 
 
-						case 'vtk':
+						if ( data.metadata.type === 'geometry' ) {
+
+							var geometry = new THREE.GeometryLoader().parse( data );
+							var material = new THREE.MeshLambertMaterial();
 
 
-							var geometry = new THREE.VTKLoader().parse( contents );
-							var material = new THREE.MeshLambertMaterial( { color: 0xffffff } );
 							var mesh = new THREE.Mesh( geometry, material );
 							var mesh = new THREE.Mesh( geometry, material );
 
 
 							signals.objectAdded.dispatch( mesh );
 							signals.objectAdded.dispatch( mesh );
 							signals.objectSelected.dispatch( mesh );
 							signals.objectSelected.dispatch( mesh );
 
 
-							break;
+						} else if ( data.metadata.type === 'scene' ) {
 
 
-					}
+							new THREE.SceneLoader().parse( data, function ( scene ) {
 
 
-				};
+								signals.objectAdded.dispatch( scene );
+								signals.objectSelected.dispatch( scene );
 
 
-				reader.readAsText( file );
+							}, '' );
 
 
-			}, false );
+						}
 
 
+						break;
 
 
-			//
+					case 'obj':
+
+						var object = new THREE.OBJLoader().parse( contents );
+
+						signals.objectAdded.dispatch( object );
+						signals.objectSelected.dispatch( object );
+
+						break;
+
+					case 'stl':
+
+						var geometry = new THREE.STLLoader().parse( contents );
+						var material = new THREE.MeshLambertMaterial();
+
+						var mesh = new THREE.Mesh( geometry, material );
+
+						signals.objectAdded.dispatch( mesh );
+						signals.objectSelected.dispatch( mesh );
+
+						break;
+
+					case 'utf8':
+
+						var geometry = new THREE.UTF8Loader().parse( contents );
+						var material = new THREE.MeshLambertMaterial();
+
+						var mesh = new THREE.Mesh( geometry, material );
+
+						signals.objectAdded.dispatch( mesh );
+						signals.objectSelected.dispatch( mesh );
+
+						break;
+
+					case 'vtk':
+
+						var geometry = new THREE.VTKLoader().parse( contents );
+						var material = new THREE.MeshLambertMaterial();
+
+						var mesh = new THREE.Mesh( geometry, material );
+
+						signals.objectAdded.dispatch( mesh );
+						signals.objectSelected.dispatch( mesh );
+
+						break;
+
+				}
+
+			}
 
 
 			var geometry = new THREE.SphereGeometry( 75, 25, 15 );
 			var geometry = new THREE.SphereGeometry( 75, 25, 15 );
 			var material = new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } );
 			var material = new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } );
@@ -171,8 +225,6 @@
 			signals.objectAdded.dispatch( mesh );
 			signals.objectAdded.dispatch( mesh );
 			signals.objectSelected.dispatch( mesh );
 			signals.objectSelected.dispatch( mesh );
 
 
-			//
-
 			var onWindowResize = function ( event ) {
 			var onWindowResize = function ( event ) {
 
 
 				signals.windowResize.dispatch();
 				signals.windowResize.dispatch();

+ 48 - 22
gui/js/UI.js → editor/js/UI.js

@@ -283,7 +283,6 @@ UI.Select = function ( position ) {
 
 
 	this.dom.addEventListener( 'change', function ( event ) {
 	this.dom.addEventListener( 'change', function ( event ) {
 
 
-		// console.log( scope.dom.selectedIndex );
 		if ( scope.onChangeCallback ) scope.onChangeCallback();
 		if ( scope.onChangeCallback ) scope.onChangeCallback();
 
 
 	}, false );
 	}, false );
@@ -294,12 +293,27 @@ UI.Select = function ( position ) {
 
 
 UI.Select.prototype = Object.create( UI.Element.prototype );
 UI.Select.prototype = Object.create( UI.Element.prototype );
 
 
+UI.Select.prototype.setMultiple = function ( boolean ) {
+
+	this.dom.multiple = boolean;
+
+	return this;
+
+};
+
 UI.Select.prototype.setOptions = function ( options ) {
 UI.Select.prototype.setOptions = function ( options ) {
 
 
-	for ( var i = 0; i < options.length; i ++ ) {
+	while ( this.dom.children.length > 0 ) {
+
+		this.dom.removeChild( this.dom.firstChild );
+
+	}
+
+	for ( var key in options ) {
 
 
 		var option = document.createElement( 'option' );
 		var option = document.createElement( 'option' );
-		option.appendChild( document.createTextNode( options[ i ] ) );
+		option.value = key;
+		option.innerHTML = options[ key ];
 		this.dom.appendChild( option );
 		this.dom.appendChild( option );
 
 
 	}
 	}
@@ -330,30 +344,49 @@ UI.Select.prototype.onChange = function ( callback ) {
 
 
 };
 };
 
 
+// Checkbox
 
 
-// Boolean
+UI.Checkbox = function ( position ) {
 
 
-UI.Boolean = function ( position ) {
+	UI.Element.call( this );
 
 
-	UI.Select.call( this, position );
+	var scope = this;
 
 
-	this.setOptions( [ 'true', 'false' ] );
+	this.dom = document.createElement( 'input' );
+	this.dom.type = 'checkbox';
+	this.dom.style.position = position || 'relative';
+
+	this.onChangeCallback = null;
+
+	this.dom.addEventListener( 'change', function ( event ) {
+
+		if ( scope.onChangeCallback ) scope.onChangeCallback();
+
+	}, false );
 
 
 	return this;
 	return this;
 
 
 };
 };
 
 
-UI.Boolean.prototype = Object.create( UI.Select.prototype );
+UI.Checkbox.prototype = Object.create( UI.Element.prototype );
 
 
-UI.Boolean.prototype.getValue = function () {
+UI.Checkbox.prototype.getValue = function () {
 
 
-	return this.dom.value === 'true';
+	return this.dom.checked;
 
 
 };
 };
 
 
-UI.Boolean.prototype.setValue = function ( value ) {
+UI.Checkbox.prototype.setValue = function ( value ) {
 
 
-	this.dom.value = value.toString();
+	this.dom.checked = value;
+
+	return this;
+
+};
+
+UI.Checkbox.prototype.onChange = function ( callback ) {
+
+	this.onChangeCallback = callback;
 
 
 	return this;
 	return this;
 
 
@@ -507,17 +540,10 @@ UI.Number.prototype.setValue = function ( value ) {
 
 
 };
 };
 
 
-UI.Number.prototype.setMin = function ( value ) {
-
-	this.min = value;
-
-	return this;
-
-};
-
-UI.Number.prototype.setMax = function ( value ) {
+UI.Number.prototype.setRange = function ( min, max ) {
 
 
-	this.max = value;
+	this.min = min;
+	this.max = max;
 
 
 	return this;
 	return this;
 
 

+ 0 - 0
gui/js/libs/signals.min.js → editor/js/libs/signals.min.js


+ 0 - 0
gui/js/ui/Menubar.js → editor/js/ui/Menubar.js


+ 98 - 0
editor/js/ui/Sidebar.Outliner.js

@@ -0,0 +1,98 @@
+Sidebar.Outliner = function ( signals ) {
+
+	var objects = {
+
+		'PerspectiveCamera': THREE.PerspectiveCamera,
+		'PointLight': THREE.PointLight,
+		'DirectionalLight': THREE.DirectionalLight,
+		'Mesh': THREE.Mesh,
+		'Object3D': THREE.Object3D
+
+	};
+
+	var selected = null;
+
+	var container = new UI.Panel();
+	container.setPadding( '8px' );
+	container.setBorderTop( '1px solid #ccc' );
+
+	container.add( new UI.Text().setValue( 'SCENE' ).setColor( '#666' ) );
+	container.add( new UI.Break(), new UI.Break() );
+
+	var sceneGraph = new UI.Select().setMultiple( true ).setWidth( '100%' ).setHeight('140px').setColor( '#444' ).setFontSize( '12px' ).onChange( update );
+	container.add( sceneGraph );
+
+	container.add( new UI.Break(), new UI.Break() );
+
+	var scene = null;
+
+	function update() {
+
+		var id = parseInt( sceneGraph.getValue() );
+
+		for ( var i in scene.children ) {
+
+			var object = scene.children[ i ];
+
+			if ( object.id === id ) {
+
+				signals.objectSelected.dispatch( object );
+				return;
+
+			}
+
+		}
+
+	}
+
+	function getObjectInstanceName( object ) {
+
+		for ( var key in objects ) {
+
+			if ( object instanceof objects[ key ] ) return key;
+
+		}
+
+	}
+
+	// events
+
+	signals.sceneCreated.add( function ( object ) {
+
+		scene = object;
+
+	} );
+
+	signals.sceneChanged.add( function ( object ) {
+
+		scene = object;
+
+		var options = {};
+
+		( function createList( object, pad ) {
+
+			for ( var key in object.children ) {
+
+				var child = object.children[ key ];
+
+				options[ child.id ] = pad + '+ ' + object.name + ' [' + getObjectInstanceName( child ) + ']';
+
+				createList( child, pad + '&nbsp;&nbsp;&nbsp;' );
+
+			}
+
+		} )( scene, '' );
+
+		sceneGraph.setOptions( options );
+
+	} );
+
+	signals.objectSelected.add( function ( object ) {
+
+		sceneGraph.setValue( object !== null ? object.id: null );
+
+	} );
+
+	return container;
+
+}

+ 59 - 37
gui/js/ui/Sidebar.Properties.Geometry.js → editor/js/ui/Sidebar.Properties.Geometry.js

@@ -1,5 +1,27 @@
 Sidebar.Properties.Geometry = function ( signals ) {
 Sidebar.Properties.Geometry = function ( signals ) {
 
 
+	var geometries = {
+
+		"ConvexGeometry": THREE.ConvexGeometry,
+		"CubeGeometry": THREE.CubeGeometry,
+		"CylinderGeometry": THREE.CylinderGeometry,
+		"ExtrudeGeometry": THREE.ExtrudeGeometry,
+		"IcosahedronGeometry": THREE.IcosahedronGeometry,
+		"LatheGeometry": THREE.LatheGeometry,
+		"OctahedronGeometry": THREE.OctahedronGeometry,
+		"ParametricGeometry": THREE.ParametricGeometry,
+		"PlaneGeometry": THREE.PlaneGeometry,
+		"PolyhedronGeometry": THREE.PolyhedronGeometry,
+		"SphereGeometry": THREE.SphereGeometry,
+		"TetrahedronGeometry": THREE.TetrahedronGeometry,
+		"TextGeometry": THREE.TextGeometry,
+		"TorusGeometry": THREE.TorusGeometry,
+		"TorusKnotGeometry": THREE.TorusKnotGeometry,
+		"TubeGeometry": THREE.TubeGeometry,
+		"Geometry": THREE.Geometry
+
+	};
+
 	var container = new UI.Panel();
 	var container = new UI.Panel();
 	container.setDisplay( 'none' );
 	container.setDisplay( 'none' );
 
 
@@ -7,24 +29,46 @@ Sidebar.Properties.Geometry = function ( signals ) {
 	container.add( new UI.Button( 'absolute' ).setRight( '0px' ).setLabel( 'Export' ).onClick( exportGeometry ) );
 	container.add( new UI.Button( 'absolute' ).setRight( '0px' ).setLabel( 'Export' ).onClick( exportGeometry ) );
 	container.add( new UI.Break(), new UI.Break() );
 	container.add( new UI.Break(), new UI.Break() );
 
 
-	container.add( new UI.Text().setValue( 'Name' ).setColor( '#666' ) );
+	// name
+
+	var geometryNameRow = new UI.Panel();
 	var geometryName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
 	var geometryName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
-	container.add( geometryName );
-	container.add( new UI.HorizontalRule() );
 
 
-	container.add( new UI.Text().setValue( 'Class' ).setColor( '#666' ) );
+	geometryNameRow.add( new UI.Text().setValue( 'Name' ).setColor( '#666' ) );
+	geometryNameRow.add( geometryName );
+
+	container.add( geometryNameRow );
+
+	// class
+
+	var geometryClassRow = new UI.Panel();
 	var geometryClass = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
 	var geometryClass = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
-	container.add( geometryClass );
-	container.add( new UI.HorizontalRule() );
 
 
-	container.add( new UI.Text().setValue( 'Vertices' ).setColor( '#666' ) );
-	var verticesCount = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
-	container.add( verticesCount );
-	container.add( new UI.HorizontalRule() );
+	geometryClassRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Class' ).setColor( '#666' ) );
+	geometryClassRow.add( geometryClass );
+
+	container.add( geometryClassRow );
+
+	// vertices
+
+	var geometryVerticesRow = new UI.Panel();
+	var geometryVertices = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	geometryVerticesRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Vertices' ).setColor( '#666' ) );
+	geometryVerticesRow.add( geometryVertices );
+
+	container.add( geometryVerticesRow );
+
+	// faces
+
+	var geometryFacesRow = new UI.Panel();
+	var geometryFaces = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	geometryFacesRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Faces' ).setColor( '#666' ) );
+	geometryFacesRow.add( geometryFaces );
+
+	container.add( geometryFacesRow );
 
 
-	container.add( new UI.Text().setValue( 'Faces' ).setColor( '#666' ) );
-	var facesCount = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
-	container.add( facesCount );
 	container.add( new UI.Break(), new UI.Break(), new UI.Break() );
 	container.add( new UI.Break(), new UI.Break(), new UI.Break() );
 
 
 	//
 	//
@@ -41,8 +85,8 @@ Sidebar.Properties.Geometry = function ( signals ) {
 
 
 			geometryName.setValue( object.geometry.name );
 			geometryName.setValue( object.geometry.name );
 			geometryClass.setValue( getGeometryInstanceName( object.geometry ) );
 			geometryClass.setValue( getGeometryInstanceName( object.geometry ) );
-			verticesCount.setValue( object.geometry.vertices.length );
-			facesCount.setValue( object.geometry.faces.length );
+			geometryVertices.setValue( object.geometry.vertices.length );
+			geometryFaces.setValue( object.geometry.faces.length );
 
 
 		} else {
 		} else {
 
 
@@ -56,28 +100,6 @@ Sidebar.Properties.Geometry = function ( signals ) {
 
 
 	function getGeometryInstanceName( geometry ) {
 	function getGeometryInstanceName( geometry ) {
 
 
-		var geometries = {
-
-			"ConvexGeometry": THREE.ConvexGeometry,
-			"CubeGeometry": THREE.CubeGeometry,
-			"CylinderGeometry": THREE.CylinderGeometry,
-			"ExtrudeGeometry": THREE.ExtrudeGeometry,
-			"IcosahedronGeometry": THREE.IcosahedronGeometry,
-			"LatheGeometry": THREE.LatheGeometry,
-			"OctahedronGeometry": THREE.OctahedronGeometry,
-			"ParametricGeometry": THREE.ParametricGeometry,
-			"PlaneGeometry": THREE.PlaneGeometry,
-			"PolyhedronGeometry": THREE.PolyhedronGeometry,
-			"SphereGeometry": THREE.SphereGeometry,
-			"TetrahedronGeometry": THREE.TetrahedronGeometry,
-			"TextGeometry": THREE.TextGeometry,
-			"TorusGeometry": THREE.TorusGeometry,
-			"TorusKnotGeometry": THREE.TorusKnotGeometry,
-			"TubeGeometry": THREE.TubeGeometry,
-			"Geometry": THREE.Geometry
-
-		};
-
 		for ( var key in geometries ) {
 		for ( var key in geometries ) {
 
 
 			if ( geometry instanceof geometries[ key ] ) return key;
 			if ( geometry instanceof geometries[ key ] ) return key;

+ 401 - 0
editor/js/ui/Sidebar.Properties.Material.js

@@ -0,0 +1,401 @@
+Sidebar.Properties.Material = function ( signals ) {
+
+	var materials = {
+
+		'LineBasicMaterial': THREE.LineBasicMaterial,
+		'MeshBasicMaterial': THREE.MeshBasicMaterial,
+		'MeshDepthMaterial': THREE.MeshDepthMaterial,
+		'MeshFaceMaterial': THREE.MeshFaceMaterial,
+		'MeshLambertMaterial': THREE.MeshLambertMaterial,
+		'MeshNormalMaterial': THREE.MeshNormalMaterial,
+		'MeshPhongMaterial': THREE.MeshPhongMaterial,
+		'ParticleBasicMaterial': THREE.ParticleBasicMaterial,
+		'ParticleCanvasMaterial': THREE.ParticleCanvasMaterial,
+		'ParticleDOMMaterial': THREE.ParticleDOMMaterial,
+		'ShaderMaterial': THREE.ShaderMaterial,
+		'Material': THREE.Material
+
+	};
+
+	var container = new UI.Panel();
+	container.setDisplay( 'none' );
+
+	container.add( new UI.Text().setValue( 'MATERIAL' ).setColor( '#666' ) );
+	container.add( new UI.Break(), new UI.Break() );
+
+	// name
+
+	var materialNameRow = new UI.Panel();
+	var materialName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	materialNameRow.add( new UI.Text().setValue( 'Name' ).setColor( '#666' ) );
+	materialNameRow.add( materialName );
+
+	container.add( materialNameRow );
+
+	// class
+
+	var materialClassRow = new UI.Panel();
+	var materialClass = new UI.Select( 'absolute' ).setOptions( {
+
+		'LineBasicMaterial': 'LineBasicMaterial',
+		'MeshBasicMaterial': 'MeshBasicMaterial',
+		'MeshDepthMaterial': 'MeshDepthMaterial',
+		'MeshFaceMaterial': 'MeshFaceMaterial',
+		'MeshLambertMaterial': 'MeshLambertMaterial',
+		'MeshNormalMaterial': 'MeshNormalMaterial',
+		'MeshPhongMaterial': 'MeshPhongMaterial'
+
+	} ).setLeft( '90px' ).setWidth( '180px' ).setColor( '#444' ).setFontSize( '12px' ).onChange( update );
+
+	materialClassRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Class' ).setColor( '#666' ) );
+	materialClassRow.add( materialClass );
+
+	container.add( materialClassRow );
+
+	// color
+
+	var materialColorRow = new UI.Panel();
+	var materialColor = new UI.Color( 'absolute' ).setLeft( '90px' ).onChange( update );
+
+	materialColorRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Color' ).setColor( '#666' ) );
+	materialColorRow.add( materialColor );
+
+	container.add( materialColorRow );
+
+	// ambient
+
+	var materialAmbientRow = new UI.Panel();
+	var materialAmbient = new UI.Color( 'absolute' ).setLeft( '90px' ).onChange( update );
+
+	materialAmbientRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Ambient' ).setColor( '#666' ) );
+	materialAmbientRow.add( materialAmbient );
+
+	container.add( materialAmbientRow );
+
+	// emissive
+
+	var materialEmissiveRow = new UI.Panel();
+	var materialEmissive = new UI.Color( 'absolute' ).setLeft( '90px' ).onChange( update );
+
+	materialEmissiveRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Emissive' ).setColor( '#666' ) );
+	materialEmissiveRow.add( materialEmissive );
+
+	container.add( materialEmissiveRow );
+
+	// specular
+
+	var materialSpecularRow = new UI.Panel();
+	var materialSpecular = new UI.Color( 'absolute' ).setLeft( '90px' ).onChange( update );
+
+	materialSpecularRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Specular' ).setColor( '#666' ) );
+	materialSpecularRow.add( materialSpecular );
+
+	container.add( materialSpecularRow );
+
+	// shininess
+
+	var materialShininessRow = new UI.Panel();
+	var materialShininess = new UI.Number( 'absolute' ).setValue( 30 ).setLeft( '90px' ).onChange( update );
+
+	materialShininessRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Shininess' ).setColor( '#666' ) );
+	materialShininessRow.add( materialShininess );
+
+	container.add( materialShininessRow );
+
+	// map
+
+	var materialMapRow = new UI.Panel();
+	var materialMap = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	materialMapRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Map' ).setColor( '#666' ) );
+	materialMapRow.add( materialMap );
+
+	container.add( materialMapRow );
+
+	// light map
+
+	var materialLightMapRow = new UI.Panel();
+	var materialLightMap = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	materialLightMapRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Light Map' ).setColor( '#666' ) );
+	materialLightMapRow.add( materialLightMap );
+
+	container.add( materialLightMapRow );
+
+	// bump map
+
+	var materialBumpMapRow = new UI.Panel();
+	var materialBumpMap = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	materialBumpMapRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Bump Map' ).setColor( '#666' ) );
+	materialBumpMapRow.add( materialBumpMap );
+
+	container.add( materialBumpMapRow );
+
+	// normal map
+
+	var materialNormalMapRow = new UI.Panel();
+	var materialNormalMap = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	materialNormalMapRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Normal Map' ).setColor( '#666' ) );
+	materialNormalMapRow.add( materialNormalMap );
+
+	container.add( materialNormalMapRow );
+
+	// specular map
+
+	var materialSpecularMapRow = new UI.Panel();
+	var materialSpecularMap = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	materialSpecularMapRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Specular Map' ).setColor( '#666' ) );
+	materialSpecularMapRow.add( materialSpecularMap );
+
+	container.add( materialSpecularMapRow );
+
+	// env map
+
+	var materialEnvMapRow = new UI.Panel();
+	var materialEnvMap = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
+
+	materialEnvMapRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Env Map' ).setColor( '#666' ) );
+	materialEnvMapRow.add( materialEnvMap );
+
+	container.add( materialEnvMapRow );
+
+	// opacity
+
+	var materialOpacityRow = new UI.Panel();
+	var materialOpacity = new UI.Number( 'absolute' ).setLeft( '90px' ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update );
+
+	materialOpacityRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Opacity' ).setColor( '#666' ) );
+	materialOpacityRow.add( materialOpacity );
+
+	container.add( materialOpacityRow );
+
+	// transparent
+
+	var materialTransparentRow = new UI.Panel();
+	var materialTransparent = new UI.Checkbox( 'absolute' ).setValue( false ).setLeft( '90px' ).onChange( update );
+
+	materialTransparentRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Transparent' ).setColor( '#666' ) );
+	materialTransparentRow.add( materialTransparent );
+
+	container.add( materialTransparentRow );
+
+	// wireframe
+
+	var materialWireframeRow = new UI.Panel();
+	var materialWireframe = new UI.Checkbox( 'absolute' ).setValue( false ).setLeft( '90px' ).onChange( update );
+	var materialWireframeLinewidth = new UI.Number( 'absolute' ).setValue( 1 ).setLeft( '120px' ).setRange( 0, 100 ).onChange( update );
+
+	materialWireframeRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Wireframe' ).setColor( '#666' ) );
+	materialWireframeRow.add( materialWireframe );
+	materialWireframeRow.add( materialWireframeLinewidth );
+
+	container.add( materialWireframeRow );
+
+
+
+	//
+
+	var selected = null;
+
+	function update() {
+
+		var material = selected.material;
+
+		if ( material ) {
+
+			if ( material instanceof materials[ materialClass.getValue() ] == false ) {
+
+				material = new materials[ materialClass.getValue() ]();
+				selected.material = material;
+
+			}
+
+			if ( material.color !== undefined ) {
+
+				material.color.setHex( parseInt( materialColor.getValue().substr( 1 ), 16 ) );
+
+			}
+
+			if ( material.ambient !== undefined ) {
+
+				material.ambient.setHex( parseInt( materialAmbient.getValue().substr( 1 ), 16 ) );
+
+			}
+
+			if ( material.emissive !== undefined ) {
+
+				material.emissive.setHex( parseInt( materialEmissive.getValue().substr( 1 ), 16 ) );
+
+			}
+
+			if ( material.specular !== undefined ) {
+
+				material.specular.setHex( parseInt( materialSpecular.getValue().substr( 1 ), 16 ) );
+
+			}
+
+			if ( material.shininess !== undefined ) {
+
+				material.shininess = materialShininess.getValue();
+
+			}
+
+			if ( material.opacity !== undefined ) {
+
+				material.opacity = materialOpacity.getValue();
+
+			}
+
+			if ( material.transparent !== undefined ) {
+
+				material.transparent = materialTransparent.getValue();
+
+			}
+
+			if ( material.wireframe !== undefined ) {
+
+				material.wireframe = materialWireframe.getValue();
+
+			}
+
+			if ( material.wireframeLinewidth !== undefined ) {
+
+				material.wireframeLinewidth = materialWireframeLinewidth.getValue();
+
+			}
+
+			updateRows();
+
+			signals.materialChanged.dispatch( material );
+
+		}
+
+	};
+
+	function updateRows() {
+
+		var material = selected.material;
+
+		materialColorRow.setDisplay( material.color !== undefined ? '' : 'none' );
+		materialAmbientRow.setDisplay( material.ambient !== undefined ? '' : 'none' );
+		materialEmissiveRow.setDisplay( material.emissive !== undefined ? '' : 'none' );
+		materialSpecularRow.setDisplay( material.specular !== undefined ? '' : 'none' );
+		materialShininessRow.setDisplay( material.shininess !== undefined ? '' : 'none' );
+		materialMapRow.setDisplay( material.map !== undefined ? '' : 'none' );
+		materialLightMapRow.setDisplay( material.lightMap !== undefined ? '' : 'none' );
+		materialBumpMapRow.setDisplay( material.bumpMap !== undefined ? '' : 'none' );
+		materialNormalMapRow.setDisplay( material.normalMap !== undefined ? '' : 'none' );
+		materialSpecularMapRow.setDisplay( material.specularMap !== undefined ? '' : 'none' );
+		materialEnvMapRow.setDisplay( material.envMap !== undefined ? '' : 'none' );
+		materialOpacityRow.setDisplay( material.opacity !== undefined ? '' : 'none' );
+		materialTransparentRow.setDisplay( material.transparent !== undefined ? '' : 'none' );
+		materialWireframeRow.setDisplay( material.wireframe !== undefined ? '' : 'none' );
+
+	};
+
+	function getMaterialInstanceName( material ) {
+
+		for ( var key in materials ) {
+
+			if ( material instanceof materials[ key ] ) return key;
+
+		}
+
+	}
+
+	// events
+
+	signals.objectSelected.add( function ( object ) {
+
+		if ( object && object.material ) {
+
+			selected = object;
+
+			container.setDisplay( '' );
+
+			var material = object.material;
+
+			materialName.setValue( material.name );
+			materialClass.setValue( getMaterialInstanceName( material ) );
+
+			if ( material.color !== undefined ) {
+
+				materialColor.setValue( '#' + material.color.getHex().toString( 16 ) );
+
+			}
+
+			if ( material.ambient !== undefined ) {
+
+				materialAmbient.setValue( '#' + material.ambient.getHex().toString( 16 ) );
+
+			}
+
+			if ( material.emissive !== undefined ) {
+
+				materialEmissive.setValue( '#' + material.emissive.getHex().toString( 16 ) );
+
+			}
+
+			if ( material.specular !== undefined ) {
+
+				materialSpecular.setValue( '#' + material.specular.getHex().toString( 16 ) );
+
+			}
+
+			if ( material.shininess !== undefined ) {
+
+				materialShininess.setValue( material.shininess );
+
+			}
+
+			/*
+			if ( material.map !== undefined ) {
+
+				materialMap.setValue( material.map );
+
+			}
+			*/
+
+			if ( material.opacity !== undefined ) {
+
+				materialOpacity.setValue( material.opacity );
+
+			}
+
+			if ( material.transparent !== undefined ) {
+
+				materialTransparent.setValue( material.transparent );
+
+			}
+
+			if ( material.wireframe !== undefined ) {
+
+				materialWireframe.setValue( material.wireframe );
+
+			}
+
+			if ( material.wireframeLinewidth !== undefined ) {
+
+				materialWireframeLinewidth.setValue( material.wireframeLinewidth );
+
+			}
+
+			updateRows();
+
+		} else {
+
+			selected = null;
+
+			container.setDisplay( 'none' );
+
+		}
+
+	} );
+
+	return container;
+
+}

+ 154 - 0
editor/js/ui/Sidebar.Properties.Object3D.js

@@ -0,0 +1,154 @@
+Sidebar.Properties.Object3D = function ( signals ) {
+
+	var objects = {
+
+		'PerspectiveCamera': THREE.PerspectiveCamera,
+		'PointLight': THREE.PointLight,
+		'DirectionalLight': THREE.DirectionalLight,
+		'Mesh': THREE.Mesh,
+		'Object3D': THREE.Object3D
+
+	};
+
+	var container = new UI.Panel();
+	container.setDisplay( 'none' );
+
+	var objectType = new UI.Text().setColor( '#666' );
+	container.add( objectType );
+	container.add( new UI.Break(), new UI.Break() );
+
+	// name
+
+	var objectNameRow = new UI.Panel();
+	var objectName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' );
+
+	objectNameRow.add( new UI.Text().setValue( 'Name' ).setColor( '#666' ) );
+	objectNameRow.add( objectName );
+
+	container.add( objectNameRow );
+
+	// position
+
+	var objectPositionRow = new UI.Panel();
+	var objectPositionX = new UI.Number( 'absolute' ).setLeft( '90px' ).setWidth( '50px' ).onChange( update );
+	var objectPositionY = new UI.Number( 'absolute' ).setLeft( '150px' ).setWidth( '50px' ).onChange( update );
+	var objectPositionZ = new UI.Number( 'absolute' ).setLeft( '210px' ).setWidth( '50px' ).onChange( update );
+
+	objectPositionRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Position' ).setColor( '#666' ) );
+	objectPositionRow.add( objectPositionX, objectPositionY, objectPositionZ );
+
+	container.add( objectPositionRow );
+
+	// rotation
+
+	var objectRotationRow = new UI.Panel();
+	var objectRotationX = new UI.Number( 'absolute' ).setLeft( '90px' ).setWidth( '50px' ).onChange( update );
+	var objectRotationY = new UI.Number( 'absolute' ).setLeft( '150px' ).setWidth( '50px' ).onChange( update );
+	var objectRotationZ = new UI.Number( 'absolute' ).setLeft( '210px' ).setWidth( '50px' ).onChange( update );
+
+	objectRotationRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Rotation' ).setColor( '#666' ) );
+	objectRotationRow.add( objectRotationX, objectRotationY, objectRotationZ );
+
+	container.add( objectRotationRow );
+
+	// scale
+
+	var objectScaleRow = new UI.Panel();
+	var objectScaleX = new UI.Number( 'absolute' ).setValue( 1 ).setLeft( '90px' ).setWidth( '50px' ).onChange( update );
+	var objectScaleY = new UI.Number( 'absolute' ).setValue( 1 ).setLeft( '150px' ).setWidth( '50px' ).onChange( update );
+	var objectScaleZ = new UI.Number( 'absolute' ).setValue( 1 ).setLeft( '210px' ).setWidth( '50px' ).onChange( update );
+
+	objectScaleRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Scale' ).setColor( '#666' ) );
+	objectScaleRow.add( objectScaleX, objectScaleY, objectScaleZ );
+
+	container.add( objectScaleRow );
+
+	// visible
+
+	var objectVisibleRow = new UI.Panel();
+	var objectVisible = new UI.Checkbox( 'absolute' ).setLeft( '90px' ).onChange( update );
+
+	objectVisibleRow.add( new UI.HorizontalRule(), new UI.Text().setValue( 'Visible' ).setColor( '#666' ) );
+	objectVisibleRow.add( objectVisible );
+
+	container.add( objectVisibleRow );
+
+	container.add( new UI.Break(), new UI.Break() );
+
+	//
+
+	var selected = null;
+
+	function update() {
+
+		if ( selected ) {
+
+			selected.position.x = objectPositionX.getValue();
+			selected.position.y = objectPositionY.getValue();
+			selected.position.z = objectPositionZ.getValue();
+
+			selected.rotation.x = objectRotationX.getValue();
+			selected.rotation.y = objectRotationY.getValue();
+			selected.rotation.z = objectRotationZ.getValue();
+
+			selected.scale.x = objectScaleX.getValue();
+			selected.scale.y = objectScaleY.getValue();
+			selected.scale.z = objectScaleZ.getValue();
+
+			selected.visible = objectVisible.getValue();
+
+			signals.objectChanged.dispatch( selected );
+
+		}
+
+	}
+
+	function getObjectInstanceName( object ) {
+
+		for ( var key in objects ) {
+
+			if ( object instanceof objects[ key ] ) return key;
+
+		}
+
+	}
+
+	// events
+
+	signals.objectSelected.add( function ( object ) {
+
+		selected = object;
+
+		if ( object ) {
+
+			container.setDisplay( 'block' );
+
+			objectType.setValue( getObjectInstanceName( object ).toUpperCase() );
+
+			objectName.setValue( object.name );
+
+			objectPositionX.setValue( object.position.x );
+			objectPositionY.setValue( object.position.y );
+			objectPositionZ.setValue( object.position.z );
+
+			objectRotationX.setValue( object.rotation.x );
+			objectRotationY.setValue( object.rotation.y );
+			objectRotationZ.setValue( object.rotation.z );
+
+			objectScaleX.setValue( object.scale.x );
+			objectScaleY.setValue( object.scale.y );
+			objectScaleZ.setValue( object.scale.z );
+
+			objectVisible.setValue( object.visible );
+
+		} else {
+
+			container.setDisplay( 'none' );
+
+		}
+
+	} );
+
+	return container;
+
+}

+ 0 - 0
gui/js/ui/Sidebar.Properties.js → editor/js/ui/Sidebar.Properties.js


+ 0 - 0
gui/js/ui/Sidebar.js → editor/js/ui/Sidebar.js


+ 9 - 11
gui/js/ui/Viewport.js → editor/js/ui/Viewport.js

@@ -69,6 +69,7 @@ var Viewport = function ( signals ) {
 	light.position.set( - 1, - 0.5, 0 ).normalize();
 	light.position.set( - 1, - 0.5, 0 ).normalize();
 	scene.add( light );
 	scene.add( light );
 
 
+	signals.sceneChanged.dispatch( scene );
 
 
 	// object picking
 	// object picking
 
 
@@ -86,7 +87,7 @@ var Viewport = function ( signals ) {
 		projector.unprojectVector( vector, camera );
 		projector.unprojectVector( vector, camera );
 
 
 		var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
 		var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
-		var intersects = ray.intersectObjects( objects );
+		var intersects = ray.intersectObjects( objects, true );
 
 
 		if ( intersects.length ) {
 		if ( intersects.length ) {
 
 
@@ -117,26 +118,23 @@ var Viewport = function ( signals ) {
 		scene.add( object );
 		scene.add( object );
 		render();
 		render();
 
 
+		signals.sceneChanged.dispatch( scene );
+
 	} );
 	} );
 
 
 	signals.objectChanged.add( function ( object ) {
 	signals.objectChanged.add( function ( object ) {
 
 
-		object.updateMatrix();
-		object.updateMatrixWorld();
-
-		selectionBox.matrixWorld.copy( object.matrixWorld );
-
 		render();
 		render();
 
 
 	} );
 	} );
 
 
-	signals.objectSelected.add( function ( object ) {
+	var selected = null;
 
 
-		if ( object === null ) {
+	signals.objectSelected.add( function ( object ) {
 
 
-			selectionBox.visible = false;
+		selectionBox.visible = false;
 
 
-		} else if ( object.geometry ) {
+		if ( object !== null && object.geometry ) {
 
 
 			var geometry = object.geometry;
 			var geometry = object.geometry;
 
 
@@ -182,7 +180,7 @@ var Viewport = function ( signals ) {
 
 
 			selectionBox.geometry.verticesNeedUpdate = true;
 			selectionBox.geometry.verticesNeedUpdate = true;
 
 
-			selectionBox.matrixWorld.copy( object.matrixWorld );
+			selectionBox.matrixWorld = object.matrixWorld;
 
 
 			selectionBox.visible = true;
 			selectionBox.visible = true;
 
 

+ 12 - 9
examples/canvas_geometry_earth.html

@@ -84,20 +84,23 @@
 
 
 				// shadow
 				// shadow
 
 
-				var shadowTexture = new THREE.Texture();
-				var loader = new THREE.ImageLoader();
-
-				loader.addEventListener( 'load', function ( event ) {
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 128;
+				canvas.height = 128;
 
 
-					shadowTexture.image = event.content;
-					shadowTexture.needsUpdate = true;
+				var context = canvas.getContext( '2d' );
+				var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
+				gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
+				gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
 
 
-				} );
+				context.fillStyle = gradient;
+				context.fillRect( 0, 0, canvas.width, canvas.height );
 
 
-				loader.load( 'textures/shadow.png' );
+				var texture = new THREE.Texture( canvas );
+				texture.needsUpdate = true;
 
 
 				var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
 				var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
-				var material = new THREE.MeshBasicMaterial( { map: shadowTexture, overdraw: true } );
+				var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
 
 
 				var mesh = new THREE.Mesh( geometry, material );
 				var mesh = new THREE.Mesh( geometry, material );
 				mesh.position.y = - 250;
 				mesh.position.y = - 250;

+ 408 - 0
examples/canvas_geometry_shapes.html

@@ -0,0 +1,408 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js canvas - geometry - shapes</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: #f0f0f0;
+				margin: 0px;
+				overflow: hidden;
+			}
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				padding: 5px;
+				text-align:center;
+			}
+		</style>
+	</head>
+	<body>
+		<canvas id="debug" style="position:absolute; left:100px"></canvas>
+
+		<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - shape geometry</div>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/Stats.js"></script>
+
+		<script>
+
+			var container, stats;
+
+			var camera, scene, renderer;
+
+			var text, plane;
+
+			var targetRotation = 0;
+			var targetRotationOnMouseDown = 0;
+
+			var mouseX = 0;
+			var mouseXOnMouseDown = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 0, 150, 500 );
+
+				scene = new THREE.Scene();
+
+				parent = new THREE.Object3D();
+				parent.position.y = 50;
+				scene.add( parent );
+
+				function addShape( shape, color, x, y, z, rx, ry, rz, s ) {
+
+					// flat shape
+
+					var geometry = new THREE.ShapeGeometry( shape );
+					var material = new THREE.MeshBasicMaterial( { color: color, side: THREE.DoubleSide, overdraw: true } );
+
+					var mesh = new THREE.Mesh( geometry, material );
+					mesh.position.set( x, y, z );
+					mesh.rotation.set( rx, ry, rz );
+					mesh.scale.set( s, s, s );
+					parent.add( mesh );
+
+					// line
+
+					var geometry = shape.createPointsGeometry();
+					var material = new THREE.LineBasicMaterial( { linewidth: 10, color: 0x333333, transparent: true } );
+
+					var line = new THREE.Line( geometry, material );
+					line.position.set( x, y, z );
+					line.rotation.set( rx, ry, rz );
+					line.scale.set( s, s, s );
+					parent.add( line );
+
+				}
+
+
+				// California
+
+				var californiaPts = [];
+
+				californiaPts.push( new THREE.Vector2 ( 610, 320 ) );
+				californiaPts.push( new THREE.Vector2 ( 450, 300 ) );
+				californiaPts.push( new THREE.Vector2 ( 392, 392 ) );
+				californiaPts.push( new THREE.Vector2 ( 266, 438 ) );
+				californiaPts.push( new THREE.Vector2 ( 190, 570 ) );
+				californiaPts.push( new THREE.Vector2 ( 190, 600 ) );
+				californiaPts.push( new THREE.Vector2 ( 160, 620 ) );
+				californiaPts.push( new THREE.Vector2 ( 160, 650 ) );
+				californiaPts.push( new THREE.Vector2 ( 180, 640 ) );
+				californiaPts.push( new THREE.Vector2 ( 165, 680 ) );
+				californiaPts.push( new THREE.Vector2 ( 150, 670 ) );
+				californiaPts.push( new THREE.Vector2 (  90, 737 ) );
+				californiaPts.push( new THREE.Vector2 (  80, 795 ) );
+				californiaPts.push( new THREE.Vector2 (  50, 835 ) );
+				californiaPts.push( new THREE.Vector2 (  64, 870 ) );
+				californiaPts.push( new THREE.Vector2 (  60, 945 ) );
+				californiaPts.push( new THREE.Vector2 ( 300, 945 ) );
+				californiaPts.push( new THREE.Vector2 ( 300, 743 ) );
+				californiaPts.push( new THREE.Vector2 ( 600, 473 ) );
+				californiaPts.push( new THREE.Vector2 ( 626, 425 ) );
+				californiaPts.push( new THREE.Vector2 ( 600, 370 ) );
+				californiaPts.push( new THREE.Vector2 ( 610, 320 ) );
+
+				var californiaShape = new THREE.Shape( californiaPts );
+
+
+				// Triangle
+
+				var triangleShape = new THREE.Shape();
+				triangleShape.moveTo(  80, 20 );
+				triangleShape.lineTo(  40, 80 );
+				triangleShape.lineTo( 120, 80 );
+				triangleShape.lineTo(  80, 20 ); // close path
+
+
+				// Heart
+
+				var x = 0, y = 0;
+
+				var heartShape = new THREE.Shape(); // From http://blog.burlock.org/html5/130-paths
+
+				heartShape.moveTo( x + 25, y + 25 );
+				heartShape.bezierCurveTo( x + 25, y + 25, x + 20, y, x, y );
+				heartShape.bezierCurveTo( x - 30, y, x - 30, y + 35,x - 30,y + 35 );
+				heartShape.bezierCurveTo( x - 30, y + 55, x - 10, y + 77, x + 25, y + 95 );
+				heartShape.bezierCurveTo( x + 60, y + 77, x + 80, y + 55, x + 80, y + 35 );
+				heartShape.bezierCurveTo( x + 80, y + 35, x + 80, y, x + 50, y );
+				heartShape.bezierCurveTo( x + 35, y, x + 25, y + 25, x + 25, y + 25 );
+
+
+				// Square
+
+				var sqLength = 80;
+
+				var squareShape = new THREE.Shape();
+				squareShape.moveTo( 0,0 );
+				squareShape.lineTo( 0, sqLength );
+				squareShape.lineTo( sqLength, sqLength );
+				squareShape.lineTo( sqLength, 0 );
+				squareShape.lineTo( 0, 0 );
+
+
+				// Rectangle
+
+				var rectLength = 120, rectWidth = 40;
+
+				var rectShape = new THREE.Shape();
+				rectShape.moveTo( 0,0 );
+				rectShape.lineTo( 0, rectWidth );
+				rectShape.lineTo( rectLength, rectWidth );
+				rectShape.lineTo( rectLength, 0 );
+				rectShape.lineTo( 0, 0 );
+
+
+				// Rounded rectangle
+
+				var roundedRectShape = new THREE.Shape();
+
+				( function roundedRect( ctx, x, y, width, height, radius ){
+
+					ctx.moveTo( x, y + radius );
+					ctx.lineTo( x, y + height - radius );
+					ctx.quadraticCurveTo( x, y + height, x + radius, y + height );
+					ctx.lineTo( x + width - radius, y + height) ;
+					ctx.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
+					ctx.lineTo( x + width, y + radius );
+					ctx.quadraticCurveTo( x + width, y, x + width - radius, y );
+					ctx.lineTo( x + radius, y );
+					ctx.quadraticCurveTo( x, y, x, y + radius );
+
+				} )( roundedRectShape, 0, 0, 50, 50, 20 );
+
+
+				// Circle
+
+				var circleRadius = 40;
+				var circleShape = new THREE.Shape();
+				circleShape.moveTo( 0, circleRadius );
+				circleShape.quadraticCurveTo( circleRadius, circleRadius, circleRadius, 0 );
+				circleShape.quadraticCurveTo( circleRadius, -circleRadius, 0, -circleRadius );
+				circleShape.quadraticCurveTo( -circleRadius, -circleRadius, -circleRadius, 0 );
+				circleShape.quadraticCurveTo( -circleRadius, circleRadius, 0, circleRadius );
+
+
+				// Fish
+
+				x = y = 0;
+
+				var fishShape = new THREE.Shape();
+
+				fishShape.moveTo(x,y);
+				fishShape.quadraticCurveTo(x + 50, y - 80, x + 90, y - 10);
+				fishShape.quadraticCurveTo(x + 100, y - 10, x + 115, y - 40);
+				fishShape.quadraticCurveTo(x + 115, y, x + 115, y + 40);
+				fishShape.quadraticCurveTo(x + 100, y + 10, x + 90, y + 10);
+				fishShape.quadraticCurveTo(x + 50, y + 80, x, y);
+
+
+				// Arc circle
+
+				var arcShape = new THREE.Shape();
+				arcShape.moveTo( 50, 10 );
+				arcShape.absarc( 10, 10, 40, 0, Math.PI*2, false );
+
+				var holePath = new THREE.Path();
+				holePath.moveTo( 20, 10 );
+				holePath.absarc( 10, 10, 10, 0, Math.PI*2, true );
+				arcShape.holes.push( holePath );
+
+
+				// Smiley
+
+				var smileyShape = new THREE.Shape();
+				smileyShape.moveTo( 80, 40 );
+				smileyShape.absarc( 40, 40, 40, 0, Math.PI*2, false );
+
+				var smileyEye1Path = new THREE.Path();
+				smileyEye1Path.moveTo( 35, 20 );
+				// smileyEye1Path.absarc( 25, 20, 10, 0, Math.PI*2, true );
+				smileyEye1Path.absellipse( 25, 20, 10, 10, 0, Math.PI*2, true );
+
+				smileyShape.holes.push( smileyEye1Path );
+
+				var smileyEye2Path = new THREE.Path();
+				smileyEye2Path.moveTo( 65, 20 );
+				smileyEye2Path.absarc( 55, 20, 10, 0, Math.PI*2, true );
+				smileyShape.holes.push( smileyEye2Path );
+
+				var smileyMouthPath = new THREE.Path();
+				// ugly box mouth
+				// smileyMouthPath.moveTo( 20, 40 );
+				// smileyMouthPath.lineTo( 60, 40 );
+				// smileyMouthPath.lineTo( 60, 60 );
+				// smileyMouthPath.lineTo( 20, 60 );
+				// smileyMouthPath.lineTo( 20, 40 );
+
+				smileyMouthPath.moveTo( 20, 40 );
+				smileyMouthPath.quadraticCurveTo( 40, 60, 60, 40 );
+				smileyMouthPath.bezierCurveTo( 70, 45, 70, 50, 60, 60 );
+				smileyMouthPath.quadraticCurveTo( 40, 80, 20, 60 );
+				smileyMouthPath.quadraticCurveTo( 5, 50, 20, 40 );
+
+				smileyShape.holes.push( smileyMouthPath );
+
+
+				// Spline shape + path extrusion
+
+				var splinepts = [];
+				splinepts.push( new THREE.Vector2 ( 350, 100 ) );
+				splinepts.push( new THREE.Vector2 ( 400, 450 ) );
+				splinepts.push( new THREE.Vector2 ( -140, 350 ) );
+				splinepts.push( new THREE.Vector2 ( 0, 0 ) );
+
+				var splineShape = new THREE.Shape(  );
+				splineShape.moveTo( 0, 0 );
+				splineShape.splineThru( splinepts );
+
+
+				// addShape( shape, color, x, y, z, rx, ry,rz, s );
+
+				addShape( californiaShape, 0xffaa00, -300, -100, 0, 0, 0, 0, 0.25 );
+				addShape( triangleShape, 0xffee00, -180, 0, 0, 0, 0, 0, 1 );
+				addShape( roundedRectShape, 0x005500, -150, 150, 0, 0, 0, 0, 1 );
+				addShape( squareShape, 0x0055ff, 150, 100, 0, 0, 0, 0, 1 );
+				addShape( heartShape, 0xff1100, 0, 100, 0, Math.PI, 0, 0, 1 );
+				addShape( circleShape, 0x00ff11, 120, 250, 0, 0, 0, 0, 1 );
+				addShape( fishShape, 0x222222, -60, 200, 0, 0, 0, 0, 1 );
+				addShape( smileyShape, 0xee00ff, -270, 250, 0, Math.PI, 0, 0, 1 );
+				addShape( arcShape, 0xbb4422, 150, 0, 0, 0, 0, 0, 1 );
+				addShape( splineShape, 0x888888, -50, -100, 0, 0, 0, 0, 0.2 );
+
+				//
+
+				renderer = new THREE.CanvasRenderer( { antialias: true } );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.sortObjects = false;
+				renderer.sortElements = false;
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
+				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
+				document.addEventListener( 'touchmove', onDocumentTouchMove, false );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			//
+
+			function onDocumentMouseDown( event ) {
+
+				event.preventDefault();
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.addEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.addEventListener( 'mouseout', onDocumentMouseOut, false );
+
+				mouseXOnMouseDown = event.clientX - windowHalfX;
+				targetRotationOnMouseDown = targetRotation;
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = event.clientX - windowHalfX;
+
+				targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
+
+			}
+
+			function onDocumentMouseUp( event ) {
+
+				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+
+			}
+
+			function onDocumentMouseOut( event ) {
+
+				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+
+			}
+
+			function onDocumentTouchStart( event ) {
+
+				if ( event.touches.length == 1 ) {
+
+					event.preventDefault();
+
+					mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
+					targetRotationOnMouseDown = targetRotation;
+
+				}
+
+			}
+
+			function onDocumentTouchMove( event ) {
+
+				if ( event.touches.length == 1 ) {
+
+					event.preventDefault();
+
+					mouseX = event.touches[ 0 ].pageX - windowHalfX;
+					targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
+
+				}
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				parent.rotation.y += ( targetRotation - parent.rotation.y ) * 0.05;
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 4 - 1
examples/canvas_geometry_terrain.html

@@ -65,7 +65,10 @@
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
 
 
 				var data = generateHeight( 1024, 1024 );
 				var data = generateHeight( 1024, 1024 );
-				var material = new THREE.MeshBasicMaterial( { map: new THREE.Texture( generateTexture( data, 1024, 1024 ) ), overdraw: true } );
+				var texture = new THREE.Texture( generateTexture( data, 1024, 1024 ) );
+				texture.needsUpdate = true;
+
+				var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
 
 
 				var quality = 16, step = 1024 / quality;
 				var quality = 16, step = 1024 / quality;
 
 

+ 1 - 1
examples/canvas_materials_depth.html

@@ -71,7 +71,7 @@
 				// Cubes
 				// Cubes
 
 
 				geometry = new THREE.CubeGeometry( 100, 100, 100 );
 				geometry = new THREE.CubeGeometry( 100, 100, 100 );
-				material = new THREE.MeshDepthMaterial( { near: 1, far: 2000, overdraw: true } );
+				material = new THREE.MeshDepthMaterial( { overdraw: true } );
 
 
 				for ( var i = 0; i < 20; i ++ ) {
 				for ( var i = 0; i < 20; i ++ ) {
 
 

+ 8 - 9
examples/js/effects/AnaglyphEffect.js

@@ -4,7 +4,7 @@
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
  */
  */
 
 
-THREE.AnaglyphEffect = function ( renderer ) {
+THREE.AnaglyphEffect = function ( renderer, width, height ) {
 
 
 	var eyeRight = new THREE.Matrix4();
 	var eyeRight = new THREE.Matrix4();
 	var eyeLeft = new THREE.Matrix4();
 	var eyeLeft = new THREE.Matrix4();
@@ -17,16 +17,17 @@ THREE.AnaglyphEffect = function ( renderer ) {
 	var _cameraR = new THREE.PerspectiveCamera();
 	var _cameraR = new THREE.PerspectiveCamera();
 	_cameraR.matrixAutoUpdate = false;
 	_cameraR.matrixAutoUpdate = false;
 
 
-	var _scene = new THREE.Scene();
+	var _camera = new THREE.OrthographicCamera( -1, 1, 1, - 1, 0, 1 );
 
 
-	var _camera = new THREE.PerspectiveCamera( 53, 1, 1, 10000 );
-	_camera.position.z = 2;
-	_scene.add( _camera );
+	var _scene = new THREE.Scene();
 
 
 	var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
 	var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
 
 
-	var _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
-	var _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
+	if ( width === undefined ) width = 512;
+	if ( height === undefined ) height = 512;
+
+	var _renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
+	var _renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
 
 
 	var _material = new THREE.ShaderMaterial( {
 	var _material = new THREE.ShaderMaterial( {
 
 
@@ -160,8 +161,6 @@ THREE.AnaglyphEffect = function ( renderer ) {
 
 
 		renderer.render( scene, _cameraR, _renderTargetR, true );
 		renderer.render( scene, _cameraR, _renderTargetR, true );
 
 
-		_scene.updateMatrixWorld();
-
 		renderer.render( _scene, _camera );
 		renderer.render( _scene, _camera );
 
 
 	};
 	};

+ 11 - 13
examples/js/loaders/ColladaLoader.js

@@ -60,21 +60,19 @@ THREE.ColladaLoader = function () {
 
 
 		if ( document.implementation && document.implementation.createDocument ) {
 		if ( document.implementation && document.implementation.createDocument ) {
 
 
-			var req = new XMLHttpRequest();
+			var request = new XMLHttpRequest();
 
 
-			if ( req.overrideMimeType ) req.overrideMimeType( "text/xml" );
+			request.onreadystatechange = function() {
 
 
-			req.onreadystatechange = function() {
+				if( request.readyState == 4 ) {
 
 
-				if( req.readyState == 4 ) {
+					if( request.status == 0 || request.status == 200 ) {
 
 
-					if( req.status == 0 || req.status == 200 ) {
 
 
-
-						if ( req.responseXML ) {
+						if ( request.responseXML ) {
 
 
 							readyCallbackFunc = readyCallback;
 							readyCallbackFunc = readyCallback;
-							parse( req.responseXML, undefined, url );
+							parse( request.responseXML, undefined, url );
 
 
 						} else {
 						} else {
 
 
@@ -84,17 +82,17 @@ THREE.ColladaLoader = function () {
 
 
 					}
 					}
 
 
-				} else if ( req.readyState == 3 ) {
+				} else if ( request.readyState == 3 ) {
 
 
 					if ( progressCallback ) {
 					if ( progressCallback ) {
 
 
 						if ( length == 0 ) {
 						if ( length == 0 ) {
 
 
-							length = req.getResponseHeader( "Content-Length" );
+							length = request.getResponseHeader( "Content-Length" );
 
 
 						}
 						}
 
 
-						progressCallback( { total: length, loaded: req.responseText.length } );
+						progressCallback( { total: length, loaded: request.responseText.length } );
 
 
 					}
 					}
 
 
@@ -102,8 +100,8 @@ THREE.ColladaLoader = function () {
 
 
 			}
 			}
 
 
-			req.open( "GET", url, true );
-			req.send( null );
+			request.open( "GET", url, true );
+			request.send( null );
 
 
 		} else {
 		} else {
 
 

+ 474 - 0
examples/js/loaders/MTLLoader.js

@@ -0,0 +1,474 @@
+/**
+ * Loads a Wavefront .mtl file specifying materials
+ *
+ * @author angelxuanchang
+ */
+
+THREE.MTLLoader = function( baseUrl, options ) {
+
+    THREE.EventTarget.call( this );
+    this.baseUrl = baseUrl;
+    this.options = options;
+
+};
+
+THREE.MTLLoader.prototype = {
+
+    /**
+     * Loads a MTL file
+     *
+     * Loading progress is indicated by the following events:
+     *   "load" event (successful loading): type = 'load', content = THREE.MTLLoader.MaterialCreator
+     *   "error" event (error loading): type = 'load', message
+     *   "progress" event (progress loading): type = 'progress', loaded, total
+     *
+     * @param url - location of MTL file
+     */
+    load: function( url ) {
+
+        var scope = this;
+        var xhr = new XMLHttpRequest();
+
+        function onloaded( event ) {
+
+            if ( event.target.status === 200 || event.target.status === 0 ) {
+
+                var materialCreator = scope.parse( event.target.responseText );
+
+                // Notify caller, that I'm done
+
+                scope.dispatchEvent( { type: 'load', content: materialCreator } );
+
+            } else {
+
+                scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']',
+                    response: event.target.responseText } );
+
+            }
+
+        }
+
+        xhr.addEventListener( 'load', onloaded, false );
+
+        xhr.addEventListener( 'progress', function ( event ) {
+
+            scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
+
+        }, false );
+
+        xhr.addEventListener( 'error', function () {
+
+            scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+
+        }, false );
+
+        xhr.open( 'GET', url, true );
+        xhr.send( null );
+    },
+
+    /**
+     * Parses loaded MTL file
+     * @param text - Content of MTL file
+     * @return {THREE.MTLLoader.MaterialCreator}
+     */
+    parse: function( text ) {
+
+        var lines = text.split( "\n" );
+        var info = {};
+        var delimiter_pattern = /\s+/;
+        var materialsInfo = {};
+
+			for ( var i = 0; i < lines.length; i ++ ) {
+
+			var line = lines[ i ];
+            line = line.trim();
+
+            if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
+
+                // Blank line or comment ignore
+                continue;
+
+            }
+
+            var pos = line.indexOf( ' ' );
+
+			var key = ( pos >= 0 ) ? line.substring( 0, pos) : line;
+            key = key.toLowerCase();
+
+            var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : "";
+            value = value.trim();
+
+            if ( key === "newmtl" ) {
+
+                // New material
+
+                info = { name: value };
+                materialsInfo[ value ] = info;
+
+            } else if ( info ) {
+
+                if ( key === "ka" || key === "kd" || key === "ks" ) {
+
+                    var ss = value.split( delimiter_pattern, 3 );
+                    info[ key ] = [ parseFloat( ss[0] ), parseFloat( ss[1] ), parseFloat( ss[2] ) ];
+
+                } else {
+
+                    info[ key ] = value;
+
+                }
+
+            }
+
+        }
+
+        var materialCreator = new THREE.MTLLoader.MaterialCreator( this.baseUrl, this.options );
+        materialCreator.setMaterials( materialsInfo );
+        return materialCreator;
+
+    }
+
+};
+
+/**
+ * Create a new THREE-MTLLoader.MaterialCreator
+ * @param baseUrl - Url relative to which textures are loaded
+ * @param options - Set of options on how to construct the materials
+ *                  side: Which side to apply the material
+ *                        THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
+ *                  wrap: What type of wrapping to apply for textures
+ *                        THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
+ *                  normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
+ *                                Default: false, assumed to be already normalized
+ *                  ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
+ *                                  Default: false
+ *                  invertTransparency: If transparency need to be inverted (inversion is needed if d = 0 is fully opaque)
+ *                                      Default: false (d = 1 is fully opaque)
+ * @constructor
+ */
+THREE.MTLLoader.MaterialCreator = function( baseUrl, options ) {
+
+    THREE.EventTarget.call( this );
+    this.baseUrl = baseUrl;
+    this.options = options;
+    this.materialsInfo = {};
+    this.materials = {};
+    this.materialsArray = [];
+    this.nameLookup = {};
+
+    this.side = ( this.options && this.options.side )? this.options.side: THREE.FrontSide;
+    this.wrap = ( this.options && this.options.wrap )? this.options.wrap: THREE.RepeatWrapping;
+
+};
+
+THREE.MTLLoader.MaterialCreator.prototype = {
+
+    setMaterials: function( materialsInfo ) {
+
+        this.materialsInfo = this.convert( materialsInfo );
+        this.materials = {};
+        this.materialsArray = [];
+        this.nameLookup = {};
+
+    },
+
+    convert: function( materialsInfo ) {
+
+        if ( !this.options ) return materialsInfo;
+
+        var converted = {};
+
+        for ( var mn in materialsInfo ) {
+
+            // Convert materials info into normalized form based on options
+
+            var mat = materialsInfo[ mn ];
+
+            var covmat = {};
+
+            converted[ mn ] = covmat;
+
+            for ( var prop in mat ) {
+
+                var save = true;
+                var value = mat[ prop ];
+                var lprop = prop.toLowerCase();
+
+                switch ( lprop ) {
+
+                    case 'kd':
+                    case 'ka':
+                    case 'ks':
+
+                        // Diffuse color (color under white light) using RGB values
+
+                        if ( this.options && this.options.normalizeRGB ) {
+
+                            value =  [ value[0]/255, value[1]/255, value[2]/255 ];
+
+                        }
+
+                        if ( this.options && this.options.ignoreZeroRGBs ) {
+
+                            if ( value[0] === 0.0 && value[1] === 0.0 && value[1] === 0.0 ) {
+
+                                // ignore
+
+                                save = false;
+
+                            }
+                        }
+
+                        break;
+
+                    case 'd':
+
+                        // According to MTL format (http://paulbourke.net/dataformats/mtl/):
+                        //   d is dissolve for current material
+                        //   factor of 1.0 is fully opaque, a factor of 0 is fully dissolved (completely transparent)
+
+                        if ( this.options && this.options.invertTransparency ) {
+
+                            value = 1 - value;
+
+                        }
+
+                        break;
+
+                    default:
+
+                        break;
+                }
+
+                if ( save ) {
+
+                    covmat[lprop] = value;
+
+                }
+
+            }
+
+        }
+
+        return converted;
+
+    },
+
+    preload: function () {
+
+        for ( var mn in this.materialsInfo ) {
+
+            this.create( mn );
+
+        }
+
+    },
+
+    getIndex: function( materialName ) {
+
+        return this.nameLookup[ materialName ];
+
+    },
+
+    getAsArray: function() {
+
+        var index = 0;
+
+        for ( var mn in this.materialsInfo ) {
+
+            this.materialsArray[ index ] = this.create( mn );
+            this.nameLookup[ mn ] = index;
+            index ++;
+
+        }
+
+        return this.materialsArray;
+
+    },
+
+    create: function ( materialName ) {
+
+        if ( this.materials[ materialName ] === undefined ) {
+
+            this.createMaterial_( materialName );
+
+        }
+
+        return this.materials[ materialName ];
+
+    },
+
+    createMaterial_: function ( materialName ) {
+
+        // Create material
+
+        var mat = this.materialsInfo[ materialName ];
+        var params = {
+
+            name: materialName,
+            side: this.side
+
+        };
+
+        for ( var prop in mat ) {
+
+            var value = mat[ prop ];
+
+            switch ( prop.toLowerCase() ) {
+
+                // Ns is material specular exponent
+
+                case 'kd':
+
+					// Diffuse color (color under white light) using RGB values
+
+					params[ 'diffuse' ] = new THREE.Color().setRGB( value[0], value[1], value[2] );
+
+					break;
+
+                case 'ka':
+
+                    // Ambient color (color under shadow) using RGB values
+
+                    params[ 'ambient' ] = new THREE.Color().setRGB( value[0], value[1], value[2] );
+
+					break;
+
+                case 'ks':
+
+                    // Specular color (color when light is reflected from shiny surface) using RGB values
+                    params[ 'specular' ] = new THREE.Color().setRGB( value[0], value[1], value[2] );
+
+                    break;
+
+                case 'map_kd':
+
+                    // Diffuse texture map
+
+                    params[ 'map' ] = THREE.MTLLoader.loadTexture( this.baseUrl + value );
+                    params[ 'map' ].wrapS = this.wrap;
+                    params[ 'map' ].wrapT = this.wrap;
+
+					break;
+
+                case 'ns':
+
+                    // 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;
+
+					break;
+
+                case 'd':
+
+                    // According to MTL format (http://paulbourke.net/dataformats/mtl/):
+                    //   d is dissolve for current material
+                    //   factor of 1.0 is fully opaque, a factor of 0 is fully dissolved (completely transparent)
+
+                    if ( value < 1 ) {
+
+                        params['transparent'] = true;
+                        params['opacity'] = value;
+
+                    }
+
+                    break;
+
+                default:
+                    break;
+
+            }
+
+        }
+
+        if ( params[ 'diffuse' ] ) {
+
+            if ( !params[ 'ambient' ]) params[ 'ambient' ] = params[ 'diffuse' ];
+            params[ 'color' ] = params[ 'diffuse' ];
+
+        }
+
+        this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
+        return this.materials[ materialName ];
+
+    }
+
+};
+
+THREE.MTLLoader.loadTexture = function ( url, mapping, onLoad, onError ) {
+
+	var isCompressed = url.toLowerCase().endsWith( ".dds" );
+
+	if ( isCompressed ) {
+
+		var texture = THREE.ImageUtils.loadCompressedTexture( url, mapping, onLoad, onError );
+
+	} else {
+
+		var image = new Image();
+		var texture = new THREE.Texture( image, mapping );
+
+		var loader = new THREE.ImageLoader();
+
+		loader.addEventListener( 'load', function ( event ) {
+
+			texture.image = THREE.MTLLoader.ensurePowerOfTwo_( event.content );
+			texture.needsUpdate = true;
+			if ( onLoad ) onLoad( texture );
+
+		} );
+
+		loader.addEventListener( 'error', function ( event ) {
+
+			if ( onError ) onError( event.message );
+
+		} );
+
+		loader.crossOrigin = this.crossOrigin;
+		loader.load( url, image );
+
+	}
+
+	return texture;
+
+};
+
+THREE.MTLLoader.ensurePowerOfTwo_ = function ( image ) {
+
+    if ( ! THREE.MTLLoader.isPowerOfTwo_( image.width ) || ! THREE.MTLLoader.isPowerOfTwo_( image.height ) ) {
+
+        var canvas = document.createElement( "canvas" );
+        canvas.width = THREE.MTLLoader.nextHighestPowerOfTwo_( image.width );
+        canvas.height = THREE.MTLLoader.nextHighestPowerOfTwo_( image.height );
+
+        var ctx = canvas.getContext("2d");
+        ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
+        return canvas;
+
+    }
+
+    return image;
+
+};
+
+THREE.MTLLoader.isPowerOfTwo_ = function ( x ) {
+
+	return ( x & ( x - 1 ) ) === 0;
+
+};
+
+THREE.MTLLoader.nextHighestPowerOfTwo_ = function( x ) {
+
+    --x;
+
+    for ( var i = 1; i < 32; i <<= 1 ) {
+
+        x = x | x >> i;
+
+    }
+
+    return x + 1;
+
+};
+

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

@@ -15,28 +15,28 @@ THREE.OBJLoader.prototype = {
 	load: function ( url ) {
 	load: function ( url ) {
 
 
 		var scope = this;
 		var scope = this;
-		var xhr = new XMLHttpRequest();
+		var request = new XMLHttpRequest();
 
 
-		xhr.addEventListener( 'load', function ( event ) {
+		request.addEventListener( 'load', function ( event ) {
 
 
 			scope.dispatchEvent( { type: 'load', content: scope.parse( event.target.responseText ) } );
 			scope.dispatchEvent( { type: 'load', content: scope.parse( event.target.responseText ) } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.addEventListener( 'progress', function ( event ) {
+		request.addEventListener( 'progress', function ( event ) {
 
 
 			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
 			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.addEventListener( 'error', function () {
+		request.addEventListener( 'error', function () {
 
 
 			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
 			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.open( 'GET', url, true );
-		xhr.send( null );
+		request.open( 'GET', url, true );
+		request.send( null );
 
 
 	},
 	},
 
 

+ 490 - 0
examples/js/loaders/OBJMTLLoader.js

@@ -0,0 +1,490 @@
+/**
+ * Loads a Wavefront .obj file with materials
+ *
+ * @author mrdoob / http://mrdoob.com/
+ * @author angelxuanchang
+ */
+
+THREE.OBJMTLLoader = function ( ) {
+
+	THREE.EventTarget.call( this );
+
+};
+
+THREE.OBJMTLLoader.prototype = {
+
+	constructor: THREE.OBJMTLLoader,
+
+    /**
+     * Load a Wavefront OBJ file with materials (MTL file)
+     *
+     * Loading progress is indicated by the following events:
+     *   "load" event (successful loading): type = 'load', content = THREE.Object3D
+     *   "error" event (error loading): type = 'load', message
+     *   "progress" event (progress loading): type = 'progress', loaded, total
+     *
+     * If the MTL file cannot be loaded, then a MeshLambertMaterial is used as a default
+     * @param url - Location of OBJ file to load
+     * @param mtlfileurl - MTL file to load (optional, if not specified, attempts to use MTL specified in OBJ file)
+     * @param options - Options on how to interpret the material (see THREE.MTLLoader.MaterialCreator )
+     *
+     */
+
+	load: function ( url, mtlfileurl, options ) {
+
+		var scope = this;
+		var xhr = new XMLHttpRequest();
+
+        var mtlDone;  // Is the MTL done (true if no MTL, error loading MTL, or MTL actually loaded)
+        var obj3d;    // Loaded model (from obj file)
+        var materialsCreator;  // Material creator is created when MTL file is loaded
+
+        // Loader for MTL
+
+        var mtlLoader = new THREE.MTLLoader( url.substr( 0, url.lastIndexOf( "/" ) + 1 ), options );
+        mtlLoader.addEventListener( 'load', waitReady );
+        mtlLoader.addEventListener( 'error', waitReady );
+
+        // Try to load mtlfile
+
+        if ( mtlfileurl ) {
+
+            mtlLoader.load( mtlfileurl );
+            mtlDone = false;
+
+        } else {
+
+            mtlDone = true;
+
+        }
+
+        function waitReady( event ) {
+
+            if ( event.type === 'load' ) {
+
+                if ( event.content instanceof THREE.MTLLoader.MaterialCreator ) {
+
+                    // MTL file is loaded
+
+                    mtlDone = true;
+                    materialsCreator = event.content;
+                    materialsCreator.preload();
+
+                } else {
+
+                    // OBJ file is loaded
+
+                    if ( event.target.status === 200 || event.target.status === 0 ) {
+
+                        var objContent = event.target.responseText;
+
+                        if ( mtlfileurl ) {
+
+                            // Parse with passed in MTL file
+
+                            obj3d = scope.parse( objContent );
+
+                        } else {
+
+                            // No passed in MTL file, look for mtlfile in obj file
+
+                            obj3d = scope.parse( objContent, function( mtlfile ) {
+
+                                mtlDone = false;
+                                mtlLoader.load( mtlLoader.baseUrl + mtlfile );
+
+                            } );
+
+                        }
+
+                    } else {
+
+                        // Error loading OBJ file....
+
+                        scope.dispatchEvent( {
+                            type: 'error',
+                            message: 'Couldn\'t load URL [' + url + ']',
+                            response: event.target.responseText } );
+
+                    }
+
+                }
+
+            } else if ( event.type === 'error' ) {
+
+                // MTL failed to load -- oh well, we will just not have material ...
+
+                mtlDone = true;
+
+            }
+
+            if ( mtlDone && obj3d ) {
+
+                // MTL file is loaded and OBJ file is loaded
+                // Apply materials to model
+
+                if ( materialsCreator ) {
+
+                    THREE.SceneUtils.traverseHierarchy( obj3d, function( node ) {
+
+						if ( node instanceof THREE.Mesh ) {
+
+							if ( node.material.name ) {
+
+								var material = materialsCreator.create( node.material.name );
+								if  (material ) node.material = material;
+							}
+						}
+
+					} );
+
+                }
+
+                // Notify listeners
+
+                scope.dispatchEvent( { type: 'load', content: obj3d } );
+            }
+
+        }
+
+        xhr.addEventListener( 'load', waitReady, false );
+
+		xhr.addEventListener( 'progress', function ( event ) {
+
+			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
+
+		}, false );
+
+		xhr.addEventListener( 'error', function () {
+
+			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
+
+		}, false );
+
+		xhr.open( 'GET', url, true );
+		xhr.send( null );
+
+    },
+
+    /**
+     * Parses loaded .obj file
+     * @param data - content of .obj file
+     * @param mtllibCallback - callback to handle mtllib declaration (optional)
+     * @return {THREE.Object3D} - Object3D (with default material)
+     */
+	parse: function ( data, mtllibCallback ) {
+
+        function vector( x, y, z ) {
+
+			return new THREE.Vector3( x, y, z );
+
+		}
+
+		function uv( u, v ) {
+
+			return new THREE.UV( u, v );
+
+		}
+
+		function face3( a, b, c, normals ) {
+
+			return new THREE.Face3( a, b, c, normals );
+
+		}
+
+		function face4( a, b, c, d, normals ) {
+
+			return new THREE.Face4( a, b, c, d, normals );
+
+		}
+
+        function finalize_mesh( group, mesh_info ) {
+
+            mesh_info.geometry.computeCentroids();
+            mesh_info.geometry.computeFaceNormals();
+            mesh_info.geometry.computeBoundingSphere();
+            group.add( new THREE.Mesh( mesh_info.geometry, mesh_info.material ) );
+
+        }
+
+		var vertices = [];
+		var normals = [];
+		var uvs = [];
+
+        // v float float float
+
+        var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
+
+		// vn float float float
+
+        var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
+
+		// vt float float
+
+        var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
+
+		// f vertex vertex vertex ...
+
+        var face_pattern1 = /f( +[\d]+)( [\d]+)( [\d]+)( [\d]+)?/;
+
+		// f vertex/uv vertex/uv vertex/uv ...
+
+        var face_pattern2 = /f( +([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))?/;
+
+		// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
+
+        var face_pattern3 = /f( +([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))?/;
+
+		// f vertex//normal vertex//normal vertex//normal ...
+
+        var face_pattern4 = /f( +([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))?/;
+
+        var final_model = new THREE.Object3D();
+
+		var geometry = new THREE.Geometry();
+        geometry.vertices = vertices;
+
+		var cur_mesh = {
+
+            material: new THREE.MeshLambertMaterial(),
+            geometry: geometry
+
+        };
+
+        var lines = data.split( "\n" );
+
+        for ( var i = 0; i < lines.length; i ++ ) {
+
+            var line = lines[ i ];
+            line = line.trim();
+
+            // temporary variable storing pattern matching result
+
+            var result;
+
+            if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
+
+                continue;
+
+            } else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
+
+                // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
+
+                vertices.push( vector(
+                    parseFloat( result[ 1 ] ),
+                    parseFloat( result[ 2 ] ),
+                    parseFloat( result[ 3 ] )
+                ) );
+
+            } else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
+
+				// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
+
+				normals.push( vector(
+                    parseFloat( result[ 1 ] ),
+                    parseFloat( result[ 2 ] ),
+                    parseFloat( result[ 3 ] )
+                ) );
+
+            } else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
+
+                // ["vt 0.1 0.2", "0.1", "0.2"]
+
+                uvs.push( uv(
+                    parseFloat( result[ 1 ] ),
+                    parseFloat( result[ 2 ] )
+                ) );
+
+            } else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
+
+                // ["f 1 2 3", "1", "2", "3", undefined]
+
+                if ( result[ 4 ] === undefined ) {
+
+                    geometry.faces.push( face3(
+                        parseInt( result[ 1 ] ) - 1,
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 3 ] ) - 1
+                    ) );
+
+                } else {
+
+                    geometry.faces.push( face4(
+                        parseInt( result[ 1 ] ) - 1,
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 3 ] ) - 1,
+                        parseInt( result[ 4 ] ) - 1
+                    ) );
+
+                }
+
+            } else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
+
+                // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
+
+                if ( result[ 10 ] === undefined ) {
+
+                    geometry.faces.push( face3(
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 5 ] ) - 1,
+                        parseInt( result[ 8 ] ) - 1
+                    ) );
+
+                    geometry.faceVertexUvs[ 0 ].push( [
+                        uvs[ parseInt( result[ 3 ] ) - 1 ],
+                        uvs[ parseInt( result[ 6 ] ) - 1 ],
+                        uvs[ parseInt( result[ 9 ] ) - 1 ]
+                    ] );
+
+                } else {
+
+                    geometry.faces.push( face4(
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 5 ] ) - 1,
+                        parseInt( result[ 8 ] ) - 1,
+                        parseInt( result[ 11 ] ) - 1
+                    ) );
+
+                    geometry.faceVertexUvs[ 0 ].push( [
+                        uvs[ parseInt( result[ 3 ] ) - 1 ],
+                        uvs[ parseInt( result[ 6 ] ) - 1 ],
+                        uvs[ parseInt( result[ 9 ] ) - 1 ],
+                        uvs[ parseInt( result[ 12 ] ) - 1 ]
+                    ] );
+
+                }
+
+            } else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
+
+                // ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
+
+                if ( result[ 13 ] === undefined ) {
+
+                    geometry.faces.push( face3(
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 6 ] ) - 1,
+                        parseInt( result[ 10 ] ) - 1,
+                        [
+                            normals[ parseInt( result[ 4 ] ) - 1 ],
+                            normals[ parseInt( result[ 8 ] ) - 1 ],
+                            normals[ parseInt( result[ 12 ] ) - 1 ]
+                        ]
+                    ) );
+
+                    geometry.faceVertexUvs[ 0 ].push( [
+                        uvs[ parseInt( result[ 3 ] ) - 1 ],
+                        uvs[ parseInt( result[ 7 ] ) - 1 ],
+                        uvs[ parseInt( result[ 11 ] ) - 1 ]
+                    ] );
+
+                } else {
+
+                    geometry.faces.push( face4(
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 6 ] ) - 1,
+                        parseInt( result[ 10 ] ) - 1,
+                        parseInt( result[ 14 ] ) - 1,
+                        [
+                            normals[ parseInt( result[ 4 ] ) - 1 ],
+                            normals[ parseInt( result[ 8 ] ) - 1 ],
+                            normals[ parseInt( result[ 12 ] ) - 1 ],
+                            normals[ parseInt( result[ 16 ] ) - 1 ]
+                        ]
+                    ) );
+
+                    geometry.faceVertexUvs[ 0 ].push( [
+                        uvs[ parseInt( result[ 3 ] ) - 1 ],
+                        uvs[ parseInt( result[ 7 ] ) - 1 ],
+                        uvs[ parseInt( result[ 11 ] ) - 1 ],
+                        uvs[ parseInt( result[ 15 ] ) - 1 ]
+                    ] );
+
+                }
+
+            } else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
+
+                // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
+
+                if ( result[ 10 ] === undefined ) {
+
+                    geometry.faces.push( face3(
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 5 ] ) - 1,
+                        parseInt( result[ 8 ] ) - 1,
+                        [
+                            normals[ parseInt( result[ 3 ] ) - 1 ],
+                            normals[ parseInt( result[ 6 ] ) - 1 ],
+                            normals[ parseInt( result[ 9 ] ) - 1 ]
+                        ]
+                    ) );
+
+                } else {
+
+                    geometry.faces.push( face4(
+                        parseInt( result[ 2 ] ) - 1,
+                        parseInt( result[ 5 ] ) - 1,
+                        parseInt( result[ 8 ] ) - 1,
+                        parseInt( result[ 11 ] ) - 1,
+                        [
+                            normals[ parseInt( result[ 3 ] ) - 1 ],
+                            normals[ parseInt( result[ 6 ] ) - 1 ],
+                            normals[ parseInt( result[ 9 ] ) - 1 ],
+                            normals[ parseInt( result[ 12 ] ) - 1 ]
+                        ]
+                    ) );
+
+                }
+
+            } else if ( line.startsWith( "usemtl " ) ) {
+
+                var material_name = line.substring( 7 );
+                material_name = material_name.trim();
+
+                var material = new THREE.MeshLambertMaterial();
+                material.name = material_name;
+
+                if ( geometry.faces.length > 0 ) {
+
+                    // Finalize previous geometry and add to model
+
+                    finalize_mesh( final_model, cur_mesh );
+                    geometry = new THREE.Geometry();
+                    geometry.vertices = vertices;
+
+                    cur_mesh = {  geometry: geometry };
+
+                }
+
+                cur_mesh.material = material;
+                //material_index = materialsCreator.getIndex( material_name );
+
+            } else if ( line.startsWith( "g " ) ) {
+
+                // Polygon group for object
+
+                var group_name = line.substring( 2 );
+                group_name = group_name.trim();
+
+            } else if ( line.startsWith( "o " ) ) {
+
+                // Object
+                var object_name = line.substring(2);
+                //object_name = $.trim(object_name);
+            } else if (line.startsWith("s ")) {
+                // Smooth shading
+            } else if (line.startsWith("mtllib ")) {
+                // mtl file
+                if (mtllibCallback) {
+                    var mtlfile = line.substring(7);
+                    mtlfile = $.trim(mtlfile);
+                    mtllibCallback(mtlfile);
+                }
+            } else {
+                console.error("Unhandled line " + line);
+            }
+        }
+        finalize_mesh(final_model, cur_mesh);
+		return final_model;
+	}
+};
+

+ 6 - 6
examples/js/loaders/STLLoader.js

@@ -31,28 +31,28 @@ THREE.STLLoader.prototype = {
 	load: function ( url ) {
 	load: function ( url ) {
 
 
 		var scope = this;
 		var scope = this;
-		var xhr = new XMLHttpRequest();
+		var request = new XMLHttpRequest();
 
 
-		xhr.addEventListener( 'load', function ( event ) {
+		request.addEventListener( 'load', function ( event ) {
 
 
 			scope.dispatchEvent( { type: 'load', content: scope.parse( event.target.responseText ) } );
 			scope.dispatchEvent( { type: 'load', content: scope.parse( event.target.responseText ) } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.addEventListener( 'progress', function ( event ) {
+		request.addEventListener( 'progress', function ( event ) {
 
 
 			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
 			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.addEventListener( 'error', function () {
+		request.addEventListener( 'error', function () {
 
 
 			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
 			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.open( 'GET', url, true );
-		xhr.send( null );
+		request.open( 'GET', url, true );
+		request.send( null );
 
 
 	},
 	},
 
 

+ 822 - 188
examples/js/loaders/UTF8Loader.js

@@ -1,326 +1,960 @@
 /**
 /**
- * Loader for UTF8 encoded models generated by:
+ * Loader for UTF8 version2 (after r51) encoded models generated by:
  *	http://code.google.com/p/webgl-loader/
  *	http://code.google.com/p/webgl-loader/
  *
  *
- * Limitations:
- *  - number of vertices < 65536 (this is after optimizations in compressor, input OBJ may have even less)
- *	- models must have normals and texture coordinates
- *  - texture coordinates must be only from <0,1>
- *  - no materials support yet
- *  - models are scaled and offset (copy numbers from compressor and use them as parameters in UTF8Loader.load() )
- *
- * @author alteredq / http://alteredqualia.com/
- * @author won3d / http://twitter.com/won3d
+ * Code to load/decompress mesh is taken from r100 of this webgl-loader
  */
  */
 
 
 THREE.UTF8Loader = function () {};
 THREE.UTF8Loader = function () {};
 
 
-THREE.UTF8Loader.prototype.load = function ( url, callback, metadata ) {
+/**
+ * Load UTF8 encoded model
+ * @param jsonUrl - URL from which to load json containing information about model
+ * @param callback - Callback(THREE.Object3D) on successful loading of model
+ * @param options - options on how to load model (see THREE.MTLLoader.MaterialCreator for basic options)
+ *                  Additional options include
+ *                   geometryBase: Base url from which to load referenced geometries
+ *                   materialBase: Base url from which to load referenced textures
+ */
 
 
-	var xhr = new XMLHttpRequest(),
-		callbackProgress = null,
+THREE.UTF8Loader.prototype.load = function ( jsonUrl, callback, options ) {
 
 
-		scale = metadata.scale !== undefined ? metadata.scale : 1,
-		offsetX = metadata.offsetX !== undefined ? metadata.offsetX : 0,
-		offsetY = metadata.offsetY !== undefined ? metadata.offsetY : 0,
-		offsetZ = metadata.offsetZ !== undefined ? metadata.offsetZ : 0;
+    this.downloadModelJson( jsonUrl, options, callback );
 
 
-	var length = 0;
+};
 
 
-	xhr.onreadystatechange = function() {
+// BufferGeometryCreator
 
 
-		if ( xhr.readyState == 4 ) {
+THREE.UTF8Loader.BufferGeometryCreator = function () {
+};
 
 
-			if ( xhr.status == 200 || xhr.status == 0 ) {
+THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray, indexArray ) {
 
 
-				THREE.UTF8Loader.prototype.createModel( xhr.responseText, callback, scale, offsetX, offsetY, offsetZ );
+	var ntris = indexArray.length / 3;
 
 
-			} else {
+	var geometry = new THREE.BufferGeometry();
 
 
-				console.error( "THREE.UTF8Loader: Couldn't load [" + url + "] [" + xhr.status + "]" );
+	var positionArray = new Float32Array( 3 * 3 * ntris );
+	var normalArray = new Float32Array( 3 * 3 * ntris );
+	var uvArray = new Float32Array( 2 * 3 * ntris );
 
 
-			}
+	var i, j, offset;
+	var x, y, z;
+	var u, v;
 
 
-		} else if ( xhr.readyState == 3 ) {
+	var end = attribArray.length;
+	var stride = 8;
 
 
-			if ( callbackProgress ) {
+	// extract positions
 
 
-				if ( length == 0 ) {
+	j = 0;
+	offset = 0;
 
 
-					length = xhr.getResponseHeader( "Content-Length" );
+	for( i = offset; i < end; i += stride ) {
 
 
-				}
+		x = attribArray[ i ];
+		y = attribArray[ i + 1 ];
+		z = attribArray[ i + 2 ];
 
 
-				callbackProgress( { total: length, loaded: xhr.responseText.length } );
+		positionArray[ j++ ] = x;
+		positionArray[ j++ ] = y;
+		positionArray[ j++ ] = z;
 
 
-			}
+	}
 
 
-		} else if ( xhr.readyState == 2 ) {
+	// extract uvs
 
 
-			length = xhr.getResponseHeader( "Content-Length" );
+	j = 0;
+	offset = 3;
 
 
-		}
+	for( i = offset; i < end; i += stride ) {
+
+		u = attribArray[ i ];
+		v = attribArray[ i + 1 ];
+
+		uvArray[ j++ ] = u;
+		uvArray[ j++ ] = v;
 
 
 	}
 	}
 
 
-	xhr.open( "GET", url, true );
-	xhr.send( null );
+	// extract normals
+
+	j = 0;
+	offset = 5;
+
+	for( i = offset; i < end; i += stride ) {
+
+		x = attribArray[ i ];
+		y = attribArray[ i + 1 ];
+		z = attribArray[ i + 2 ];
+
+		normalArray[ j++ ] = x;
+		normalArray[ j++ ] = y;
+		normalArray[ j++ ] = z;
+
+	}
+
+	// create attributes
+
+	var attributes = geometry.attributes;
+
+	attributes[ "index" ]    = { itemSize: 1, array: indexArray, numItems: indexArray.length };
+	attributes[ "position" ] = { itemSize: 3, array: positionArray, numItems: positionArray.length };
+	attributes[ "normal" ]   = { itemSize: 3, array: normalArray, numItems: normalArray.length };
+	attributes[ "uv" ] 		 = { itemSize: 2, array: uvArray, numItems: uvArray.length };
+
+	// create offsets
+	// (all triangles should fit in a single chunk)
+
+	geometry.offsets = [ { start: 0, count: indexArray.length, index: 0 } ];
+
+	geometry.computeBoundingSphere();
+
+	return geometry;
+
+};
+
+// GeometryCreator
+
+THREE.UTF8Loader.GeometryCreator = function () {
+};
+
+THREE.UTF8Loader.GeometryCreator.prototype = {
+
+    create: function ( attribArray, indexArray ) {
+
+        var geometry = new THREE.Geometry();
+
+        this.init_vertices( geometry, attribArray, 8, 0 );
+
+        var uvs = this.init_uvs( attribArray, 8, 3 );
+        var normals = this.init_normals( attribArray, 8, 5 );
+
+        this.init_faces( geometry, normals, uvs, indexArray );
+
+        geometry.computeCentroids();
+        geometry.computeFaceNormals();
+
+        return geometry;
+
+    },
+
+    init_vertices: function ( scope, data, stride, offset ) {
+
+        var i, x, y, z;
+		var end = data.length;
+
+        for( i = offset; i < end; i += stride ) {
+
+            x = data[ i ];
+            y = data[ i + 1 ];
+            z = data[ i + 2 ];
+
+            this.addVertex( scope, x, y, z );
+
+        }
+
+    },
+
+    init_normals: function( data, stride, offset ) {
+
+        var normals = [];
+
+        var i, x, y, z;
+		var end = data.length;
+
+        for( i = offset; i < end; i += stride ) {
+
+            // Assumes already normalized to <-1,1> (unlike previous version of UTF8Loader)
+
+            x = data[ i ];
+            y = data[ i + 1 ];
+            z = data[ i + 2 ];
+
+            normals.push( x, y, z );
+
+        }
+
+        return normals;
+
+    },
+
+    init_uvs: function( data, stride, offset ) {
+
+        var uvs = [];
+
+        var i, u, v;
+		var end = data.length;
+
+        for( i = offset; i < end; i += stride ) {
+
+            // Assumes uvs are already normalized (unlike previous version of UTF8Loader)
+            // uvs can be negative, need to set wrap for texture map later on ...
+
+            u = data[ i ];
+            v = data[ i + 1 ];
+
+            uvs.push( u, v );
+        }
+
+        return uvs;
+
+    },
+
+    init_faces: function( scope, normals, uvs, indices ) {
+
+        var i,
+            a, b, c,
+            u1, v1, u2, v2, u3, v3;
+
+		var end = indices.length;
+
+        var m = 0; // all faces defaulting to material 0
+
+        for( i = 0; i < end; i += 3 ) {
+
+            a = indices[ i ];
+            b = indices[ i + 1 ];
+            c = indices[ i + 2 ];
+
+            this.f3n( scope, normals, a, b, c, m, a, b, c );
+
+            u1 = uvs[ a * 2 ];
+            v1 = uvs[ a * 2 + 1 ];
+
+            u2 = uvs[ b * 2 ];
+            v2 = uvs[ b * 2 + 1 ];
+
+            u3 = uvs[ c * 2 ];
+            v3 = uvs[ c * 2 + 1 ];
+
+            this.uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 );
+
+        }
+
+    },
+
+    addVertex: function ( scope, x, y, z ) {
+
+        scope.vertices.push( new THREE.Vector3( x, y, z ) );
+
+    },
+
+    f3n: function( scope, normals, a, b, c, mi, nai, nbi, nci ) {
+
+        var nax = normals[ nai * 3 ],
+            nay = normals[ nai * 3 + 1 ],
+            naz = normals[ nai * 3 + 2 ],
+
+            nbx = normals[ nbi * 3 ],
+            nby = normals[ nbi * 3 + 1 ],
+            nbz = normals[ nbi * 3 + 2 ],
+
+            ncx = normals[ nci * 3 ],
+            ncy = normals[ nci * 3 + 1 ],
+            ncz = normals[ nci * 3 + 2 ];
+
+        var na = new THREE.Vector3( nax, nay, naz ),
+            nb = new THREE.Vector3( nbx, nby, nbz ),
+            nc = new THREE.Vector3( ncx, ncy, ncz );
+
+        scope.faces.push( new THREE.Face3( a, b, c, [ na, nb, nc ], null, mi ) );
+
+    },
+
+    uv3: function ( where, u1, v1, u2, v2, u3, v3 ) {
+
+        var uv = [];
+        uv.push( new THREE.UV( u1, v1 ) );
+        uv.push( new THREE.UV( u2, v2 ) );
+        uv.push( new THREE.UV( u3, v3 ) );
+        where.push( uv );
+
+    }
 
 
 };
 };
 
 
-// UTF-8 decoder from webgl-loader
+
+// UTF-8 decoder from webgl-loader (r100)
 // http://code.google.com/p/webgl-loader/
 // http://code.google.com/p/webgl-loader/
 
 
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you
-// may not use this file except in compliance with the License. You
-// may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
+// Model manifest description. Contains objects like:
+// name: {
+//   materials: { 'material_name': { ... } ... },
+//   decodeParams: {
+//     decodeOffsets: [ ... ],
+//     decodeScales: [ ... ],
+//   },
+//   urls: {
+//     'url': [
+//       { material: 'material_name',
+//         attribRange: [#, #],
+//         indexRange: [#, #],
+//         names: [ 'object names' ... ],
+//         lengths: [#, #, # ... ]
+//       }
+//     ],
+//     ...
+//   }
+// }
+
+var DEFAULT_DECODE_PARAMS = {
+
+    decodeOffsets: [-4095, -4095, -4095, 0, 0, -511, -511, -511],
+    decodeScales: [1/8191, 1/8191, 1/8191, 1/1023, 1/1023, 1/1023, 1/1023, 1/1023]
+
+    // TODO: normal decoding? (see walt.js)
+    // needs to know: input, output (from vertex format!)
+    //
+    // Should split attrib/index.
+    // 1) Decode position and non-normal attributes.
+    // 2) Decode indices, computing normals
+    // 3) Maybe normalize normals? Only necessary for refinement, or fixed?
+    // 4) Maybe refine normals? Should this be part of regular refinement?
+    // 5) Morphing
 
 
-THREE.UTF8Loader.prototype.decompressMesh = function ( str ) {
+};
 
 
-	var num_verts = str.charCodeAt( 0 );
+// Triangle strips!
 
 
-	if ( num_verts >= 0xE000 ) {
+// TODO: will it be an optimization to specialize this method at
+// runtime for different combinations of stride, decodeOffset and
+// decodeScale?
 
 
-		num_verts -= 0x0800;
+THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart, inputEnd,
+                                                                  output, outputStart, stride,
+                                                                  decodeOffset, decodeScale ) {
 
 
-	}
+    var prev = 0;
 
 
-	num_verts ++;
+    for ( var j = inputStart; j < inputEnd; j ++ ) {
 
 
-	var attribs_out = new Float32Array( 8 * num_verts );
+        var code = str.charCodeAt( j );
+        prev += ( code >> 1 ) ^ ( -( code & 1 ) );
 
 
-	var offset = 1;
+        output[ outputStart ] = decodeScale * ( prev + decodeOffset );
+        outputStart += stride;
 
 
-	for ( var i = 0; i < 8; i ++ ) {
+    }
 
 
-		var prev_attrib = 0;
+};
 
 
-		for ( var j = 0; j < num_verts; ++ j ) {
+THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIndices,
+                                                            output, outputStart ) {
 
 
-			var code = str.charCodeAt( j + offset );
+	var highest = 0;
 
 
-			prev_attrib += ( code >> 1 ) ^ ( - ( code & 1 ) );
+    for ( var i = 0; i < numIndices; i ++ ) {
 
 
-			attribs_out[ 8 * j + i ] = prev_attrib;
+        var code = str.charCodeAt( inputStart ++ );
 
 
-		}
+        output[ outputStart ++ ] = highest - code;
 
 
-		offset += num_verts;
+        if ( code === 0 ) {
 
 
-	}
+            highest ++;
 
 
-	var num_indices = str.length - offset;
+        }
 
 
-	var indices_out = new Uint16Array( num_indices );
+    }
 
 
-	var index_high_water_mark = 0;
+};
 
 
-	for ( var i = 0; i < num_indices; i ++ ) {
+THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen,
+                                                           decodeOffsets, decodeScales ) {
+    var numFloats = 6 * numBBoxen;
 
 
-		var code = str.charCodeAt( i + offset );
+    var inputEnd = inputStart + numFloats;
+    var outputStart = 0;
 
 
-		indices_out[ i ] = index_high_water_mark - code;
+    var bboxen = new Float32Array( numFloats );
 
 
-		if ( code == 0 ) {
+    for ( var i = inputStart; i < inputEnd; i += 6 ) {
 
 
-			index_high_water_mark ++;
+        var minX = str.charCodeAt(i + 0) + decodeOffsets[0];
+        var minY = str.charCodeAt(i + 1) + decodeOffsets[1];
+        var minZ = str.charCodeAt(i + 2) + decodeOffsets[2];
 
 
-		}
+        var radiusX = (str.charCodeAt(i + 3) + 1) >> 1;
+        var radiusY = (str.charCodeAt(i + 4) + 1) >> 1;
+        var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1;
 
 
-	}
+        bboxen[ outputStart++ ] = decodeScales[0] * (minX + radiusX);
+        bboxen[ outputStart++ ] = decodeScales[1] * (minY + radiusY);
+        bboxen[ outputStart++ ] = decodeScales[2] * (minZ + radiusZ);
+
+        bboxen[ outputStart++ ] = decodeScales[0] * radiusX;
+        bboxen[ outputStart++ ] = decodeScales[1] * radiusY;
+        bboxen[ outputStart++ ] = decodeScales[2] * radiusZ;
+
+    }
+
+    return bboxen;
+
+};
+
+THREE.UTF8Loader.prototype.decompressMesh =  function ( str, meshParams, decodeParams, name, idx, callback ) {
+
+    // Extract conversion parameters from attribArrays.
+
+    var stride = decodeParams.decodeScales.length;
+
+    var decodeOffsets = decodeParams.decodeOffsets;
+    var decodeScales = decodeParams.decodeScales;
+
+    var attribStart = meshParams.attribRange[0];
+    var numVerts = meshParams.attribRange[1];
+
+    // Decode attributes.
+
+    var inputOffset = attribStart;
+    var attribsOut = new Float32Array( stride * numVerts );
+
+    for (var j = 0; j < stride; j ++ ) {
+
+        var end = inputOffset + numVerts;
+
+		var decodeScale = decodeScales[j];
+
+        if ( decodeScale ) {
+
+            // Assume if decodeScale is never set, simply ignore the
+            // attribute.
+
+            this.decompressAttribsInner_( str, inputOffset, end,
+                attribsOut, j, stride,
+                decodeOffsets[j], decodeScale );
+        }
+
+        inputOffset = end;
+
+    }
+
+    var indexStart = meshParams.indexRange[ 0 ];
+    var numIndices = 3 * meshParams.indexRange[ 1 ];
+
+    var indicesOut = new Uint16Array( numIndices );
+
+    this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 );
+
+    // Decode bboxen.
+
+    var bboxen = undefined;
+    var bboxOffset = meshParams.bboxes;
+
+    if ( bboxOffset ) {
+
+        bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales );
+    }
+
+    callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
+
+};
+
+THREE.UTF8Loader.prototype.copyAttrib = function ( stride, attribsOutFixed, lastAttrib, index ) {
+
+    for ( var j = 0; j < stride; j ++ ) {
+
+        lastAttrib[ j ] = attribsOutFixed[ stride * index + j ];
+
+    }
+
+};
+
+THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets, decodeScales, deltaStart,
+                                                        numVerts, attribsOut, attribsOutFixed, lastAttrib,
+                                                        index ) {
+
+    for ( var j = 0; j < 5; j ++ ) {
+
+        var code = str.charCodeAt( deltaStart + numVerts*j + index );
+        var delta = ( code >> 1) ^ (-(code & 1));
 
 
-	return [ attribs_out, indices_out ];
+        lastAttrib[ j ] += delta;
+        attribsOutFixed[ stride * index + j ] = lastAttrib[ j ];
+        attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] );
+    }
 
 
 };
 };
 
 
-THREE.UTF8Loader.prototype.createModel = function ( data, callback, scale, offsetX, offsetY, offsetZ ) {
+THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutFixed, crosses ) {
 
 
-	var Model = function ( texture_path ) {
+    var p0x = attribsOutFixed[ 8*i0 ];
+    var p0y = attribsOutFixed[ 8*i0 + 1 ];
+    var p0z = attribsOutFixed[ 8*i0 + 2 ];
 
 
-		//var s = (new Date).getTime();
+    var p1x = attribsOutFixed[ 8*i1 ];
+    var p1y = attribsOutFixed[ 8*i1 + 1 ];
+    var p1z = attribsOutFixed[ 8*i1 + 2 ];
 
 
-		var scope = this;
+    var p2x = attribsOutFixed[ 8*i2 ];
+    var p2y = attribsOutFixed[ 8*i2 + 1 ];
+    var p2z = attribsOutFixed[ 8*i2 + 2 ];
 
 
-		scope.materials = [];
+    p1x -= p0x;
+    p1y -= p0y;
+    p1z -= p0z;
 
 
-		THREE.Geometry.call( this );
+    p2x -= p0x;
+    p2y -= p0y;
+    p2z -= p0z;
 
 
-		var buffers = THREE.UTF8Loader.prototype.decompressMesh( data );
+    p0x = p1y*p2z - p1z*p2y;
+    p0y = p1z*p2x - p1x*p2z;
+    p0z = p1x*p2y - p1y*p2x;
 
 
-		var normals = [],
-			uvs = [];
+    crosses[ 3*i0 ]     += p0x;
+    crosses[ 3*i0 + 1 ] += p0y;
+    crosses[ 3*i0 + 2 ] += p0z;
 
 
-		init_vertices( buffers[ 0 ], 8, 0 );
-		init_uvs( buffers[ 0 ], 8, 3 );
-		init_normals( buffers[ 0 ], 8, 5 );
+    crosses[ 3*i1 ]     += p0x;
+    crosses[ 3*i1 + 1 ] += p0y;
+    crosses[ 3*i1 + 2 ] += p0z;
 
 
-		init_faces( buffers[ 1 ] );
+    crosses[ 3*i2 ]     += p0x;
+    crosses[ 3*i2 + 1 ] += p0y;
+    crosses[ 3*i2 + 2 ] += p0z;
 
 
-		this.computeCentroids();
-		this.computeFaceNormals();
-		//this.computeTangents();
+};
+
+THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodeParams, name, idx, callback ) {
+
+    var MAX_BACKREF = 96;
+
+    // Extract conversion parameters from attribArrays.
+
+    var stride = decodeParams.decodeScales.length;
+
+	var decodeOffsets = decodeParams.decodeOffsets;
+    var decodeScales = decodeParams.decodeScales;
+
+    var deltaStart = meshParams.attribRange[ 0 ];
+    var numVerts = meshParams.attribRange[ 1 ];
+
+    var codeStart = meshParams.codeRange[ 0 ];
+    var codeLength = meshParams.codeRange[ 1 ];
+
+    var numIndices = 3 * meshParams.codeRange[ 2 ];
+
+    var indicesOut = new Uint16Array( numIndices );
+
+    var crosses = new Int32Array( 3 * numVerts );
+
+    var lastAttrib = new Uint16Array( stride );
+
+    var attribsOutFixed = new Uint16Array( stride * numVerts );
+    var attribsOut = new Float32Array( stride * numVerts );
+
+    var highest = 0;
+    var outputStart = 0;
+
+    for ( var i = 0; i < numIndices; i += 3 ) {
+
+        var code = str.charCodeAt( codeStart ++ );
+
+        var max_backref = Math.min( i, MAX_BACKREF );
+
+        if ( code < max_backref ) {
+
+            // Parallelogram
+
+            var winding = code % 3;
+            var backref = i - ( code - winding );
+            var i0, i1, i2;
+
+            switch ( winding ) {
+
+                case 0:
+
+                    i0 = indicesOut[ backref + 2 ];
+                    i1 = indicesOut[ backref + 1 ];
+                    i2 = indicesOut[ backref + 0 ];
+                    break;
+
+                case 1:
+
+                    i0 = indicesOut[ backref + 0 ];
+                    i1 = indicesOut[ backref + 2 ];
+                    i2 = indicesOut[ backref + 1 ];
+                    break;
+
+                case 2:
+
+                    i0 = indicesOut[ backref + 1 ];
+                    i1 = indicesOut[ backref + 0 ];
+                    i2 = indicesOut[ backref + 2 ];
+                    break;
+
+            }
+
+            indicesOut[ outputStart ++ ] = i0;
+            indicesOut[ outputStart ++ ] = i1;
+
+            code = str.charCodeAt( codeStart ++ );
+
+            var index = highest - code;
+            indicesOut[ outputStart ++ ] = index;
+
+            if ( code === 0 ) {
+
+                for (var j = 0; j < 5; j ++ ) {
+
+                    var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest );
+
+                    var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) +
+                        attribsOutFixed[stride*i0 + j] +
+                        attribsOutFixed[stride*i1 + j] -
+                        attribsOutFixed[stride*i2 + j];
+
+                    lastAttrib[j] = prediction;
+
+                    attribsOutFixed[ stride * highest + j ] = prediction;
+                    attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] );
+
+                }
+
+                highest ++;
+
+            } else {
+
+                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index );
+
+            }
+
+            this.accumulateNormal( i0, i1, index, attribsOutFixed, crosses );
+
+        } else {
+
+            // Simple
+
+            var index0 = highest - ( code - max_backref );
+
+            indicesOut[ outputStart ++ ] = index0;
+
+            if ( code === max_backref ) {
+
+                this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
+                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
+                    highest ++ );
+
+            } else {
+
+                this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0);
+
+            }
+
+            code = str.charCodeAt( codeStart ++ );
+
+            var index1 = highest - code;
+            indicesOut[ outputStart ++ ] = index1;
+
+            if ( code === 0 ) {
+
+                this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
+                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
+                    highest ++ );
+
+            } else {
+
+                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index1 );
+
+            }
+
+            code = str.charCodeAt( codeStart ++ );
+
+            var index2 = highest - code;
+            indicesOut[ outputStart ++ ] = index2;
+
+            if ( code === 0 ) {
+
+                for ( var j = 0; j < 5; j ++ ) {
+
+                    lastAttrib[ j ] = ( attribsOutFixed[ stride * index0 + j ] + attribsOutFixed[ stride * index1 + j ] ) / 2;
+
+                }
+
+                this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
+                    numVerts, attribsOut, attribsOutFixed, lastAttrib,
+                    highest ++ );
+
+            } else {
+
+                this.copyAttrib( stride, attribsOutFixed, lastAttrib, index2 );
 
 
-		//var e = (new Date).getTime();
+            }
 
 
-		//console.log( "utf8 data parse time: " + (e-s) + " ms" );
+            this.accumulateNormal( index0, index1, index2, attribsOutFixed, crosses );
 
 
-		function init_vertices( data, stride, offset ) {
+        }
 
 
-			var i, x, y, z,
-				end = data.length;
+    }
 
 
-			for( i = offset; i < end; i += stride ) {
+    for ( var i = 0; i < numVerts; i ++ ) {
 
 
-				x = data[ i ];
-				y = data[ i + 1 ];
-				z = data[ i + 2 ];
+        var nx = crosses[ 3*i ];
+        var ny = crosses[ 3*i + 1 ];
+        var nz = crosses[ 3*i + 2 ];
 
 
-				// fix scale and offsets
+        var norm = 511.0 / Math.sqrt( nx*nx + ny*ny + nz*nz );
 
 
-				x = ( x / 16383 ) * scale;
-				y = ( y / 16383 ) * scale;
-				z = ( z / 16383 ) * scale;
+        var cx = str.charCodeAt( deltaStart + 5*numVerts + i );
+        var cy = str.charCodeAt( deltaStart + 6*numVerts + i );
+        var cz = str.charCodeAt( deltaStart + 7*numVerts + i );
 
 
-				x += offsetX;
-				y += offsetY;
-				z += offsetZ;
+        attribsOut[ stride*i + 5 ] = norm*nx + ((cx >> 1) ^ (-(cx & 1)));
+        attribsOut[ stride*i + 6 ] = norm*ny + ((cy >> 1) ^ (-(cy & 1)));
+        attribsOut[ stride*i + 7 ] = norm*nz + ((cz >> 1) ^ (-(cz & 1)));
+    }
 
 
-				vertex( scope, x, y, z );
+    callback( name, idx, attribsOut, indicesOut, undefined, meshParams );
 
 
-			}
+};
+
+THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, decodeParams, callback ) {
+
+    var loader = this;
+    var idx = 0;
+
+    function onprogress( req, e ) {
+
+        while ( idx < meshEntry.length ) {
+
+            var meshParams = meshEntry[ idx ];
+            var indexRange = meshParams.indexRange;
+
+            if ( indexRange ) {
+
+                var meshEnd = indexRange[ 0 ] + 3 * indexRange[ 1 ];
+
+                if ( req.responseText.length < meshEnd ) break;
+
+                loader.decompressMesh( req.responseText, meshParams, decodeParams, name, idx, callback );
+
+            } else {
+
+                var codeRange = meshParams.codeRange;
+                var meshEnd = codeRange[ 0 ] + codeRange[ 1 ];
+
+                if ( req.responseText.length < meshEnd ) break;
+
+                loader.decompressMesh2( req.responseText, meshParams, decodeParams, name, idx, callback );
+            }
+
+            ++idx;
+
+        }
+
+    };
 
 
-		};
+    getHttpRequest( path, function( req, e ) {
 
 
-		function init_normals( data, stride, offset ) {
+        if ( req.status === 200 || req.status === 0 ) {
 
 
-			var i, x, y, z,
-				end = data.length;
+            onprogress( req, e );
 
 
-			for( i = offset; i < end; i += stride ) {
+        }
 
 
-				x = data[ i ];
-				y = data[ i + 1 ];
-				z = data[ i + 2 ];
+        // TODO: handle errors.
 
 
-				// normalize to <-1,1>
+    }, onprogress );
 
 
-				x = ( x - 512 ) / 511;
-				y = ( y - 512 ) / 511;
-				z = ( z - 512 ) / 511;
+};
+
+THREE.UTF8Loader.prototype.downloadMeshes = function ( path, meshUrlMap, decodeParams, callback ) {
+
+    for ( var url in meshUrlMap ) {
 
 
-				normals.push( x, y, z );
+        var meshEntry = meshUrlMap[url];
+        this.downloadMesh( path + url, url, meshEntry, decodeParams, callback );
 
 
-			}
+    }
+
+};
 
 
-		};
+THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadModelInfo, allDoneCallback ) {
 
 
-		function init_uvs( data, stride, offset ) {
+	var nCompletedUrls = 0;
+    var nExpectedUrls = 0;
 
 
-			var i, u, v,
-				end = data.length;
+    var expectedMeshesPerUrl = {};
+    var decodedMeshesPerUrl = {};
 
 
-			for( i = offset; i < end; i += stride ) {
+	var modelParts = {};
 
 
-				u = data[ i ];
-				v = data[ i + 1 ];
+	var meshUrlMap = loadModelInfo.urls;
 
 
-				// normalize to <0,1>
+    for ( var url in meshUrlMap ) {
 
 
-				u /= 1023;
-				v /= 1023;
+        expectedMeshesPerUrl[ url ] = meshUrlMap[ url ].length;
+        decodedMeshesPerUrl[ url ] = 0;
 
 
-				uvs.push( u, v );
+		nExpectedUrls ++;
 
 
-			}
+        modelParts[ url ] = new THREE.Object3D();
 
 
-		};
+    }
 
 
-		function init_faces( indices ) {
+    var model = new THREE.Object3D();
 
 
-			var i,
-				a, b, c,
-				u1, v1, u2, v2, u3, v3,
-				m,
-				end = indices.length;
+    // Prepare materials first...
 
 
-			m = 0; // all faces defaulting to material 0
+    var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
+    materialCreator.setMaterials( loadModelInfo.materials );
 
 
-			for( i = 0; i < end; i += 3 ) {
+    materialCreator.preload();
 
 
-				a = indices[ i ];
-				b = indices[ i + 1 ];
-				c = indices[ i + 2 ];
+	// Create callback for creating mesh parts
 
 
-				f3n( scope, normals, a, b, c, m, a, b, c );
+    var geometryCreator = new THREE.UTF8Loader.GeometryCreator();
+	var bufferGeometryCreator = new THREE.UTF8Loader.BufferGeometryCreator();
 
 
-				u1 = uvs[ a * 2 ];
-				v1 = uvs[ a * 2 + 1 ];
+	var meshCallback = function( name, idx, attribArray, indexArray, bboxen, meshParams ) {
 
 
-				u2 = uvs[ b * 2 ];
-				v2 = uvs[ b * 2 + 1 ];
+        // Got ourselves a new mesh
 
 
-				u3 = uvs[ c * 2 ];
-				v3 = uvs[ c * 2 + 1 ];
+        // name identifies this part of the model (url)
+        // idx is the mesh index of this mesh of the part
+        // attribArray defines the vertices
+        // indexArray defines the faces
+        // bboxen defines the bounding box
+        // meshParams contains the material info
 
 
-				uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 );
+		var useBuffers = loadModelInfo.options.useBuffers !== undefined ? loadModelInfo.options.useBuffers : true;
 
 
-			}
+		if ( useBuffers ) {
 
 
+			var geometry = bufferGeometryCreator.create( attribArray, indexArray );
+
+		} else {
+
+			var geometry = geometryCreator.create( attribArray, indexArray );
 
 
 		}
 		}
 
 
-	};
+        var material = materialCreator.create( meshParams.material );
+
+		var mesh = new THREE.Mesh( geometry, material );
+        modelParts[ name ].add( mesh );
+
+        //model.add(new THREE.Mesh(geometry, material));
+
+        decodedMeshesPerUrl[ name ] ++;
+
+        if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) {
+
+            nCompletedUrls ++;
+
+            model.add( modelParts[ name ] );
+
+            if ( nCompletedUrls === nExpectedUrls ) {
+
+                // ALL DONE!!!
+
+                allDoneCallback( model );
+
+            }
 
 
-	function vertex ( scope, x, y, z ) {
+        }
 
 
-		scope.vertices.push( new THREE.Vector3( x, y, z ) );
+    };
 
 
-	};
+	return meshCallback;
 
 
-	function f3n ( scope, normals, a, b, c, mi, nai, nbi, nci ) {
+};
+
+THREE.UTF8Loader.prototype.downloadModel = function ( geometryBase, materialBase, model, callback ) {
+
+    var meshCallback = this.createMeshCallback( materialBase, model, callback );
+    this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback );
+
+};
+
+THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, options, callback ) {
+
+    getJsonRequest( jsonUrl, function( loaded ) {
+
+        if ( ! loaded.decodeParams ) {
+
+            if ( options && options.decodeParams ) {
+
+                loaded.decodeParams = options.decodeParams;
+
+            } else {
+
+                loaded.decodeParams = DEFAULT_DECODE_PARAMS;
+
+            }
+
+        }
+
+        loaded.options = options;
+
+        var geometryBase = jsonUrl.substr( 0, jsonUrl.lastIndexOf( "/" ) + 1 );
+        var materialBase = geometryBase;
+
+        if ( options && options.geometryBase ) {
 
 
-		var nax = normals[ nai * 3     ],
-			nay = normals[ nai * 3 + 1 ],
-			naz = normals[ nai * 3 + 2 ],
+            geometryBase = options.geometryBase;
 
 
-			nbx = normals[ nbi * 3     ],
-			nby = normals[ nbi * 3 + 1 ],
-			nbz = normals[ nbi * 3 + 2 ],
+            if ( geometryBase.charAt( geometryBase.length - 1 ) !== "/" ) {
 
 
-			ncx = normals[ nci * 3     ],
-			ncy = normals[ nci * 3 + 1 ],
-			ncz = normals[ nci * 3 + 2 ];
+                geometryBase = geometryBase + "/";
 
 
-		var na = new THREE.Vector3( nax, nay, naz ),
-			nb = new THREE.Vector3( nbx, nby, nbz ),
-			nc = new THREE.Vector3( ncx, ncy, ncz );
+            }
 
 
-		scope.faces.push( new THREE.Face3( a, b, c, [ na, nb, nc ], null, mi ) );
+        }
 
 
-	};
+        if ( options && options.materialBase ) {
 
 
-	function uv3 ( where, u1, v1, u2, v2, u3, v3 ) {
+            materialBase = options.materialBase;
 
 
-		var uv = [];
-		uv.push( new THREE.UV( u1, v1 ) );
-		uv.push( new THREE.UV( u2, v2 ) );
-		uv.push( new THREE.UV( u3, v3 ) );
-		where.push( uv );
+            if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) {
 
 
-	};
+                materialBase = materialBase  + "/";
 
 
-	Model.prototype = Object.create( THREE.Geometry.prototype );
+            }
 
 
-	callback( new Model() );
+        }
+
+        this.downloadModel( geometryBase, materialBase, loaded, callback );
+
+    }.bind( this ) );
 
 
 };
 };
+
+// XMLHttpRequest stuff
+
+function getHttpRequest( url, onload, opt_onprogress ) {
+
+    var LISTENERS = {
+
+        load: function( e ) { onload( req, e ); },
+        progress: function( e ) { opt_onprogress( req, e ); }
+
+    };
+
+    var req = new XMLHttpRequest();
+    addListeners( req, LISTENERS );
+
+    req.open( 'GET', url, true );
+    req.send( null );
+}
+
+function getJsonRequest( url, onjson ) {
+
+    getHttpRequest( url,
+        function( e ) { onjson( JSON.parse( e.responseText ) ); },
+        function() {} );
+
+}
+
+function addListeners( dom, listeners ) {
+
+    // TODO: handle event capture, object binding.
+
+    for ( var key in listeners ) {
+
+        dom.addEventListener( key, listeners[ key ] );
+
+    }
+}

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

@@ -15,28 +15,28 @@ THREE.VTKLoader.prototype = {
 	load: function ( url ) {
 	load: function ( url ) {
 
 
 		var scope = this;
 		var scope = this;
-		var xhr = new XMLHttpRequest();
+		var request = new XMLHttpRequest();
 
 
-		xhr.addEventListener( 'load', function ( event ) {
+		request.addEventListener( 'load', function ( event ) {
 
 
 			scope.dispatchEvent( { type: 'load', content: scope.parse( event.target.responseText ) } );
 			scope.dispatchEvent( { type: 'load', content: scope.parse( event.target.responseText ) } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.addEventListener( 'progress', function ( event ) {
+		request.addEventListener( 'progress', function ( event ) {
 
 
 			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
 			scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.addEventListener( 'error', function () {
+		request.addEventListener( 'error', function () {
 
 
 			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
 			scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
 
 
 		}, false );
 		}, false );
 
 
-		xhr.open( 'GET', url, true );
-		xhr.send( null );
+		request.open( 'GET', url, true );
+		request.send( null );
 
 
 	},
 	},
 
 

+ 8 - 7
examples/js/loaders/ctm/CTMLoader.js

@@ -18,13 +18,13 @@ THREE.CTMLoader.prototype = Object.create( THREE.Loader.prototype );
 
 
 // Load multiple CTM parts defined in JSON
 // Load multiple CTM parts defined in JSON
 
 
-THREE.CTMLoader.prototype.loadParts = function( url, callback, useWorker, useBuffers, basePath ) {
+THREE.CTMLoader.prototype.loadParts = function( url, callback, parameters ) {
 
 
 	var scope = this;
 	var scope = this;
 
 
 	var xhr = new XMLHttpRequest();
 	var xhr = new XMLHttpRequest();
 
 
-	basePath = basePath ? basePath : this.extractUrlBase( url );
+	var basePath = parameters.basePath ? parameters.basePath : this.extractUrlBase( url );
 
 
 	xhr.onreadystatechange = function() {
 	xhr.onreadystatechange = function() {
 
 
@@ -62,7 +62,8 @@ THREE.CTMLoader.prototype.loadParts = function( url, callback, useWorker, useBuf
 				// load joined CTM file
 				// load joined CTM file
 
 
 				var partUrl = basePath + jsonObject.data;
 				var partUrl = basePath + jsonObject.data;
-				scope.load( partUrl, callbackFinal, useWorker, useBuffers, jsonObject.offsets );
+				var parametersPart = { useWorker: parameters.useWorker, useBuffers: parameters.useBuffers, offsets: jsonObject.offsets };
+				scope.load( partUrl, callbackFinal, parametersPart );
 
 
 			}
 			}
 
 
@@ -82,11 +83,12 @@ THREE.CTMLoader.prototype.loadParts = function( url, callback, useWorker, useBuf
 //		- url (required)
 //		- url (required)
 //		- callback (required)
 //		- callback (required)
 
 
-THREE.CTMLoader.prototype.load = function( url, callback, useWorker, useBuffers, offsets ) {
+THREE.CTMLoader.prototype.load = function( url, callback, parameters ) {
 
 
 	var scope = this;
 	var scope = this;
 
 
-	offsets = offsets !== undefined ? offsets : [ 0 ];
+	var offsets = parameters.offsets !== undefined ? parameters.offsets : [ 0 ];
+	var useBuffers = parameters.useBuffers !== undefined ? parameters.useBuffers : true;
 
 
 	var xhr = new XMLHttpRequest(),
 	var xhr = new XMLHttpRequest(),
 		callbackProgress = null;
 		callbackProgress = null;
@@ -103,7 +105,7 @@ THREE.CTMLoader.prototype.load = function( url, callback, useWorker, useBuffers,
 
 
 				//var s = Date.now();
 				//var s = Date.now();
 
 
-				if ( useWorker ) {
+				if ( parameters.useWorker ) {
 
 
 					var worker = new Worker( "js/loaders/ctm/CTMWorker.js" );
 					var worker = new Worker( "js/loaders/ctm/CTMWorker.js" );
 
 
@@ -136,7 +138,6 @@ THREE.CTMLoader.prototype.load = function( url, callback, useWorker, useBuffers,
 
 
 				} else {
 				} else {
 
 
-
 					for ( var i = 0; i < offsets.length; i ++ ) {
 					for ( var i = 0; i < offsets.length; i ++ ) {
 
 
 						var stream = new CTM.Stream( binaryData );
 						var stream = new CTM.Stream( binaryData );

+ 0 - 2
examples/js/postprocessing/BloomPass.js

@@ -96,5 +96,3 @@ THREE.BloomPass.prototype = {
 
 
 THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 );
 THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 );
 THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 );
 THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 );
-
-

+ 2 - 21
examples/js/postprocessing/EffectComposer.js

@@ -109,34 +109,15 @@ THREE.EffectComposer.prototype = {
 		this.writeBuffer = this.renderTarget1;
 		this.writeBuffer = this.renderTarget1;
 		this.readBuffer = this.renderTarget2;
 		this.readBuffer = this.renderTarget2;
 
 
-		THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 );
-
-		THREE.EffectComposer.camera.left = window.innerWidth / - 2;
-		THREE.EffectComposer.camera.right = window.innerWidth / 2;
-		THREE.EffectComposer.camera.top = window.innerHeight / 2;
-		THREE.EffectComposer.camera.bottom = window.innerHeight / - 2;
-
-		THREE.EffectComposer.camera.updateProjectionMatrix();
-
 	}
 	}
 
 
 };
 };
 
 
 // shared ortho camera
 // shared ortho camera
 
 
-THREE.EffectComposer.initWidth = window.innerWidth || 1;
-THREE.EffectComposer.initHeight = window.innerHeight || 1;
-
-THREE.EffectComposer.camera = new THREE.OrthographicCamera( THREE.EffectComposer.initWidth / - 2, THREE.EffectComposer.initWidth / 2, THREE.EffectComposer.initHeight / 2, THREE.EffectComposer.initHeight / - 2, -10000, 10000 );
-
-// shared fullscreen quad scene
-
-THREE.EffectComposer.geometry = new THREE.PlaneGeometry( 1, 1 );
+THREE.EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );
 
 
-THREE.EffectComposer.quad = new THREE.Mesh( THREE.EffectComposer.geometry, null );
-THREE.EffectComposer.quad.position.z = -100;
-THREE.EffectComposer.quad.scale.set( THREE.EffectComposer.initWidth, THREE.EffectComposer.initHeight, 1 );
+THREE.EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );
 
 
 THREE.EffectComposer.scene = new THREE.Scene();
 THREE.EffectComposer.scene = new THREE.Scene();
 THREE.EffectComposer.scene.add( THREE.EffectComposer.quad );
 THREE.EffectComposer.scene.add( THREE.EffectComposer.quad );
-THREE.EffectComposer.scene.add( THREE.EffectComposer.camera );

+ 164 - 0
examples/js/renderers/CSS3DRenderer.js

@@ -0,0 +1,164 @@
+/**
+ * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.CSS3DObject = function ( element ) {
+
+	THREE.Object3D.call( this );
+
+	this.element = element;
+	this.element.style.position = "absolute";
+	this.element.style.WebkitTransformStyle = 'preserve-3d';
+	this.element.style.MozTransformStyle = 'preserve-3d';
+	this.element.style.oTransformStyle = 'preserve-3d';
+
+};
+
+THREE.CSS3DObject.prototype = Object.create( THREE.Object3D.prototype );
+
+//
+
+THREE.CSS3DRenderer = function () {
+
+	console.log( 'THREE.CSS3DRenderer', THREE.REVISION );
+
+	var _width, _height;
+	var _widthHalf, _heightHalf;
+	var _projector = new THREE.Projector();
+
+	this.domElement = document.createElement( 'div' );
+
+	this.domElement.style.WebkitTransformStyle = 'preserve-3d';
+	this.domElement.style.WebkitPerspectiveOrigin = '50% 50%';
+
+	this.domElement.style.MozTransformStyle = 'preserve-3d';
+	this.domElement.style.MozPerspectiveOrigin = '50% 50%';
+
+	this.domElement.style.oTransformStyle = 'preserve-3d';
+	this.domElement.style.oPerspectiveOrigin = '50% 50%';
+
+	// TODO: Shouldn't it be possible to remove cameraElement?
+
+	this.cameraElement = document.createElement( 'div' );
+	this.cameraElement.style.WebkitTransformStyle = 'preserve-3d';
+	this.cameraElement.style.MozTransformStyle = 'preserve-3d';
+	this.cameraElement.style.oTransformStyle = 'preserve-3d';
+
+	this.domElement.appendChild( this.cameraElement );
+
+	this.setSize = function ( width, height ) {
+
+		_width = width;
+		_height = height;
+
+		_widthHalf = _width / 2;
+		_heightHalf = _height / 2;
+
+		this.domElement.style.width = width + 'px';
+		this.domElement.style.height = height + 'px';
+
+		this.cameraElement.style.width = width + 'px';
+		this.cameraElement.style.height = height + 'px';
+
+	};
+
+	var epsilon = function ( value ) {
+
+		return Math.abs( value ) < 0.000001 ? 0 : value;
+
+        }
+
+	var getCameraCSSMatrix = function ( matrix ) {
+
+		var elements = matrix.elements;
+
+		return 'matrix3d(' +
+			epsilon( elements[ 0 ] ) + ',' +
+			epsilon( - elements[ 1 ] ) + ',' +
+			epsilon( elements[ 2 ] ) + ',' +
+			epsilon( elements[ 3 ] ) + ',' +
+			epsilon( elements[ 4 ] ) + ',' +
+			epsilon( - elements[ 5 ] ) + ',' +
+			epsilon( elements[ 6 ] ) + ',' +
+			epsilon( elements[ 7 ] ) + ',' +
+			epsilon( elements[ 8 ] ) + ',' +
+			epsilon( - elements[ 9 ] ) + ',' +
+			epsilon( elements[ 10 ] ) + ',' +
+			epsilon( elements[ 11 ] ) + ',' +
+			epsilon( elements[ 12 ] ) + ',' +
+			epsilon( - elements[ 13 ] ) + ',' +
+			epsilon( elements[ 14 ] ) + ',' +
+			epsilon( elements[ 15 ] ) +
+		')';
+
+	}
+
+	var getObjectCSSMatrix = function ( matrix ) {
+
+		var elements = matrix.elements;
+
+		return 'translate3d(-50%,-50%,0) scale3d(1,-1,1) matrix3d(' +
+			epsilon( elements[ 0 ] ) + ',' +
+			epsilon( elements[ 1 ] ) + ',' +
+			epsilon( elements[ 2 ] ) + ',' +
+			epsilon( elements[ 3 ] ) + ',' +
+			epsilon( elements[ 4 ] ) + ',' +
+			epsilon( elements[ 5 ] ) + ',' +
+			epsilon( elements[ 6 ] ) + ',' +
+			epsilon( elements[ 7 ] ) + ',' +
+			epsilon( elements[ 8 ] ) + ',' +
+			epsilon( elements[ 9 ] ) + ',' +
+			epsilon( elements[ 10 ] ) + ',' +
+			epsilon( elements[ 11 ] ) + ',' +
+			epsilon( elements[ 12 ] ) + ',' +
+			epsilon( elements[ 13 ] ) + ',' +
+			epsilon( elements[ 14 ] ) + ',' +
+			epsilon( elements[ 15 ] ) +
+		')';
+
+	}
+
+	this.render = function ( scene, camera ) {
+
+		var fov = 0.5 / Math.tan( camera.fov * Math.PI / 360 ) * _height;
+
+		this.domElement.style.WebkitPerspective = fov + "px";
+		this.domElement.style.MozPerspective = fov + "px";
+		this.domElement.style.oPerspective = fov + "px";
+
+		var style = "translate3d(0,0," + fov + "px)" + getCameraCSSMatrix( camera.matrixWorldInverse ) + " translate3d(" + _widthHalf + "px," + _heightHalf + "px, 0)";
+
+		this.cameraElement.style.WebkitTransform = style;
+		this.cameraElement.style.MozTransform = style;
+		this.cameraElement.style.oTransform = style;
+
+		var objects = _projector.projectScene( scene, camera, false ).objects;
+
+		for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+			var object = objects[ i ].object;
+
+			if ( object instanceof THREE.CSS3DObject ) {
+
+				var element = object.element;
+
+				style = getObjectCSSMatrix( object.matrixWorld );
+
+				element.style.WebkitTransform = style;
+				element.style.MozTransform = style;
+				element.style.oTransform = style;
+
+				if ( element.parentNode !== this.cameraElement ) {
+
+					this.cameraElement.appendChild( element );
+
+				}
+
+			}
+
+		}
+
+	};
+
+};

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

@@ -1,5 +1,5 @@
 /**
 /**
- * @author mr.doob / http://mrdoob.com/
+ * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
 THREE.DOMRenderer = function () {
 THREE.DOMRenderer = function () {

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

@@ -1,5 +1,5 @@
 /**
 /**
- * @author mr.doob / http://mrdoob.com/
+ * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
 THREE.SVGRenderer = function () {
 THREE.SVGRenderer = function () {
@@ -97,7 +97,7 @@ THREE.SVGRenderer = function () {
 		_this.info.render.vertices = 0;
 		_this.info.render.vertices = 0;
 		_this.info.render.faces = 0;
 		_this.info.render.faces = 0;
 
 
-		_renderData = _projector.projectScene( scene, camera, this.sortElements );
+		_renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
 		_elements = _renderData.elements;
 		_elements = _renderData.elements;
 		_lights = _renderData.lights;
 		_lights = _renderData.lights;
 
 
@@ -350,15 +350,18 @@ THREE.SVGRenderer = function () {
 
 
 			if ( _enableLighting ) {
 			if ( _enableLighting ) {
 
 
+				var diffuse = material.color;
+				var emissive = material.emissive;
+
 				_color.r = _ambientLight.r;
 				_color.r = _ambientLight.r;
 				_color.g = _ambientLight.g;
 				_color.g = _ambientLight.g;
 				_color.b = _ambientLight.b;
 				_color.b = _ambientLight.b;
 
 
 				calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
 				calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
 
 
-				_color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
-				_color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
-				_color.b = Math.max( 0, Math.min( material.color.b * _color.b, 1 ) );
+				_color.r = diffuse.r * _color.r + emissive.r;
+				_color.g = diffuse.g * _color.g + emissive.g;
+				_color.b = diffuse.b * _color.b + emissive.b;
 
 
 			} else {
 			} else {
 
 
@@ -407,15 +410,18 @@ THREE.SVGRenderer = function () {
 
 
 			if ( _enableLighting ) {
 			if ( _enableLighting ) {
 
 
+				var diffuse = material.color;
+				var emissive = material.emissive;
+
 				_color.r = _ambientLight.r;
 				_color.r = _ambientLight.r;
 				_color.g = _ambientLight.g;
 				_color.g = _ambientLight.g;
 				_color.b = _ambientLight.b;
 				_color.b = _ambientLight.b;
 
 
 				calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
 				calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
 
 
-				_color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
-				_color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
-				_color.b = Math.max( 0, Math.min( material.color.b * _color.b, 1 ) );
+				_color.r = diffuse.r * _color.r + emissive.r;
+				_color.g = diffuse.g * _color.g + emissive.g;
+				_color.b = diffuse.b * _color.b + emissive.b;
 
 
 			} else {
 			} else {
 
 

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

@@ -1,5 +1,5 @@
 /**
 /**
- * @author mr.doob / http://mrdoob.com/
+ * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
 THREE.SoftwareRenderer = function () {
 THREE.SoftwareRenderer = function () {

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

@@ -1,5 +1,5 @@
 /**
 /**
- * @author mr.doob / http://mrdoob.com/
+ * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
 THREE.SoftwareRenderer2 = function () {
 THREE.SoftwareRenderer2 = function () {

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

@@ -1,5 +1,5 @@
 /**
 /**
- * @author mr.doob / http://mrdoob.com/
+ * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
 THREE.SoftwareRenderer3 = function () {
 THREE.SoftwareRenderer3 = function () {

+ 1 - 1
examples/misc_camera_fly.html

@@ -118,7 +118,7 @@
 				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
 
 				uniforms[ "tNormal" ].value = normalTexture;
 				uniforms[ "tNormal" ].value = normalTexture;
-				uniforms[ "uNormalScale" ].value = 0.85;
+				uniforms[ "uNormalScale" ].value.set( 0.85, 0.85 );
 
 
 				uniforms[ "tDiffuse" ].value = planetTexture;
 				uniforms[ "tDiffuse" ].value = planetTexture;
 				uniforms[ "tSpecular" ].value = specularTexture;
 				uniforms[ "tSpecular" ].value = specularTexture;

+ 103 - 0
examples/misc_css3d.html

@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<style>
+			body {
+				background-color: #ffffff;
+				margin: 0;
+				overflow: hidden;
+			}
+		</style>
+	</head>
+	<body>
+		<script src="../build/three.min.js"></script>
+		<script src="js/renderers/CSS3DRenderer.js"></script>
+		<script>
+
+			var camera, scene, renderer;
+			var geometry, material, mesh;
+
+			var scene2, renderer2;
+
+			var controls;
+
+			init();
+			animate();
+
+			function init() {
+
+				camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 200, 200, 200 );
+
+				controls = new THREE.TrackballControls( camera );
+
+				controls.rotateSpeed = 1.0;
+				controls.zoomSpeed = 1.2;
+				controls.panSpeed = 0.8;
+
+				controls.noZoom = false;
+				controls.noPan = false;
+
+				controls.staticMoving = false;
+				controls.dynamicDampingFactor = 0.3;
+
+				controls.keys = [ 65, 83, 68 ];
+
+				scene = new THREE.Scene();
+
+				geometry = new THREE.CubeGeometry( 200, 200, 200 );
+				material = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, wireframeLinewidth: 1 } );
+
+				mesh = new THREE.Mesh( geometry, material );
+				scene.add( mesh );
+
+				renderer = new THREE.CanvasRenderer();
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				//
+
+				scene2 = new THREE.Scene();
+
+				for ( var i = 0; i < 20; i ++ ) {
+
+					var element = document.createElement( 'div' );
+					element.style.width = '100px';
+					element.style.height = '100px';
+					element.style.background = new THREE.Color( Math.random() * 0xffffff ).getContextStyle();
+
+					var object = new THREE.CSS3DObject( element );
+					object.position.x = Math.random() * 200 - 100;
+					object.position.y = Math.random() * 200 - 100;
+					object.position.z = Math.random() * 200 - 100;
+					object.scale.x = Math.random() + 0.5;
+					object.scale.y = Math.random() + 0.5;
+					scene2.add( object );
+
+				}
+
+				//
+
+				renderer2 = new THREE.CSS3DRenderer();
+				renderer2.setSize( window.innerWidth, window.innerHeight );
+				renderer2.domElement.style.position = 'absolute';
+				renderer2.domElement.style.top = 0;
+				document.body.appendChild( renderer2.domElement );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				controls.update();
+
+				renderer.render( scene, camera );
+				renderer2.render( scene2, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

BIN
examples/models/utf8/James_Body_Lores.jpg


BIN
examples/models/utf8/James_EyeLashBotTran.png


BIN
examples/models/utf8/James_EyeLashTopTran.png


BIN
examples/models/utf8/James_Eye_Green.jpg


BIN
examples/models/utf8/James_Eye_Inner_Green.jpg


BIN
examples/models/utf8/James_Face_Color_Hair_Lores.jpg


BIN
examples/models/utf8/James_Mouth_Gum_Lores.jpg


BIN
examples/models/utf8/James_Tongue_Lores.jpg


BIN
examples/models/utf8/MCasShoe1TEX_Lores.jpg


BIN
examples/models/utf8/MJeans1TEX_Lores.jpg


BIN
examples/models/utf8/MTshirt3TEX_Lores.jpg


BIN
examples/models/utf8/Nail_Hand_01_Lores.jpg


+ 107 - 0
examples/models/utf8/ben.js

@@ -0,0 +1,107 @@
+{
+  "materials": {
+    "gums": { "map_Kd": "James_Mouth_Gum_Lores.jpg" },
+    "tongue": { "map_Kd": "James_Tongue_Lores.jpg" },
+    "teethbottom": { "Kd": [251, 248, 248] },
+    "teethtop": { "Kd": [251, 248, 248] },
+    "topeyelashes": { "Kd": [66, 52, 42], "map_Kd": "James_EyeLashTopTran.png", "d": 0.999 },
+    "bottomeyelashes": { "Kd": [66, 52, 42], "map_Kd": "James_EyeLashBotTran.png", "d": 0.999 },
+    "head": { "map_Kd": "James_Face_Color_Hair_Lores.jpg", "Ks": [25,25,25], "Ns": 70 },
+    "eyetrans": { "Kd": [0, 0, 0] },
+    "pupil": { "Kd": [1, 1, 1] },
+    "iris": { "map_Kd": "James_Eye_Inner_Green.jpg" },
+    "eyeball": { "map_Kd": "James_Eye_Green.jpg" },
+    "pants": { "map_Kd": "MJeans1TEX_Lores.jpg", "Ks": [30,30,30], "Ns": 20 },
+    "tshirt3": { "map_Kd": "MTshirt3TEX_Lores.jpg", "Ks": [30,30,30], "Ns": 20 },
+    "skinbody": { "map_Kd": "James_Body_Lores.jpg", "Ks": [25,25,25], "Ns": 70 },
+    "fingernails": { "map_Kd": "Nail_Hand_01_Lores.jpg" },
+    "soleshoe": { "map_Kd": "MCasShoe1TEX_Lores.jpg" },
+    "sole": { "map_Kd": "MCasShoe1TEX_Lores.jpg" },
+    "laces": { "map_Kd": "MCasShoe1TEX_Lores.jpg" },
+    "bow": { "map_Kd": "MCasShoe1TEX_Lores.jpg" }
+  },
+  "decodeParams": {
+    "decodeOffsets": [-2533,-149,-6225,0,0,-511,-511,-511],
+    "decodeScales": [0.000043,0.000043,0.000043,0.000978,0.000978,0.001957,0.001957,0.001957]
+  },
+  "urls": {
+    "ben.utf8": [
+      { "material": "bottomeyelashes",
+        "attribRange": [0, 130],
+        "codeRange": [1040, 388, 192]
+      },
+      { "material": "bow",
+        "attribRange": [1428, 1848],
+        "codeRange": [16212, 6457, 3224]
+      },
+      { "material": "eyeball",
+        "attribRange": [22669, 3834],
+        "codeRange": [53341, 14697, 7284]
+      },
+      { "material": "eyetrans",
+        "attribRange": [68038, 5248],
+        "codeRange": [110022, 20180, 9964]
+      },
+      { "material": "fingernails",
+        "attribRange": [130202, 1023],
+        "codeRange": [138386, 2669, 1228]
+      },
+      { "material": "gums",
+        "attribRange": [141055, 1446],
+        "codeRange": [152623, 5270, 2624]
+      },
+      { "material": "head",
+        "attribRange": [157893, 2219],
+        "codeRange": [175645, 8353, 4168]
+      },
+      { "material": "iris",
+        "attribRange": [183998, 902],
+        "codeRange": [191214, 3332, 1664]
+      },
+      { "material": "laces",
+        "attribRange": [194546, 1016],
+        "codeRange": [202674, 3590, 1792]
+      },
+      { "material": "pants",
+        "attribRange": [206264, 8200],
+        "codeRange": [271864, 30625, 15293]
+      },
+      { "material": "pupil",
+        "attribRange": [302489, 148],
+        "codeRange": [303673, 581, 288]
+      },
+      { "material": "skinbody",
+        "attribRange": [304254, 4990],
+        "codeRange": [344174, 15770, 7830]
+      },
+      { "material": "sole",
+        "attribRange": [359944, 2588],
+        "codeRange": [380648, 9345, 4668]
+      },
+      { "material": "soleshoe",
+        "attribRange": [389993, 3164],
+        "codeRange": [415305, 10721, 5352]
+      },
+      { "material": "teethbottom",
+        "attribRange": [426026, 1235],
+        "codeRange": [435906, 3513, 1656]
+      },
+      { "material": "teethtop",
+        "attribRange": [439419, 1666],
+        "codeRange": [452747, 3937, 1816]
+      },
+      { "material": "tongue",
+        "attribRange": [456684, 845],
+        "codeRange": [463444, 3162, 1578]
+      },
+      { "material": "topeyelashes",
+        "attribRange": [466606, 130],
+        "codeRange": [467646, 388, 192]
+      },
+      { "material": "tshirt3",
+        "attribRange": [468034, 4283],
+        "codeRange": [502298, 14470, 7216]
+      }
+    ]
+  }
+}

BIN
examples/models/utf8/ben.utf8


+ 107 - 0
examples/models/utf8/ben_dds.js

@@ -0,0 +1,107 @@
+{
+  "materials": {
+    "gums": { "map_Kd": "dds/James_Mouth_Gum_Lores.dds" },
+    "tongue": { "map_Kd": "dds/James_Tongue_Lores.dds" },
+    "teethbottom": { "Kd": [251, 248, 248] },
+    "teethtop": { "Kd": [251, 248, 248] },
+    "topeyelashes": { "Kd": [66, 52, 42], "map_Kd": "dds/James_EyeLashTopTran.dds", "d": 0.999 },
+    "bottomeyelashes": { "Kd": [66, 52, 42], "map_Kd": "dds/James_EyeLashBotTran.dds", "d": 0.999 },
+    "head": { "map_Kd": "dds/James_Face_Color_Hair_Lores.dds", "Ks": [25,25,25], "Ns": 70 },
+    "eyetrans": { "Kd": [0, 0, 0] },
+    "pupil": { "Kd": [1, 1, 1] },
+    "iris": { "map_Kd": "dds/James_Eye_Inner_Green.dds" },
+    "eyeball": { "map_Kd": "dds/James_Eye_Green.dds" },
+    "pants": { "map_Kd": "dds/MJeans1TEX_Lores.dds", "Ks": [30,30,30], "Ns": 20 },
+    "tshirt3": { "map_Kd": "dds/MTshirt3TEX_Lores.dds", "Ks": [30,30,30], "Ns": 20 },
+    "skinbody": { "map_Kd": "dds/James_Body_Lores.dds", "Ks": [25,25,25], "Ns": 70 },
+    "fingernails": { "map_Kd": "dds/Nail_Hand_01_Lores.dds" },
+    "soleshoe": { "map_Kd": "dds/MCasShoe1TEX_Lores.dds" },
+    "sole": { "map_Kd": "dds/MCasShoe1TEX_Lores.dds" },
+    "laces": { "map_Kd": "dds/MCasShoe1TEX_Lores.dds" },
+    "bow": { "map_Kd": "dds/MCasShoe1TEX_Lores.dds" }
+  },
+  "decodeParams": {
+    "decodeOffsets": [-2533,-149,-6225,0,0,-511,-511,-511],
+    "decodeScales": [0.000043,0.000043,0.000043,0.000978,0.000978,0.001957,0.001957,0.001957]
+  },
+  "urls": {
+    "ben.utf8": [
+      { "material": "bottomeyelashes",
+        "attribRange": [0, 130],
+        "codeRange": [1040, 388, 192]
+      },
+      { "material": "bow",
+        "attribRange": [1428, 1848],
+        "codeRange": [16212, 6457, 3224]
+      },
+      { "material": "eyeball",
+        "attribRange": [22669, 3834],
+        "codeRange": [53341, 14697, 7284]
+      },
+      { "material": "eyetrans",
+        "attribRange": [68038, 5248],
+        "codeRange": [110022, 20180, 9964]
+      },
+      { "material": "fingernails",
+        "attribRange": [130202, 1023],
+        "codeRange": [138386, 2669, 1228]
+      },
+      { "material": "gums",
+        "attribRange": [141055, 1446],
+        "codeRange": [152623, 5270, 2624]
+      },
+      { "material": "head",
+        "attribRange": [157893, 2219],
+        "codeRange": [175645, 8353, 4168]
+      },
+      { "material": "iris",
+        "attribRange": [183998, 902],
+        "codeRange": [191214, 3332, 1664]
+      },
+      { "material": "laces",
+        "attribRange": [194546, 1016],
+        "codeRange": [202674, 3590, 1792]
+      },
+      { "material": "pants",
+        "attribRange": [206264, 8200],
+        "codeRange": [271864, 30625, 15293]
+      },
+      { "material": "pupil",
+        "attribRange": [302489, 148],
+        "codeRange": [303673, 581, 288]
+      },
+      { "material": "skinbody",
+        "attribRange": [304254, 4990],
+        "codeRange": [344174, 15770, 7830]
+      },
+      { "material": "sole",
+        "attribRange": [359944, 2588],
+        "codeRange": [380648, 9345, 4668]
+      },
+      { "material": "soleshoe",
+        "attribRange": [389993, 3164],
+        "codeRange": [415305, 10721, 5352]
+      },
+      { "material": "teethbottom",
+        "attribRange": [426026, 1235],
+        "codeRange": [435906, 3513, 1656]
+      },
+      { "material": "teethtop",
+        "attribRange": [439419, 1666],
+        "codeRange": [452747, 3937, 1816]
+      },
+      { "material": "tongue",
+        "attribRange": [456684, 845],
+        "codeRange": [463444, 3162, 1578]
+      },
+      { "material": "topeyelashes",
+        "attribRange": [466606, 130],
+        "codeRange": [467646, 388, 192]
+      },
+      { "material": "tshirt3",
+        "attribRange": [468034, 4283],
+        "codeRange": [502298, 14470, 7216]
+      }
+    ]
+  }
+}

BIN
examples/models/utf8/dds/James_Body_Lores.dds


BIN
examples/models/utf8/dds/James_EyeLashBotTran.dds


BIN
examples/models/utf8/dds/James_EyeLashTopTran.dds


BIN
examples/models/utf8/dds/James_Eye_Green.dds


BIN
examples/models/utf8/dds/James_Eye_Inner_Green.dds


BIN
examples/models/utf8/dds/James_Face_Color_Hair_Lores.dds


BIN
examples/models/utf8/dds/James_Mouth_Gum_Lores.dds


BIN
examples/models/utf8/dds/James_Tongue_Lores.dds


BIN
examples/models/utf8/dds/MCasShoe1TEX_Lores.dds


BIN
examples/models/utf8/dds/MJeans1TEX_Lores.dds


BIN
examples/models/utf8/dds/MTshirt3TEX_Lores.dds


BIN
examples/models/utf8/dds/Nail_Hand_01_Lores.dds


BIN
examples/models/utf8/hand.jpg


+ 27 - 0
examples/models/utf8/hand.js

@@ -0,0 +1,27 @@
+{
+  "materials": {
+    "preview": { "Kd": [184, 136, 234] },
+    "nails": { "Kd": [251, 238, 209], "map_Kd": "hand.jpg", "Ks": [30,30,30], "Ns": 100 },
+    "skin": { "Kd": [207, 181, 161],  "map_Kd": "hand.jpg", "Ks": [30,30,30], "Ns": 30 }
+  },
+  "decodeParams": {
+    "decodeOffsets": [-7473,-239,-8362,0,0,-511,-511,-511],
+    "decodeScales": [0.000050,0.000050,0.000050,0.000978,0.000978,0.001957,0.001957,0.001957]
+  },
+  "urls": {
+    "hand.utf8": [
+      { "material": "nails",
+        "attribRange": [0, 261],
+        "codeRange": [2088, 817, 404]
+      },
+      { "material": "preview",
+        "attribRange": [2905, 688],
+        "codeRange": [8409, 2570, 1280]
+      },
+      { "material": "skin",
+        "attribRange": [10979, 8899],
+        "codeRange": [82171, 31026, 15451]
+      }
+    ]
+  }
+}

BIN
examples/models/utf8/hand.utf8


+ 20 - 8
examples/obj/blenderscene/scene.Cube.js

@@ -2,15 +2,16 @@
 
 
     "metadata" :
     "metadata" :
     {
     {
-        "formatVersion" : 3,
-        "generatedBy"   : "Blender 2.60 Exporter",
+        "formatVersion" : 3.1,
+        "generatedBy"   : "Blender 2.63 Exporter",
         "vertices"      : 8,
         "vertices"      : 8,
         "faces"         : 6,
         "faces"         : 6,
         "normals"       : 0,
         "normals"       : 0,
         "colors"        : 0,
         "colors"        : 0,
-        "uvs"           : 0,
+        "uvs"           : [],
         "materials"     : 1,
         "materials"     : 1,
-        "morphTargets"  : 0
+        "morphTargets"  : 0,
+        "bones"         : 0
     },
     },
 
 
     "scale" : 1.000000,
     "scale" : 1.000000,
@@ -19,16 +20,20 @@
 	"DbgColor" : 15658734,
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgIndex" : 0,
 	"DbgName" : "Material",
 	"DbgName" : "Material",
-	"colorAmbient" : [0.0, 0.0, 0.0],
+	"blending" : "NormalBlending",
+	"colorAmbient" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746],
 	"colorDiffuse" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746],
 	"colorDiffuse" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746],
 	"colorSpecular" : [0.5, 0.5, 0.5],
 	"colorSpecular" : [0.5, 0.5, 0.5],
+	"depthTest" : true,
+	"depthWrite" : true,
 	"shading" : "Lambert",
 	"shading" : "Lambert",
 	"specularCoef" : 50,
 	"specularCoef" : 50,
 	"transparency" : 1.0,
 	"transparency" : 1.0,
+	"transparent" : false,
 	"vertexColors" : false
 	"vertexColors" : false
 	}],
 	}],
 
 
-    "vertices": [1.000000,1.000000,-1.000000,1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,-1.000000,1.000000,-1.000000,1.000000,1.000000,1.000000,0.999999,-1.000001,1.000000,-1.000000,-1.000000,1.000000,-1.000000,1.000000,1.000000],
+    "vertices": [1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,1,0.999999,-1,1,-1,-1,1,-1,1,1],
 
 
     "morphTargets": [],
     "morphTargets": [],
 
 
@@ -36,10 +41,17 @@
 
 
     "colors": [],
     "colors": [],
 
 
-    "uvs": [[]],
+    "uvs": [],
 
 
-    "faces": [3,0,1,2,3,0,3,4,7,6,5,0,3,0,4,5,1,0,3,1,5,6,2,0,3,2,6,7,3,0,3,4,0,3,7,0]
+    "faces": [3,0,1,2,3,0,3,4,7,6,5,0,3,0,4,5,1,0,3,1,5,6,2,0,3,2,6,7,3,0,3,4,0,3,7,0],
 
 
+    "bones" : [],
+
+    "skinIndices" : [],
+
+    "skinWeights" : [],
+
+    "animation" : {}
 
 
 
 
 }
 }

File diff suppressed because it is too large
+ 10 - 5
examples/obj/blenderscene/scene.Monkey.js


+ 20 - 8
examples/obj/blenderscene/scene.Plane.js

@@ -2,15 +2,16 @@
 
 
     "metadata" :
     "metadata" :
     {
     {
-        "formatVersion" : 3,
-        "generatedBy"   : "Blender 2.60 Exporter",
+        "formatVersion" : 3.1,
+        "generatedBy"   : "Blender 2.63 Exporter",
         "vertices"      : 4,
         "vertices"      : 4,
         "faces"         : 1,
         "faces"         : 1,
         "normals"       : 0,
         "normals"       : 0,
         "colors"        : 0,
         "colors"        : 0,
-        "uvs"           : 0,
+        "uvs"           : [],
         "materials"     : 1,
         "materials"     : 1,
-        "morphTargets"  : 0
+        "morphTargets"  : 0,
+        "bones"         : 0
     },
     },
 
 
     "scale" : 1.000000,
     "scale" : 1.000000,
@@ -19,16 +20,20 @@
 	"DbgColor" : 15658734,
 	"DbgColor" : 15658734,
 	"DbgIndex" : 0,
 	"DbgIndex" : 0,
 	"DbgName" : "Material.001",
 	"DbgName" : "Material.001",
-	"colorAmbient" : [0.0, 0.0, 0.0],
+	"blending" : "NormalBlending",
+	"colorAmbient" : [0.14462547517754842, 0.6400000190734865, 0.24541190036254967],
 	"colorDiffuse" : [0.14462547517754842, 0.6400000190734865, 0.24541190036254967],
 	"colorDiffuse" : [0.14462547517754842, 0.6400000190734865, 0.24541190036254967],
 	"colorSpecular" : [0.5, 0.5, 0.5],
 	"colorSpecular" : [0.5, 0.5, 0.5],
+	"depthTest" : true,
+	"depthWrite" : true,
 	"shading" : "Lambert",
 	"shading" : "Lambert",
 	"specularCoef" : 50,
 	"specularCoef" : 50,
 	"transparency" : 1.0,
 	"transparency" : 1.0,
+	"transparent" : false,
 	"vertexColors" : false
 	"vertexColors" : false
 	}],
 	}],
 
 
-    "vertices": [1.000000,1.000000,0.000000,1.000000,-1.000000,0.000000,-1.000000,-1.000000,0.000000,-1.000000,1.000000,0.000000],
+    "vertices": [1,1,0,1,-1,0,-1,-1,0,-1,1,0],
 
 
     "morphTargets": [],
     "morphTargets": [],
 
 
@@ -36,10 +41,17 @@
 
 
     "colors": [],
     "colors": [],
 
 
-    "uvs": [[]],
+    "uvs": [],
 
 
-    "faces": [3,0,3,2,1,0]
+    "faces": [3,0,3,2,1,0],
 
 
+    "bones" : [],
+
+    "skinIndices" : [],
+
+    "skinWeights" : [],
+
+    "animation" : {}
 
 
 
 
 }
 }

+ 194 - 194
examples/obj/blenderscene/scene.js

@@ -2,9 +2,9 @@
 
 
 "metadata" :
 "metadata" :
 {
 {
-    "formatVersion" : 3,
+    "formatVersion" : 3.1,
     "sourceFile"    : "scene.blend",
     "sourceFile"    : "scene.blend",
-    "generatedBy"   : "Blender 2.60 Exporter",
+    "generatedBy"   : "Blender 2.63 Exporter",
     "objects"       : 27,
     "objects"       : 27,
     "geometries"    : 3,
     "geometries"    : 3,
     "materials"     : 3,
     "materials"     : 3,
@@ -21,378 +21,378 @@
         "geometry"  : "geo_Cube",
         "geometry"  : "geo_Cube",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material" ],
         "materials" : [ "Material" ],
-        "position"  : [ 10.623673, 0.321692, 3.370784 ],
-        "rotation"  : [ 0.005265, 0.056306, 1.566005 ],
-        "quaternion": [ 0.708568, -0.017992, 0.021809, 0.705076 ],
-        "scale"     : [ 8.310000, 0.120000, 4.930000 ],
+        "position"  : [ 10.6237, 0.321692, 3.37078 ],
+        "rotation"  : [ 0.00526525, 0.0563064, 1.566 ],
+        "quaternion": [ 0.708568, -0.0179916, 0.0218086, 0.705076 ],
+        "scale"     : [ 8.31, 0.12, 4.93 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.018" : {
     "Monkey.018" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ 1.702659, -5.860421, 0.680278 ],
-        "rotation"  : [ 1.413516, -0.081377, -3.079004 ],
-        "quaternion": [ 0.050177, -0.010617, -0.649485, -0.758643 ],
+        "position"  : [ 1.70266, -5.86042, 0.680278 ],
+        "rotation"  : [ 1.41352, -0.0813772, -3.079 ],
+        "quaternion": [ 0.0501767, -0.0106173, -0.649485, -0.758643 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.017" : {
     "Monkey.017" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ 0.081295, -5.808783, 0.639505 ],
-        "rotation"  : [ 1.413516, -0.081377, -3.079004 ],
-        "quaternion": [ 0.050177, -0.010617, -0.649485, -0.758643 ],
+        "position"  : [ 0.0812951, -5.80878, 0.639505 ],
+        "rotation"  : [ 1.41352, -0.0813772, -3.079 ],
+        "quaternion": [ 0.0501767, -0.0106173, -0.649485, -0.758643 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.016" : {
     "Monkey.016" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -1.569030, -5.747240, 0.619385 ],
-        "rotation"  : [ 1.413516, -0.081377, -3.079004 ],
-        "quaternion": [ 0.050177, -0.010617, -0.649485, -0.758643 ],
+        "position"  : [ -1.56903, -5.74724, 0.619385 ],
+        "rotation"  : [ 1.41352, -0.0813772, -3.079 ],
+        "quaternion": [ 0.0501767, -0.0106173, -0.649485, -0.758643 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.015" : {
     "Monkey.015" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -3.129120, -5.709269, 0.552267 ],
-        "rotation"  : [ 1.413516, -0.081377, -3.079004 ],
-        "quaternion": [ 0.050177, -0.010617, -0.649485, -0.758643 ],
+        "position"  : [ -3.12912, -5.70927, 0.552267 ],
+        "rotation"  : [ 1.41352, -0.0813772, -3.079 ],
+        "quaternion": [ 0.0501767, -0.0106173, -0.649485, -0.758643 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.014" : {
     "Monkey.014" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -6.386331, -3.004400, 0.382167 ],
-        "rotation"  : [ 1.646237, 0.058425, 1.670594 ],
-        "quaternion": [ 0.471896, 0.477057, 0.556810, 0.489585 ],
+        "position"  : [ -6.38633, -3.0044, 0.382167 ],
+        "rotation"  : [ 1.64624, 0.0584253, 1.67059 ],
+        "quaternion": [ 0.471896, 0.477057, 0.55681, 0.489585 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.013" : {
     "Monkey.013" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -6.499331, -1.593073, 0.471640 ],
-        "rotation"  : [ 1.646237, 0.058425, 1.670594 ],
-        "quaternion": [ 0.471896, 0.477057, 0.556810, 0.489585 ],
+        "position"  : [ -6.49933, -1.59307, 0.47164 ],
+        "rotation"  : [ 1.64624, 0.0584253, 1.67059 ],
+        "quaternion": [ 0.471896, 0.477057, 0.55681, 0.489585 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.012" : {
     "Monkey.012" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -6.629794, -0.234131, 0.533840 ],
-        "rotation"  : [ 1.646237, 0.058425, 1.670594 ],
-        "quaternion": [ 0.471896, 0.477057, 0.556810, 0.489585 ],
+        "position"  : [ -6.62979, -0.234131, 0.53384 ],
+        "rotation"  : [ 1.64624, 0.0584253, 1.67059 ],
+        "quaternion": [ 0.471896, 0.477057, 0.55681, 0.489585 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.011" : {
     "Monkey.011" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -6.713673, 1.008146, 0.629835 ],
-        "rotation"  : [ 1.646237, 0.058425, 1.670594 ],
-        "quaternion": [ 0.471896, 0.477057, 0.556810, 0.489585 ],
+        "position"  : [ -6.71367, 1.00815, 0.629835 ],
+        "rotation"  : [ 1.64624, 0.0584253, 1.67059 ],
+        "quaternion": [ 0.471896, 0.477057, 0.55681, 0.489585 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "scale"     : [ 0.435837, 0.435837, 0.435837 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.010" : {
     "Monkey.010" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -2.010442, -24.343616, 1.387332 ],
-        "rotation"  : [ -1.621122, -2.949867, -0.136972 ],
-        "quaternion": [ 0.016439, -0.116140, -0.679574, -0.724169 ],
-        "scale"     : [ 9.160008, 9.160008, 9.160007 ],
+        "position"  : [ -2.01044, -24.3436, 1.38733 ],
+        "rotation"  : [ -1.62112, -2.94987, -0.136972 ],
+        "quaternion": [ 0.0164388, -0.11614, -0.679574, -0.724169 ],
+        "scale"     : [ 9.16001, 9.16001, 9.16001 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.009" : {
     "Monkey.009" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -4.292194, 7.975398, 1.826282 ],
-        "rotation"  : [ 1.594819, -0.080713, 0.213986 ],
-        "quaternion": [ 0.690920, 0.713888, 0.048328, 0.103242 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ -4.29219, 7.9754, 1.82628 ],
+        "rotation"  : [ 1.59482, -0.0807133, 0.213986 ],
+        "quaternion": [ 0.69092, 0.713888, 0.0483276, 0.103242 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.008" : {
     "Monkey.008" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ 2.151757, 8.065320, 1.891882 ],
-        "rotation"  : [ 1.594819, -0.080713, 0.213986 ],
-        "quaternion": [ 0.690920, 0.713888, 0.048328, 0.103242 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ 2.15176, 8.06532, 1.89188 ],
+        "rotation"  : [ 1.59482, -0.0807133, 0.213986 ],
+        "quaternion": [ 0.69092, 0.713888, 0.0483276, 0.103242 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.007" : {
     "Monkey.007" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -0.712512, 8.097841, 2.115002 ],
-        "rotation"  : [ 1.594819, -0.080713, 0.213986 ],
-        "quaternion": [ 0.690920, 0.713888, 0.048328, 0.103242 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ -0.712512, 8.09784, 2.115 ],
+        "rotation"  : [ 1.59482, -0.0807133, 0.213986 ],
+        "quaternion": [ 0.69092, 0.713888, 0.0483276, 0.103242 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Cube.005" : {
     "Cube.005" : {
         "geometry"  : "geo_Cube",
         "geometry"  : "geo_Cube",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material" ],
         "materials" : [ "Material" ],
-        "position"  : [ -1.000975, 8.755547, 1.319482 ],
-        "rotation"  : [ 0.000000, -0.000000, 0.000000 ],
-        "quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
-        "scale"     : [ 6.130000, 0.070000, 1.690000 ],
+        "position"  : [ -1.00097, 8.75555, 1.31948 ],
+        "rotation"  : [ 0, -0, 0 ],
+        "quaternion": [ 1, 0, 0, 0 ],
+        "scale"     : [ 6.13, 0.07, 1.69 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Cube.004" : {
     "Cube.004" : {
         "geometry"  : "geo_Cube",
         "geometry"  : "geo_Cube",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material" ],
         "materials" : [ "Material" ],
-        "position"  : [ 2.484517, -7.486932, 2.724846 ],
-        "rotation"  : [ 0.220417, 0.075224, -0.181029 ],
-        "quaternion": [ 0.988791, 0.112836, 0.027288, -0.093898 ],
-        "scale"     : [ 0.350000, 0.890000, 3.309999 ],
+        "position"  : [ 2.48452, -7.48693, 2.72485 ],
+        "rotation"  : [ 0.220417, 0.0752244, -0.181029 ],
+        "quaternion": [ 0.988791, 0.112836, 0.0272876, -0.093898 ],
+        "scale"     : [ 0.35, 0.89, 3.31 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.006" : {
     "Monkey.006" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ 7.724935, 7.123103, 1.694883 ],
-        "rotation"  : [ 1.835590, -0.083161, 2.048913 ],
+        "position"  : [ 7.72494, 7.1231, 1.69488 ],
+        "rotation"  : [ 1.83559, -0.0831609, 2.04891 ],
         "quaternion": [ 0.287189, 0.433893, 0.664936, 0.535835 ],
         "quaternion": [ 0.287189, 0.433893, 0.664936, 0.535835 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.005" : {
     "Monkey.005" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -6.334642, 6.636147, 0.566791 ],
-        "rotation"  : [ 1.327136, 0.032561, -2.147285 ],
+        "position"  : [ -6.33464, 6.63615, 0.566791 ],
+        "rotation"  : [ 1.32714, 0.0325614, -2.14729 ],
         "quaternion": [ 0.366859, 0.304988, -0.535181, -0.697122 ],
         "quaternion": [ 0.366859, 0.304988, -0.535181, -0.697122 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.004" : {
     "Monkey.004" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -5.384042, -6.194087, 0.444915 ],
-        "rotation"  : [ 0.991213, -0.181430, -1.037108 ],
-        "quaternion": [ 0.782246, 0.371851, -0.303947, -0.396780 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ -5.38404, -6.19409, 0.444915 ],
+        "rotation"  : [ 0.991213, -0.18143, -1.03711 ],
+        "quaternion": [ 0.782246, 0.371851, -0.303947, -0.39678 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.003" : {
     "Monkey.003" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ 3.147747, -4.230884, 1.014840 ],
-        "rotation"  : [ -1.422281, 2.834549, 0.213809 ],
-        "quaternion": [ 0.046369, -0.179128, 0.733783, 0.653701 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ 3.14775, -4.23088, 1.01484 ],
+        "rotation"  : [ -1.42228, 2.83455, 0.213809 ],
+        "quaternion": [ 0.0463686, -0.179128, 0.733783, 0.653701 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.002" : {
     "Monkey.002" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -2.668043, -2.153389, 3.008879 ],
-        "rotation"  : [ 1.881970, -0.457870, 2.217052 ],
-        "quaternion": [ 0.091675, 0.470648, 0.644833, 0.595211 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ -2.66804, -2.15339, 3.00888 ],
+        "rotation"  : [ 1.88197, -0.45787, 2.21705 ],
+        "quaternion": [ 0.0916755, 0.470648, 0.644833, 0.595211 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Cube.003" : {
     "Cube.003" : {
         "geometry"  : "geo_Cube",
         "geometry"  : "geo_Cube",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material" ],
         "materials" : [ "Material" ],
-        "position"  : [ -3.031251, -1.943665, 0.702044 ],
-        "rotation"  : [ 1.840852, 1.811250, -0.141131 ],
+        "position"  : [ -3.03125, -1.94366, 0.702044 ],
+        "rotation"  : [ 1.84085, 1.81125, -0.141131 ],
         "quaternion": [ 0.328619, 0.523567, 0.440581, -0.650981 ],
         "quaternion": [ 0.328619, 0.523567, 0.440581, -0.650981 ],
-        "scale"     : [ 1.781142, 0.361142, 0.231142 ],
+        "scale"     : [ 1.78114, 0.361142, 0.231142 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey.001" : {
     "Monkey.001" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ 1.245307, 0.137285, 0.620196 ],
-        "rotation"  : [ 2.339869, 0.286025, 1.394760 ],
-        "quaternion": [ 0.380330, 0.662839, 0.627894, 0.147451 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ 1.24531, 0.137285, 0.620196 ],
+        "rotation"  : [ 2.33987, 0.286025, 1.39476 ],
+        "quaternion": [ 0.38033, 0.662839, 0.627894, 0.147451 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Monkey" : {
     "Monkey" : {
         "geometry"  : "geo_Monkey",
         "geometry"  : "geo_Monkey",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.002" ],
         "materials" : [ "Material.002" ],
-        "position"  : [ -0.282500, 4.272932, 1.813606 ],
-        "rotation"  : [ 0.646062, 0.219349, 0.010569 ],
-        "quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ -0.2825, 4.27293, 1.81361 ],
+        "rotation"  : [ 0.646062, 0.219349, 0.0105691 ],
+        "quaternion": [ 0.942751, 0.314982, 0.10546, -0.0297641 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Cube.002" : {
     "Cube.002" : {
         "geometry"  : "geo_Cube",
         "geometry"  : "geo_Cube",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material" ],
         "materials" : [ "Material" ],
-        "position"  : [ 0.042212, 0.199037, 5.536832 ],
-        "rotation"  : [ 0.000000, -0.000000, 0.000000 ],
-        "quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ 0.0422118, 0.199037, 5.53683 ],
+        "rotation"  : [ 0, -0, 0 ],
+        "quaternion": [ 1, 0, 0, 0 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Cube.001" : {
     "Cube.001" : {
         "geometry"  : "geo_Cube",
         "geometry"  : "geo_Cube",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material" ],
         "materials" : [ "Material" ],
-        "position"  : [ -0.395497, 3.944532, 1.009696 ],
-        "rotation"  : [ 0.000000, -0.000000, 0.000000 ],
-        "quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ -0.395497, 3.94453, 1.0097 ],
+        "rotation"  : [ 0, -0, 0 ],
+        "quaternion": [ 1, 0, 0, 0 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Plane" : {
     "Plane" : {
         "geometry"  : "geo_Plane",
         "geometry"  : "geo_Plane",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material.001" ],
         "materials" : [ "Material.001" ],
-        "position"  : [ 0.000000, -0.118260, 0.000000 ],
-        "rotation"  : [ 0.000000, -0.000000, 0.000000 ],
-        "quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
-        "scale"     : [ 7.922787, 7.922787, 7.922787 ],
+        "position"  : [ 0, -0.11826, 0 ],
+        "rotation"  : [ 0, -0, 0 ],
+        "quaternion": [ 1, 0, 0, 0 ],
+        "scale"     : [ 7.92279, 7.92279, 7.92279 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     },
     },
 
 
     "Cube" : {
     "Cube" : {
         "geometry"  : "geo_Cube",
         "geometry"  : "geo_Cube",
         "groups"    : [  ],
         "groups"    : [  ],
         "materials" : [ "Material" ],
         "materials" : [ "Material" ],
-        "position"  : [ 3.651978, -0.000000, 1.071144 ],
-        "rotation"  : [ 0.220417, 0.075224, -0.181029 ],
-        "quaternion": [ 0.988791, 0.112836, 0.027288, -0.093898 ],
-        "scale"     : [ 1.000000, 1.000000, 1.000000 ],
+        "position"  : [ 3.65198, -1.49012e-08, 1.07114 ],
+        "rotation"  : [ 0.220417, 0.0752244, -0.181029 ],
+        "quaternion": [ 0.988791, 0.112836, 0.0272876, -0.093898 ],
+        "scale"     : [ 1, 1, 1 ],
         "visible"       : true,
         "visible"       : true,
-        "castsShadow"   : false,
-        "meshCollider"  : false,
-        "trigger"       : "None"
+        "castShadow"    : false,
+        "receiveShadow" : false,
+        "doubleSided"   : false
     }
     }
 },
 },
 
 
@@ -400,17 +400,17 @@
 "geometries" :
 "geometries" :
 {
 {
     "geo_Cube" : {
     "geo_Cube" : {
-        "type" : "ascii_mesh",
+        "type" : "ascii",
         "url"  : "scene.Cube.js"
         "url"  : "scene.Cube.js"
     },
     },
 
 
     "geo_Monkey" : {
     "geo_Monkey" : {
-        "type" : "ascii_mesh",
+        "type" : "ascii",
         "url"  : "scene.Monkey.js"
         "url"  : "scene.Monkey.js"
     },
     },
 
 
     "geo_Plane" : {
     "geo_Plane" : {
-        "type" : "ascii_mesh",
+        "type" : "ascii",
         "url"  : "scene.Plane.js"
         "url"  : "scene.Plane.js"
     }
     }
 },
 },
@@ -420,17 +420,17 @@
 {
 {
     "Material" : {
     "Material" : {
         "type": "MeshLambertMaterial",
         "type": "MeshLambertMaterial",
-        "parameters": { "color": 10688800, "opacity": 1 }
+        "parameters": { "color": 10688800, "opacity": 1, "blending": "NormalBlending" }
     },
     },
 
 
     "Material.001" : {
     "Material.001" : {
         "type": "MeshLambertMaterial",
         "type": "MeshLambertMaterial",
-        "parameters": { "color": 2401086, "opacity": 1 }
+        "parameters": { "color": 2401086, "opacity": 1, "blending": "NormalBlending" }
     },
     },
 
 
     "Material.002" : {
     "Material.002" : {
         "type": "MeshLambertMaterial",
         "type": "MeshLambertMaterial",
-        "parameters": { "color": 10711076, "opacity": 1 }
+        "parameters": { "color": 10711076, "opacity": 1, "blending": "NormalBlending" }
     }
     }
 },
 },
 
 
@@ -443,8 +443,8 @@
         "aspect": 1.333000,
         "aspect": 1.333000,
         "near"  : 1.000000,
         "near"  : 1.000000,
         "far"   : 10000.000000,
         "far"   : 10000.000000,
-        "position": [ 0.000000, 0.000000, 10.000000 ],
-        "target"  : [ 0.000000, 0.000000, 0.000000 ]
+        "position": [ 0, 0, 10 ],
+        "target"  : [ 0, 0, 0 ]
     }
     }
 },
 },
 
 
@@ -452,8 +452,8 @@
 "lights" :
 "lights" :
 {
 {
     "default_light": {
     "default_light": {
-        "type"		 : "directional",
-        "direction"	 : [ 0.000000, 1.000000, 1.000000 ],
+        "type"    	 : "directional",
+        "direction"	 : [ 0, 1, 1 ],
         "color" 	 : 16777215,
         "color" 	 : 16777215,
         "intensity"	 : 0.80
         "intensity"	 : 0.80
     }
     }
@@ -462,14 +462,14 @@
 
 
 "transform" :
 "transform" :
 {
 {
-    "position"  : [ 0.000000, 0.000000, 0.000000 ],
-    "rotation"  : [ -1.570796, 0.000000, 0.000000 ],
-    "scale"     : [ 1.000000, 1.000000, 1.000000 ]
+    "position"  : [ 0, 0, 0 ],
+    "rotation"  : [ -1.5708, 0, 0 ],
+    "scale"     : [ 1, 1, 1 ]
 },
 },
 
 
 "defaults" :
 "defaults" :
 {
 {
-    "bgcolor" : [ 0.000000, 0.000000, 0.000000 ],
+    "bgcolor" : [ 0, 0, 0 ],
     "bgalpha" : 1.000000,
     "bgalpha" : 1.000000,
     "camera"  : "default_camera"
     "camera"  : "default_camera"
 }
 }

BIN
examples/obj/lightmap/lightmap-ao-shadow.png


+ 123 - 0
examples/obj/lightmap/lightmap.js

@@ -0,0 +1,123 @@
+{
+
+    "metadata" :
+    {
+        "formatVersion" : 3.1,
+        "generatedBy"   : "Blender 2.63 Exporter",
+        "vertices"      : 20,
+        "faces"         : 13,
+        "normals"       : 0,
+        "colors"        : 0,
+        "uvs"           : 4,
+        "materials"     : 1,
+        "morphTargets"  : 0,
+        "bones"         : 0
+    },
+
+    "scale" : 1.000000,
+
+    "materials": [	{
+	"DbgColor" : 15658734,
+	"DbgIndex" : 0,
+	"DbgName" : "redstone",
+	"blending" : "NormalBlending",
+	"colorAmbient" : [0.8, 0.3736, 0.2799],
+	"colorDiffuse" : [0.8, 0.3736, 0.2799],
+	"colorSpecular" : [0.067, 0.067, 0.067],
+	"depthTest" : true,
+	"depthWrite" : true,
+	"mapLight" : "lightmap-ao-shadow.png",
+	"mapBump" : "stone.jpg",
+	"mapSpecular" : "stone.jpg",
+	"mapBumpRepeat" : [2, 2],
+	"mapSpecularRepeat" : [2, 2],
+	"mapBumpWrap" : ["repeat", "repeat"],
+	"mapSpecularWrap" : ["repeat", "repeat"],
+	"mapBumpScale" : 2,
+	"mapBumpAnisotropy": 4,
+	"mapSpecularAnisotropy": 4,
+	"mapLightAnisotropy": 4,
+	"shading" : "Phong",
+	"specularCoef" : 100,
+	"transparency" : 1.0,
+	"transparent" : false,
+	"vertexColors" : false
+	},
+
+	{
+	"DbgColor" : 15597568,
+	"DbgIndex" : 1,
+	"DbgName" : "floor",
+	"blending" : "NormalBlending",
+	"colorAmbient" : [0.8, 0.72, 0.6],
+	"colorDiffuse" : [0.8, 0.72, 0.6],
+	"colorSpecular" : [0.067, 0.067, 0.067],
+	"depthTest" : true,
+	"depthWrite" : true,
+	"mapLight" : "lightmap-ao-shadow.png",
+	"mapBump" : "stone.jpg",
+	"mapSpecular" : "stone.jpg",
+	"mapBumpRepeat" : [16, 16],
+	"mapSpecularRepeat" : [16, 16],
+	"mapBumpWrap" : ["repeat", "repeat"],
+	"mapSpecularWrap" : ["repeat", "repeat"],
+	"mapBumpScale" : 2,
+	"mapBumpAnisotropy": 4,
+	"mapSpecularAnisotropy": 4,
+	"mapLightAnisotropy": 4,
+	"shading" : "Phong",
+	"specularCoef" : 100,
+	"transparency" : 1.0,
+	"transparent" : false,
+	"vertexColors" : false
+	},
+
+	{
+	"DbgColor" : 15597568,
+	"DbgIndex" : 1,
+	"DbgName" : "stone",
+	"blending" : "NormalBlending",
+	"colorAmbient" : [0.8, 0.5184, 0.36],
+	"colorDiffuse" : [0.8, 0.5184, 0.36],
+	"colorSpecular" : [0.067, 0.067, 0.067],
+	"depthTest" : true,
+	"depthWrite" : true,
+	"mapLight" : "lightmap-ao-shadow.png",
+	"mapBump" : "rocks.jpg",
+	"mapSpecular" : "rocks.jpg",
+	"mapBumpRepeat" : [2, 2],
+	"mapSpecularRepeat" : [2, 2],
+	"mapBumpWrap" : ["repeat", "repeat"],
+	"mapSpecularWrap" : ["repeat", "repeat"],
+	"mapBumpScale" : 2,
+	"mapBumpAnisotropy": 4,
+	"mapSpecularAnisotropy": 4,
+	"mapLightAnisotropy": 4,
+	"shading" : "Phong",
+	"specularCoef" : 100,
+	"transparency" : 1.0,
+	"transparent" : false,
+	"vertexColors" : false
+	}],
+
+    "vertices": [1.85679,0.0125948,0.544906,1.85679,0.0125948,-0.544906,2.9466,0.0125948,-0.544906,2.9466,0.0125948,0.544906,1.85679,1.10241,0.544906,1.85679,1.10241,-0.544906,2.9466,1.10241,-0.544906,2.9466,1.10241,0.544906,-8.39711,-3.67049e-07,-8.39711,8.39711,-3.67049e-07,-8.39711,-8.39711,3.67049e-07,8.39711,8.39711,3.67049e-07,8.39711,1,0.0180082,-1,1,0.0180083,1,-1,0.0180083,1,-1,0.0180082,-1,1,2.01801,-1,0.999999,2.01801,1,-1,2.01801,1,-1,2.01801,-1],
+
+    "morphTargets": [],
+
+    "normals": [],
+
+    "colors": [],
+
+    "uvs": [[1,1,0,1,0,0,1,0],[0.001001,0.498999,0.248999,0.498999,0.248999,0.251001,0.001001,0.251001,0.498999,0.001001,0.251001,0.001001,0.251001,0.248999,0.498999,0.248999,0.498999,0.251001,0.251001,0.251001,0.251001,0.498999,0.498999,0.498999,0.501001,0.498999,0.748999,0.498999,0.748999,0.251001,0.501001,0.251001,0.748999,0.001001,0.501001,0.001001,0.501001,0.248999,0.748999,0.248999,0.498999,0.501001,0.251001,0.501001,0.251001,0.748999,0.498999,0.748999,0.001001,0.248999,0.248999,0.248999,0.248999,0.001001,0.001001,0.001001,0.248999,0.501001,0.001001,0.501001,0.001001,0.748999,0.248999,0.748999,0.748999,0.501001,0.501001,0.501001,0.501001,0.748999,0.748999,0.748999,0.748999,0.751001,0.501001,0.751001,0.501001,0.998999,0.748999,0.998999,0.498999,0.751001,0.251001,0.751001,0.251001,0.998999,0.498999,0.998999,0.248999,0.751001,0.001001,0.751001,0.001001,0.998999,0.248999,0.998999,0.998999,0.251001,0.751001,0.251001,0.751001,0.498999,0.998999,0.498999]],
+
+    "faces": [11,1,0,4,5,0,0,1,2,3,0,1,2,3,11,5,6,2,1,0,2,3,0,1,4,5,6,7,11,6,7,3,2,0,2,3,0,1,8,9,10,11,11,0,3,7,4,0,0,1,2,3,12,13,14,15,11,0,1,2,3,0,2,3,0,1,16,17,18,19,11,7,6,5,4,0,2,3,0,1,20,21,22,23,11,9,8,10,11,1,0,1,2,3,24,25,26,27,11,12,13,14,15,2,3,0,1,2,28,29,30,31,	11,16,19,18,17,2,3,0,1,2,32,33,34,35,11,12,16,17,13,2,3,0,1,2,36,37,38,39,11,13,17,18,14,2,3,0,1,2,40,41,42,43,11,14,18,19,15,2,3,0,1,2,44,45,46,47,11,16,12,15,19,2,3,0,1,2, 48,49,50,51],
+
+    "bones" : [],
+
+    "skinIndices" : [],
+
+    "skinWeights" : [],
+
+    "animation" : {}
+
+}

+ 4 - 0
examples/obj/lightmap/readme.txt

@@ -0,0 +1,4 @@
+Textures from:
+
+http://opengameart.org/node/7506
+http://opengameart.org/node/8038

BIN
examples/obj/lightmap/rocks.jpg


BIN
examples/obj/lightmap/stone.jpg


BIN
examples/obj/male02/01_-_Default1noCulling.dds


File diff suppressed because it is too large
+ 87 - 0
examples/obj/male02/Male02_dds.js


BIN
examples/obj/male02/male-02-1noCulling.dds


+ 56 - 0
examples/obj/male02/male02_dds.mtl

@@ -0,0 +1,56 @@
+# Material Count: 5
+newmtl _01_-_Default1noCulli__01_-_Default1noCulli
+Ns 154.901961
+Ka 0.000000 0.000000 0.000000
+Kd 0.640000 0.640000 0.640000
+Ks 0.165000 0.165000 0.165000
+Ni 1.000000
+d 1.000000
+illum 2
+map_Kd 01_-_Default1noCulling.dds
+
+
+newmtl FrontColorNoCullingID_male-02-1noCulling.JP
+Ns 154.901961
+Ka 0.000000 0.000000 0.000000
+Kd 0.800000 0.800000 0.800000
+Ks 0.165000 0.165000 0.165000
+Ni 1.000000
+d 1.000000
+illum 2
+map_Kd male-02-1noCulling.dds
+
+
+newmtl male-02-1noCullingID_male-02-1noCulling.JP
+Ns 154.901961
+Ka 0.000000 0.000000 0.000000
+Kd 0.640000 0.640000 0.640000
+Ks 0.165000 0.165000 0.165000
+Ni 1.000000
+d 1.000000
+illum 2
+map_Kd male-02-1noCulling.dds
+
+
+newmtl orig_02_-_Defaul1noCu_orig_02_-_Defaul1noCu
+Ns 154.901961
+Ka 0.000000 0.000000 0.000000
+Kd 0.640000 0.640000 0.640000
+Ks 0.165000 0.165000 0.165000
+Ni 1.000000
+d 1.000000
+illum 2
+map_Kd orig_02_-_Defaul1noCulling.dds
+
+
+newmtl FrontColorNoCullingID_orig_02_-_Defaul1noCu
+Ns 154.901961
+Ka 0.000000 0.000000 0.000000
+Kd 0.800000 0.800000 0.800000
+Ks 0.165000 0.165000 0.165000
+Ni 1.000000
+d 1.000000
+illum 2
+map_Kd orig_02_-_Defaul1noCulling.dds
+
+

BIN
examples/obj/male02/orig_02_-_Defaul1noCulling.dds


+ 225 - 30
examples/scenes/test_scene.js

@@ -1,7 +1,7 @@
 {
 {
 
 
 	"metadata": {
 	"metadata": {
-		"formatVersion": 3,
+		"formatVersion": 3.1,
 		"type" : "scene"
 		"type" : "scene"
 	},
 	},
 
 
@@ -11,13 +11,15 @@
 
 
 		"cube1" : {
 		"cube1" : {
 			"geometry" : "cubeNormals",
 			"geometry" : "cubeNormals",
-			"materials": [ "lambert_red" ],
+			"materials": [ "phong_red" ],
 			"position" : [ 0, 0, 0 ],
 			"position" : [ 0, 0, 0 ],
 			"rotation" : [ 0, -0.3, 0 ],
 			"rotation" : [ 0, -0.3, 0 ],
 			"scale"	   : [ 1, 1, 1 ],
 			"scale"	   : [ 1, 1, 1 ],
 			"visible"  : true,
 			"visible"  : true,
 			"properties" : {
 			"properties" : {
-				"rotating" : true
+				"rotating" : true,
+				"rotateX"  : true,
+				"rotateY"  : true
 			}
 			}
 		},
 		},
 
 
@@ -57,6 +59,15 @@
 			"visible"  : true
 			"visible"  : true
 		},
 		},
 
 
+		"sphere_cube" : {
+			"geometry" : "sphere_uvs",
+			"materials": [ "phong_compressed_cube" ],
+			"position" : [ -30, -2, -15 ],
+			"rotation" : [ 0, 0, 0 ],
+			"scale"	   : [ 1.5, 1.5, 1.5 ],
+			"visible"  : true
+		},
+
 		"icosahedron" : {
 		"icosahedron" : {
 			"geometry" : "icosahedron",
 			"geometry" : "icosahedron",
 			"materials": [ "faceted_white" ],
 			"materials": [ "faceted_white" ],
@@ -66,7 +77,6 @@
 			"visible"  : true
 			"visible"  : true
 		},
 		},
 
 
-
 		"torus" : {
 		"torus" : {
 			"geometry" : "torus",
 			"geometry" : "torus",
 			"materials": [ "phong_orange" ],
 			"materials": [ "phong_orange" ],
@@ -145,12 +155,55 @@
 		"walt" : {
 		"walt" : {
 			"geometry" : "WaltHead",
 			"geometry" : "WaltHead",
 			"materials": [ "lambert_cube" ],
 			"materials": [ "lambert_cube" ],
-			"position" : [ -45, 10, 0 ],
-			"rotation" : [ 0, 0, 0 ],
+			"position" : [ -75, 10, -30 ],
+			"rotation" : [ 0, 0.5, 0 ],
 			"scale"	   : [ 0.5, 0.5, 0.5 ],
 			"scale"	   : [ 0.5, 0.5, 0.5 ],
 			"visible"  : true
 			"visible"  : true
 		},
 		},
 
 
+		"ben" : {
+			"geometry" : "ben",
+			"materials": [ "phong_ben" ],
+			"position" : [ -45, -10, 0 ],
+			"rotation" : [ 0, 0.5, 0 ],
+			"scale"	   : [ 55, 55, 55 ],
+			"visible"  : true
+		},
+
+		"hand" : {
+			"geometry" : "hand",
+			"materials": [ "phong_hand" ],
+			"position" : [ -28, -1, 29 ],
+			"rotation" : [ 0, 0.5, 0 ],
+			"scale"	   : [ 12, 12, 12 ],
+			"visible"  : true,
+			"properties" : {
+				"rotating" : true,
+				"rotateY"  : true
+			}
+		},
+
+		"ninja" : {
+			"geometry" : "NinjaLo",
+			"materials": [ "phong_normal" ],
+			"position" : [ 75, 10, -30 ],
+			"rotation" : [ 0, -0.5, 0 ],
+			"scale"	   : [ 1.25, 1.25, 1.25 ],
+			"visible"  : true
+		},
+
+		"sittingBox" : {
+			"geometry" : "sittingBox",
+			"materials": [ "phong_morph" ],
+			"position" : [ -60, -10, 10 ],
+			"rotation" : [ 0, 0.5, 0 ],
+			"scale"	   : [ 23, 23, 23 ],
+			"visible"  : true,
+			"morph"	   : true,
+			"duration" : 8000,
+			"mirroredLoop" : true
+		},
+
 		"quad_bg" : {
 		"quad_bg" : {
 			"geometry" : "quad",
 			"geometry" : "quad",
 			"materials": [ "textured_bg" ],
 			"materials": [ "textured_bg" ],
@@ -160,6 +213,24 @@
 			"visible"  : true
 			"visible"  : true
 		},
 		},
 
 
+		"quad_texture1" : {
+			"geometry" : "quad",
+			"materials": [ "textured_compressed_dxt3" ],
+			"position" : [ 15, -5, 20 ],
+			"rotation" : [ 0, 0, 0 ],
+			"scale"	   : [ 1, 1, 1 ],
+			"visible"  : true
+		},
+
+		"quad_texture2" : {
+			"geometry" : "quad",
+			"materials": [ "textured_compressed_dxt5" ],
+			"position" : [ 15, -5, 25 ],
+			"rotation" : [ 0, 0, 0 ],
+			"scale"	   : [ 1, 1, 1 ],
+			"visible"  : true
+		},
+
 		"ground" : {
 		"ground" : {
 			"geometry" : "plane",
 			"geometry" : "plane",
 			"materials": [ "basic_gray" ],
 			"materials": [ "basic_gray" ],
@@ -232,6 +303,13 @@
 			"segmentsHeight" : 16
 			"segmentsHeight" : 16
 		},
 		},
 
 
+		"sphere_uvs": {
+			"type"    : "sphere",
+			"radius"  : 5,
+			"segmentsWidth"  : 32,
+			"segmentsHeight" : 16
+		},
+
 		"icosahedron": {
 		"icosahedron": {
 			"type"    : "icosahedron",
 			"type"    : "icosahedron",
 			"radius"  : 20,
 			"radius"  : 20,
@@ -265,17 +343,43 @@
 		},
 		},
 
 
 		"WaltHead": {
 		"WaltHead": {
-			"type": "bin_mesh",
+			"type": "binary",
 			"url" : "obj/walt/WaltHead_bin.js"
 			"url" : "obj/walt/WaltHead_bin.js"
 		},
 		},
 
 
+		"NinjaLo": {
+			"type": "binary",
+			"url" : "obj/ninja/NinjaLo_bin.js"
+		},
+
 		"veyron": {
 		"veyron": {
-			"type": "bin_mesh",
+			"type": "binary",
 			"url" : "obj/veyron/VeyronNoUv_bin.js"
 			"url" : "obj/veyron/VeyronNoUv_bin.js"
 		},
 		},
 
 
+		"sittingBox": {
+			"type": "ascii",
+			"url" : "models/animated/sittingBox.js"
+		},
+
+		"ben": {
+			"type": "ctm",
+			"url" : "models/ctm/ben.ctm",
+			"useWorkers" : true,
+			"useBuffers" : true
+		},
+
+		"hand": {
+			"type": "utf8",
+			"url" : "models/utf8/hand.utf8",
+			"scale"   : 0.815141,
+			"offsetX" : -0.371823,
+			"offsetY" : -0.011920,
+			"offsetZ" : -0.416061
+		},
+
 		"colorcube": {
 		"colorcube": {
-			"type": "embedded_mesh",
+			"type": "embedded",
 			"id"  : "cube_fvc"
 			"id"  : "cube_fvc"
 		}
 		}
 
 
@@ -336,9 +440,34 @@
 			"parameters": { "color": 16777215, "shading": "flat" }
 			"parameters": { "color": 16777215, "shading": "flat" }
 		},
 		},
 
 
-		"lambert_red": {
-			"type": "MeshLambertMaterial",
-			"parameters": { "color": 16711680 }
+		"phong_red": {
+			"type": "MeshPhongMaterial",
+			"parameters": { "color": 16711680, "specular": 16711680, "shininess": 25, "bumpMap": "texture_bump", "bumpScale": -0.75 }
+		},
+
+		"phong_ben": {
+			"type": "MeshPhongMaterial",
+			"parameters": { "color": 1118481, "ambient": 1118481, "specular": 5601245, "shininess": 12, "bumpMap": "texture_bump_repeat", "bumpScale": 0.125 }
+		},
+
+		"phong_hand": {
+			"type": "MeshPhongMaterial",
+			"parameters": { "color": 14531481, "ambient": 14531481, "specular": 2236962, "shininess": 40, "wrapAround": true, "wrapRGB": [ 0.15, 0.02, 0.01 ] }
+		},
+
+		"phong_normal": {
+			"type": "MeshPhongMaterial",
+			"parameters": { "color": 0, "specular": 16777215, "shininess": 25, "envMap": "cube_reflection", "reflectivity": 0.1, "lightMap": "texture_ao", "normalMap": "texture_normal", "normalScale": [ 1, -1 ], "displacementMap": "texture_displacement", "displacementScale": 2.436143, "displacementBias": -0.428408 }
+		},
+
+		"phong_morph": {
+			"type": "MeshPhongMaterial",
+			"parameters": { "color": 0, "ambient": 0, "specular": 16777215, "shininess": 50, "envMap": "cube_reflection", "reflectivity": 0.125, "combine": "MixOperation", "shading": "flat", "side": "double", "morphTargets": true, "morphNormals" : true }
+		},
+
+		"phong_compressed_cube": {
+			"type": "MeshPhongMaterial",
+			"parameters": { "color": 16777215, "envMap": "cube_compressed", "bumpMap": "texture_bump_repeat_2", "bumpScale": -0.1 }
 		},
 		},
 
 
 		"lambert_green": {
 		"lambert_green": {
@@ -401,6 +530,16 @@
 			"parameters": { "color": 16777215, "map": "texture_bg" }
 			"parameters": { "color": 16777215, "map": "texture_bg" }
 		},
 		},
 
 
+		"textured_compressed_dxt3": {
+			"type": "MeshBasicMaterial",
+			"parameters": { "color": 16777215, "map": "texture_compressed_dxt3", "transparent": true }
+		},
+
+		"textured_compressed_dxt5": {
+			"type": "MeshBasicMaterial",
+			"parameters": { "color": 16777215, "map": "texture_compressed_dxt5", "transparent": true, "blending": "AdditiveBlending" }
+		},
+
 		"minecraft": {
 		"minecraft": {
 			"type": "MeshBasicMaterial",
 			"type": "MeshBasicMaterial",
 			"parameters": { "color": 16777215, "map": "texture_minecraft" }
 			"parameters": { "color": 16777215, "map": "texture_minecraft" }
@@ -416,28 +555,84 @@
 	"textures": {
 	"textures": {
 
 
 		"cube_reflection": {
 		"cube_reflection": {
-			"url": [ "textures/cube/SwedishRoyalCastle/px.jpg",
-					 "textures/cube/SwedishRoyalCastle/nx.jpg",
-					 "textures/cube/SwedishRoyalCastle/py.jpg",
-					 "textures/cube/SwedishRoyalCastle/ny.jpg",
-					 "textures/cube/SwedishRoyalCastle/pz.jpg",
-					 "textures/cube/SwedishRoyalCastle/nz.jpg"
-					]
+			"url": [
+				"textures/cube/SwedishRoyalCastle/px.jpg",
+				"textures/cube/SwedishRoyalCastle/nx.jpg",
+				"textures/cube/SwedishRoyalCastle/py.jpg",
+				"textures/cube/SwedishRoyalCastle/ny.jpg",
+				"textures/cube/SwedishRoyalCastle/pz.jpg",
+				"textures/cube/SwedishRoyalCastle/nz.jpg"
+			]
 		},
 		},
 
 
 		"cube_refraction": {
 		"cube_refraction": {
-			"url": [ "textures/cube/SwedishRoyalCastle/px.jpg",
-					 "textures/cube/SwedishRoyalCastle/nx.jpg",
-					 "textures/cube/SwedishRoyalCastle/py.jpg",
-					 "textures/cube/SwedishRoyalCastle/ny.jpg",
-					 "textures/cube/SwedishRoyalCastle/nz.jpg",
-					 "textures/cube/SwedishRoyalCastle/pz.jpg"
-					],
+			"url": [
+				"textures/cube/SwedishRoyalCastle/px.jpg",
+				"textures/cube/SwedishRoyalCastle/nx.jpg",
+				"textures/cube/SwedishRoyalCastle/py.jpg",
+				"textures/cube/SwedishRoyalCastle/ny.jpg",
+				"textures/cube/SwedishRoyalCastle/nz.jpg",
+				"textures/cube/SwedishRoyalCastle/pz.jpg"
+			],
 			"mapping": "CubeRefractionMapping"
 			"mapping": "CubeRefractionMapping"
 		},
 		},
 
 
+		"cube_compressed": {
+			"url": [
+				"textures/cube/Escher/dds/px.dds",
+				 "textures/cube/Escher/dds/nx.dds",
+				 "textures/cube/Escher/dds/py.dds",
+				 "textures/cube/Escher/dds/ny.dds",
+				 "textures/cube/Escher/dds/pz.dds",
+				 "textures/cube/Escher/dds/nz.dds"
+			]
+		},
+
 		"texture_bg": {
 		"texture_bg": {
-			"url": "textures/cube/SwedishRoyalCastle/pz.jpg"
+			"url": "textures/cube/SwedishRoyalCastle/pz.jpg",
+			"anisotropy": 4
+		},
+
+		"texture_compressed_dxt3": {
+			"url": "textures/compressed/hepatica_dxt3_mip.dds",
+			"anisotropy": 4
+		},
+
+		"texture_compressed_dxt5": {
+			"url": "textures/compressed/explosion_dxt5_mip.dds",
+			"anisotropy": 4
+		},
+
+		"texture_bump": {
+			"url": "textures/water.jpg",
+			"anisotropy": 4
+		},
+
+		"texture_bump_repeat": {
+			"url": "textures/water.jpg",
+			"repeat" : [ 20, 20 ],
+			"anisotropy": 4
+		},
+
+		"texture_bump_repeat_2": {
+			"url": "textures/water.jpg",
+			"repeat" : [ 4, 2 ],
+			"anisotropy": 4
+		},
+
+		"texture_normal": {
+			"url": "textures/normal/ninja/normal.jpg",
+			"anisotropy": 4
+		},
+
+		"texture_ao": {
+			"url": "textures/normal/ninja/ao.jpg",
+			"anisotropy": 4
+		},
+
+		"texture_displacement": {
+			"url": "textures/normal/ninja/displacement.jpg",
+			"anisotropy": 4
 		},
 		},
 
 
 		"texture_minecraft": {
 		"texture_minecraft": {
@@ -478,15 +673,15 @@
 			"type"		 : "directional",
 			"type"		 : "directional",
 			"direction"	 : [0,1,1],
 			"direction"	 : [0,1,1],
 			"color" 	 : 16777215,
 			"color" 	 : 16777215,
-			"intensity"	 : 0.8
+			"intensity"	 : 1
 		},
 		},
 
 
 		"light2": {
 		"light2": {
 			"type"	  : "point",
 			"type"	  : "point",
 			"position": [0,0,0],
 			"position": [0,0,0],
-			"color"   : 16777215
+			"color"   : 16777215,
+			"intensity"	 : 1.25
 		}
 		}
-
 	},
 	},
 
 
 	"fogs":	{
 	"fogs":	{

BIN
examples/textures/compressed/explosion_dxt5_mip.dds


BIN
examples/textures/compressed/hepatica_dxt3_mip.dds


BIN
examples/textures/cube/Escher/dds/nx.dds


BIN
examples/textures/cube/Escher/dds/ny.dds


BIN
examples/textures/cube/Escher/dds/nz.dds


BIN
examples/textures/cube/Escher/dds/px.dds


BIN
examples/textures/cube/Escher/dds/py.dds


BIN
examples/textures/cube/Escher/dds/pz.dds


BIN
examples/textures/shadow.png


BIN
examples/textures/shadowAlpha.png


+ 0 - 3
examples/webgl_buffergeometry.html

@@ -275,9 +275,6 @@
 
 
 			function onWindowResize() {
 			function onWindowResize() {
 
 
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 

+ 4 - 4
examples/webgl_custom_attributes_lines.html

@@ -130,13 +130,13 @@
 
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 			var shaderMaterial = new THREE.ShaderMaterial( {
 
 
-				uniforms: 		uniforms,
+				uniforms:       uniforms,
 				attributes:     attributes,
 				attributes:     attributes,
 				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
 				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
 				fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
 				fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
-				blending: 		THREE.AdditiveBlending,
-				depthTest:		false,
-				transparent:	true
+				blending:       THREE.AdditiveBlending,
+				depthTest:      false,
+				transparent:    true
 
 
 			});
 			});
 
 

+ 18 - 1
examples/webgl_geometry_colors.html

@@ -70,7 +70,24 @@
 				light.position.set( 0, 0, 1 );
 				light.position.set( 0, 0, 1 );
 				scene.add( light );
 				scene.add( light );
 
 
-				var shadowMaterial = new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'textures/shadow.png' ) } );
+				// shadow
+
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 128;
+				canvas.height = 128;
+
+				var context = canvas.getContext( '2d' );
+				var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
+				gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
+				gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
+
+				context.fillStyle = gradient;
+				context.fillRect( 0, 0, canvas.width, canvas.height );
+
+				var shadowTexture = new THREE.Texture( canvas );
+				shadowTexture.needsUpdate = true;
+
+				var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
 				var shadowGeo = new THREE.PlaneGeometry( 300, 300, 1, 1 );
 				var shadowGeo = new THREE.PlaneGeometry( 300, 300, 1, 1 );
 
 
 				mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
 				mesh = new THREE.Mesh( shadowGeo, shadowMaterial );

+ 44 - 60
examples/webgl_geometry_shapes.html

@@ -67,10 +67,25 @@
 				parent.position.y = 50;
 				parent.position.y = 50;
 				scene.add( parent );
 				scene.add( parent );
 
 
-				function addGeometry( geometry, points, spacedPoints, color, x, y, z, rx, ry, rz, s ) {
+				function addShape( shape, extrudeSettings, color, x, y, z, rx, ry, rz, s ) {
+
+					var points = shape.createPointsGeometry();
+					var spacedPoints = shape.createSpacedPointsGeometry( 100 );
+
+					// flat shape
+
+					var geometry = new THREE.ShapeGeometry( shape );
+
+					var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } ) ] );
+					mesh.position.set( x, y, z - 125 );
+					mesh.rotation.set( rx, ry, rz );
+					mesh.scale.set( s, s, s );
+					parent.add( mesh );
 
 
 					// 3d shape
 					// 3d shape
 
 
+					var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
+
 					var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } ) ] );
 					var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } ) ] );
 					mesh.position.set( x, y, z - 75 );
 					mesh.position.set( x, y, z - 75 );
 					mesh.rotation.set( rx, ry, rz );
 					mesh.rotation.set( rx, ry, rz );
@@ -105,7 +120,7 @@
 					// transparent line from equidistance sampled points
 					// transparent line from equidistance sampled points
 
 
 					var line = new THREE.Line( spacedPoints, new THREE.LineBasicMaterial( { color: color, opacity: 0.2 } ) );
 					var line = new THREE.Line( spacedPoints, new THREE.LineBasicMaterial( { color: color, opacity: 0.2 } ) );
-					line.position.set( x, y, z + 100 );
+					line.position.set( x, y, z + 125 );
 					line.rotation.set( rx, ry, rz );
 					line.rotation.set( rx, ry, rz );
 					line.scale.set( s, s, s );
 					line.scale.set( s, s, s );
 					parent.add( line );
 					parent.add( line );
@@ -114,14 +129,13 @@
 
 
 					var pgeo = THREE.GeometryUtils.clone( spacedPoints );
 					var pgeo = THREE.GeometryUtils.clone( spacedPoints );
 					var particles2 = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.5 } ) );
 					var particles2 = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.5 } ) );
-					particles2.position.set( x, y, z + 100 );
+					particles2.position.set( x, y, z + 125 );
 					particles2.rotation.set( rx, ry, rz );
 					particles2.rotation.set( rx, ry, rz );
 					particles2.scale.set( s, s, s );
 					particles2.scale.set( s, s, s );
 					parent.add( particles2 );
 					parent.add( particles2 );
 
 
 				}
 				}
 
 
-				var extrudeSettings = {	amount: 20,  bevelEnabled: true, bevelSegments: 2, steps: 2 }; // bevelSegments: 2, steps: 2 , bevelSegments: 5, bevelSize: 8, bevelThickness:5,
 
 
 				// California
 				// California
 
 
@@ -152,9 +166,6 @@
 
 
 				var californiaShape = new THREE.Shape( californiaPts );
 				var californiaShape = new THREE.Shape( californiaPts );
 
 
-				var california3d = new THREE.ExtrudeGeometry( californiaShape, { amount: 20	} );
-				var californiaPoints = californiaShape.createPointsGeometry();
-				var californiaSpacedPoints = californiaShape.createSpacedPointsGeometry( 100 );
 
 
 				// Triangle
 				// Triangle
 
 
@@ -164,10 +175,6 @@
 				triangleShape.lineTo( 120, 80 );
 				triangleShape.lineTo( 120, 80 );
 				triangleShape.lineTo(  80, 20 ); // close path
 				triangleShape.lineTo(  80, 20 ); // close path
 
 
-				var triangle3d = triangleShape.extrude( extrudeSettings );
-				var trianglePoints = triangleShape.createPointsGeometry();
-				var triangleSpacedPoints = triangleShape.createSpacedPointsGeometry();
-
 
 
 				// Heart
 				// Heart
 
 
@@ -183,11 +190,6 @@
 				heartShape.bezierCurveTo( x + 80, y + 35, x + 80, y, x + 50, y );
 				heartShape.bezierCurveTo( x + 80, y + 35, x + 80, y, x + 50, y );
 				heartShape.bezierCurveTo( x + 35, y, x + 25, y + 25, x + 25, y + 25 );
 				heartShape.bezierCurveTo( x + 35, y, x + 25, y + 25, x + 25, y + 25 );
 
 
-				var heart3d = heartShape.extrude( extrudeSettings );
-				var heartPoints = heartShape.createPointsGeometry();
-				var heartSpacedPoints = heartShape.createSpacedPointsGeometry();
-
-				//heartShape.debug( document.getElementById("debug") );
 
 
 				// Square
 				// Square
 
 
@@ -200,9 +202,6 @@
 				squareShape.lineTo( sqLength, 0 );
 				squareShape.lineTo( sqLength, 0 );
 				squareShape.lineTo( 0, 0 );
 				squareShape.lineTo( 0, 0 );
 
 
-				var square3d = squareShape.extrude( extrudeSettings );
-				var squarePoints = squareShape.createPointsGeometry();
-				var squareSpacedPoints = squareShape.createSpacedPointsGeometry();
 
 
 				// Rectangle
 				// Rectangle
 
 
@@ -215,20 +214,12 @@
 				rectShape.lineTo( rectLength, 0 );
 				rectShape.lineTo( rectLength, 0 );
 				rectShape.lineTo( 0, 0 );
 				rectShape.lineTo( 0, 0 );
 
 
-				var rect3d = rectShape.extrude( extrudeSettings );
-				var rectPoints = rectShape.createPointsGeometry();
-				var rectSpacedPoints = rectShape.createSpacedPointsGeometry();
 
 
 				// Rounded rectangle
 				// Rounded rectangle
 
 
 				var roundedRectShape = new THREE.Shape();
 				var roundedRectShape = new THREE.Shape();
-				roundedRect( roundedRectShape, 0, 0, 50, 50, 20 );
-
-				var roundedRect3d = roundedRectShape.extrude( extrudeSettings );
-				var roundedRectPoints = roundedRectShape.createPointsGeometry();
-				var roundedRectSpacedPoints = roundedRectShape.createSpacedPointsGeometry();
 
 
-				function roundedRect( ctx, x, y, width, height, radius ){
+				( function roundedRect( ctx, x, y, width, height, radius ){
 
 
 					ctx.moveTo( x, y + radius );
 					ctx.moveTo( x, y + radius );
 					ctx.lineTo( x, y + height - radius );
 					ctx.lineTo( x, y + height - radius );
@@ -240,7 +231,8 @@
 					ctx.lineTo( x + radius, y );
 					ctx.lineTo( x + radius, y );
 					ctx.quadraticCurveTo( x, y, x, y + radius );
 					ctx.quadraticCurveTo( x, y, x, y + radius );
 
 
-				}
+				} )( roundedRectShape, 0, 0, 50, 50, 20 );
+
 
 
 				// Circle
 				// Circle
 
 
@@ -252,9 +244,6 @@
 				circleShape.quadraticCurveTo( -circleRadius, -circleRadius, -circleRadius, 0 );
 				circleShape.quadraticCurveTo( -circleRadius, -circleRadius, -circleRadius, 0 );
 				circleShape.quadraticCurveTo( -circleRadius, circleRadius, 0, circleRadius );
 				circleShape.quadraticCurveTo( -circleRadius, circleRadius, 0, circleRadius );
 
 
-				var circle3d = circleShape.extrude( extrudeSettings );
-				var circlePoints = circleShape.createPointsGeometry();
-				var circleSpacedPoints = circleShape.createSpacedPointsGeometry();
 
 
 				// Fish
 				// Fish
 
 
@@ -269,9 +258,6 @@
 				fishShape.quadraticCurveTo(x + 100, y + 10, x + 90, y + 10);
 				fishShape.quadraticCurveTo(x + 100, y + 10, x + 90, y + 10);
 				fishShape.quadraticCurveTo(x + 50, y + 80, x, y);
 				fishShape.quadraticCurveTo(x + 50, y + 80, x, y);
 
 
-				var fish3d = fishShape.extrude( extrudeSettings );
-				var fishPoints = fishShape.createPointsGeometry();
-				var fishSpacedPoints = fishShape.createSpacedPointsGeometry();
 
 
 				// Arc circle
 				// Arc circle
 
 
@@ -284,10 +270,6 @@
 				holePath.absarc( 10, 10, 10, 0, Math.PI*2, true );
 				holePath.absarc( 10, 10, 10, 0, Math.PI*2, true );
 				arcShape.holes.push( holePath );
 				arcShape.holes.push( holePath );
 
 
-				var arc3d = arcShape.extrude( extrudeSettings );
-				var arcPoints = arcShape.createPointsGeometry();
-				var arcSpacedPoints = arcShape.createSpacedPointsGeometry();
-
 
 
 				// Smiley
 				// Smiley
 
 
@@ -299,7 +281,7 @@
 				smileyEye1Path.moveTo( 35, 20 );
 				smileyEye1Path.moveTo( 35, 20 );
 				// smileyEye1Path.absarc( 25, 20, 10, 0, Math.PI*2, true );
 				// smileyEye1Path.absarc( 25, 20, 10, 0, Math.PI*2, true );
 				smileyEye1Path.absellipse( 25, 20, 10, 10, 0, Math.PI*2, true );
 				smileyEye1Path.absellipse( 25, 20, 10, 10, 0, Math.PI*2, true );
-				
+
 				smileyShape.holes.push( smileyEye1Path );
 				smileyShape.holes.push( smileyEye1Path );
 
 
 				var smileyEye2Path = new THREE.Path();
 				var smileyEye2Path = new THREE.Path();
@@ -324,10 +306,6 @@
 				smileyShape.holes.push( smileyMouthPath );
 				smileyShape.holes.push( smileyMouthPath );
 
 
 
 
-				var smiley3d = smileyShape.extrude( extrudeSettings );
-				var smileyPoints = smileyShape.createPointsGeometry();
-				var smileySpacedPoints = smileyShape.createSpacedPointsGeometry();
-
 				// Spline shape + path extrusion
 				// Spline shape + path extrusion
 
 
 				var splinepts = [];
 				var splinepts = [];
@@ -340,7 +318,7 @@
 				splineShape.moveTo( 0, 0 );
 				splineShape.moveTo( 0, 0 );
 				splineShape.splineThru( splinepts );
 				splineShape.splineThru( splinepts );
 
 
-				//splineShape.debug( document.getElementById("debug") );
+				// splineShape.debug( document.getElementById("debug") );
 
 
 				// TODO 3d path?
 				// TODO 3d path?
 
 
@@ -350,25 +328,31 @@
 				apath.points.push(new THREE.Vector3(40, 220, 50));
 				apath.points.push(new THREE.Vector3(40, 220, 50));
 				apath.points.push(new THREE.Vector3(200, 290, 100));
 				apath.points.push(new THREE.Vector3(200, 290, 100));
 
 
+
+				var extrudeSettings = { amount: 20 }; // bevelSegments: 2, steps: 2 , bevelSegments: 5, bevelSize: 8, bevelThickness:5
+
+				// addShape( shape, color, x, y, z, rx, ry,rz, s );
+
+				addShape( californiaShape, extrudeSettings, 0xffaa00, -300, -100, 0, 0, 0, 0, 0.25 );
+
+				extrudeSettings.bevelEnabled = true;
+				extrudeSettings.bevelSegments = 2;
+				extrudeSettings.steps = 2;
+
+				addShape( triangleShape, extrudeSettings, 0xffee00, -180, 0, 0, 0, 0, 0, 1 );
+				addShape( roundedRectShape, extrudeSettings, 0x005500, -150, 150, 0, 0, 0, 0, 1 );
+				addShape( squareShape, extrudeSettings, 0x0055ff, 150, 100, 0, 0, 0, 0, 1 );
+				addShape( heartShape, extrudeSettings, 0xff1100, 0, 100, 0, Math.PI, 0, 0, 1 );
+				addShape( circleShape, extrudeSettings, 0x00ff11, 120, 250, 0, 0, 0, 0, 1 );
+				addShape( fishShape, extrudeSettings, 0x222222, -60, 200, 0, 0, 0, 0, 1 );
+				addShape( smileyShape, extrudeSettings, 0xee00ff, -270, 250, 0, Math.PI, 0, 0, 1 );
+				addShape( arcShape, extrudeSettings, 0xbb4422, 150, 0, 0, 0, 0, 0, 1 );
+
 				extrudeSettings.extrudePath = apath;
 				extrudeSettings.extrudePath = apath;
 				extrudeSettings.bevelEnabled = false;
 				extrudeSettings.bevelEnabled = false;
 				extrudeSettings.steps = 20;
 				extrudeSettings.steps = 20;
 
 
-				var splineShape3d = splineShape.extrude( extrudeSettings );
-				var splinePoints = splineShape.createPointsGeometry( );
-				var splineSpacedPoints = splineShape.createSpacedPointsGeometry( );
-
-				addGeometry( california3d, californiaPoints, californiaSpacedPoints,	0xffaa00, -300, -100, 0,     0, 0, 0, 0.25 );
-				addGeometry( triangle3d, trianglePoints, triangleSpacedPoints, 			0xffee00, -180,    0, 0,     0, 0, 0, 1 );
-				addGeometry( roundedRect3d, roundedRectPoints, roundedRectSpacedPoints,	0x005500, -150,  150, 0,     0, 0, 0, 1 );
-				addGeometry( square3d, squarePoints, squareSpacedPoints,				0x0055ff,  150,  100, 0,     0, 0, 0, 1 );
-				addGeometry( heart3d, heartPoints, heartSpacedPoints,					0xff1100,    0,  100, 0, 	 Math.PI, 0, 0, 1 );
-				addGeometry( circle3d, circlePoints, circleSpacedPoints,				0x00ff11,  120,  250, 0,     0, 0, 0, 1 );
-				addGeometry( fish3d, fishPoints, fishSpacedPoints,						0x222222,  -60,  200, 0,     0, 0, 0, 1 );
-				addGeometry( splineShape3d, splinePoints, splineSpacedPoints,			0x888888,  -50,  -100, -50,  0, 0, 0, 0.2 );
-				addGeometry( arc3d, arcPoints, arcSpacedPoints,							0xbb4422,  150,    0, 0,     0, 0, 0, 1 );
-				addGeometry( smiley3d, smileyPoints, smileySpacedPoints,				0xee00ff,  -270,    250, 0,  Math.PI, 0, 0, 1 );
-
+				addShape( splineShape, extrudeSettings, 0x888888, -50, -100, -50, 0, 0, 0, 0.2 );
 
 
 				//
 				//
 
 

+ 10 - 9
examples/webgl_loader_ctm.html

@@ -155,9 +155,6 @@
 
 
 				}
 				}
 
 
-				var useWorker = true;
-				var useBuffers = true;
-
 				var loader = new THREE.CTMLoader();
 				var loader = new THREE.CTMLoader();
 
 
 				loader.load( "models/ctm/ben.ctm",   function( geometry ) {
 				loader.load( "models/ctm/ben.ctm",   function( geometry ) {
@@ -166,7 +163,7 @@
 					callbackModel( geometry, 450, material, 0, -200, 0, 0, 0 );
 					callbackModel( geometry, 450, material, 0, -200, 0, 0, 0 );
 					checkTime();
 					checkTime();
 
 
-				}, useWorker, useBuffers );
+				}, { useWorker: true } );
 
 
 				loader.load( "models/ctm/WaltHead.ctm",  function( geometry ) {
 				loader.load( "models/ctm/WaltHead.ctm",  function( geometry ) {
 
 
@@ -180,7 +177,7 @@
 
 
 					checkTime();
 					checkTime();
 
 
-				}, useWorker, useBuffers );
+				}, { useWorker: true } );
 
 
 				loader.load( "models/ctm/LeePerry.ctm",  function( geometry ) {
 				loader.load( "models/ctm/LeePerry.ctm",  function( geometry ) {
 
 
@@ -195,7 +192,7 @@
 					var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 					var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
 
 
 					uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
 					uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
-					uniforms[ "uNormalScale" ].value = 0.8;
+					uniforms[ "uNormalScale" ].value.set( 0.8, 0.8 );
 
 
 					uniforms[ "tDiffuse" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
 					uniforms[ "tDiffuse" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
 					uniforms[ "tSpecular" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
 					uniforms[ "tSpecular" ].value = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
@@ -212,8 +209,12 @@
 
 
 					uniforms[ "wrapRGB" ].value.set( 0.75, 0.5, 0.5 );
 					uniforms[ "wrapRGB" ].value.set( 0.75, 0.5, 0.5 );
 
 
-					var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
-					var material = new THREE.ShaderMaterial( parameters );
+					var material = new THREE.ShaderMaterial( {
+						fragmentShader: shader.fragmentShader,
+						vertexShader: shader.vertexShader,
+						uniforms: uniforms,
+						lights: true
+					} );
 
 
 					material.wrapAround = true;
 					material.wrapAround = true;
 
 
@@ -222,7 +223,7 @@
 					callbackModel( geometry, 1300, material, 200, 50, 0, 0, 0 );
 					callbackModel( geometry, 1300, material, 200, 50, 0, 0, 0 );
 					checkTime();
 					checkTime();
 
 
-				}, useWorker, useBuffers );
+				}, { useWorker: true } );
 
 
 			}
 			}
 
 

+ 1 - 4
examples/webgl_loader_ctm_materials.html

@@ -196,9 +196,6 @@
 */
 */
 				// new way via CTMLoader and separate parts
 				// new way via CTMLoader and separate parts
 
 
-				var useWorker = true,
-					useBuffers = true;
-
 				loaderCTM = new THREE.CTMLoader( true );
 				loaderCTM = new THREE.CTMLoader( true );
 				document.body.appendChild( loaderCTM.statusDomElement );
 				document.body.appendChild( loaderCTM.statusDomElement );
 
 
@@ -224,7 +221,7 @@
 
 
 					console.log( "load time:", end - start, "ms" );
 					console.log( "load time:", end - start, "ms" );
 
 
-				}, useWorker, useBuffers );
+				}, { useWorker: true } );
 
 
 			}
 			}
 
 

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