Mr.doob 9 years ago
parent
commit
ed1ee9a1cd
100 changed files with 14310 additions and 2868 deletions
  1. 345 170
      build/three.js
  2. 171 167
      build/three.min.js
  3. 58 0
      docs/api/extras/geometries/BoxBufferGeometry.html
  4. 44 0
      docs/api/extras/geometries/CircleBufferGeometry.html
  5. 56 0
      docs/api/extras/geometries/CylinderBufferGeometry.html
  6. 52 0
      docs/api/extras/geometries/LatheBufferGeometry.html
  7. 50 0
      docs/api/extras/geometries/PlaneBufferGeometry.html
  8. 45 0
      docs/api/extras/geometries/RingBufferGeometry.html
  9. 57 0
      docs/api/extras/geometries/SphereBufferGeometry.html
  10. 51 0
      docs/api/extras/geometries/TorusBufferGeometry.html
  11. 57 0
      docs/api/extras/geometries/TorusKnotBufferGeometry.html
  12. 221 0
      docs/api/materials/MeshStandardMaterial.html
  13. 3 4
      editor/js/Menubar.Add.js
  14. 10 2
      editor/js/Sidebar.Geometry.LatheGeometry.js
  15. 12 23
      editor/js/Sidebar.Geometry.TorusKnotGeometry.js
  16. 10 10
      editor/js/libs/app.js
  17. 0 4
      editor/js/libs/tern-threejs/threejs.js
  18. 2 1
      examples/canvas_ascii_effect.html
  19. 2 1
      examples/canvas_camera_orthographic.html
  20. 2 1
      examples/canvas_camera_orthographic2.html
  21. 2 1
      examples/canvas_geometry_birds.html
  22. 2 1
      examples/canvas_geometry_cube.html
  23. 11 3
      examples/files.js
  24. 1 4
      examples/index.html
  25. 26 0
      examples/js/Encodings.js
  26. 51 0
      examples/js/Half.js
  27. 0 4
      examples/js/Ocean.js
  28. 6 8
      examples/js/ParametricGeometries.js
  29. 544 0
      examples/js/RollerCoaster.js
  30. 4 10
      examples/js/ShaderSkin.js
  31. 0 2
      examples/js/ShaderTerrain.js
  32. 448 0
      examples/js/Volume.js
  33. 217 0
      examples/js/VolumeSlice.js
  34. 97 0
      examples/js/WebVR.js
  35. 6 12
      examples/js/controls/EditorControls.js
  36. 21 39
      examples/js/controls/OrbitControls.js
  37. 19 0
      examples/js/controls/TrackballControls.js
  38. 5 3
      examples/js/effects/AnaglyphEffect.js
  39. 4 2
      examples/js/effects/CardboardEffect.js
  40. 5 3
      examples/js/effects/ParallaxBarrierEffect.js
  41. 71 4
      examples/js/exporters/OBJExporter.js
  42. 25 19
      examples/js/exporters/STLBinaryExporter.js
  43. 15 0
      examples/js/libs/inflate.min.js
  44. 51 0
      examples/js/libs/zlib_and_gzip.min.js
  45. 4 0
      examples/js/libs/zlib_and_gzip.min.js.map
  46. 99 6
      examples/js/loaders/ColladaLoader2.js
  47. 83 0
      examples/js/loaders/HDRCubeTextureLoader.js
  48. 0 2
      examples/js/loaders/MMDLoader.js
  49. 591 0
      examples/js/loaders/NRRDLoader.js
  50. 2 2
      examples/js/loaders/OBJLoader.js
  51. 2 2
      examples/js/loaders/PCDLoader.js
  52. 7 7
      examples/js/loaders/VRMLLoader.js
  53. 982 147
      examples/js/loaders/VTKLoader.js
  54. 317 307
      examples/js/loaders/gltf/glTF-parser.js
  55. 13 13
      examples/js/loaders/gltf/glTFAnimation.js
  56. 1466 1103
      examples/js/loaders/gltf/glTFLoader.js
  57. 185 106
      examples/js/loaders/gltf/glTFLoaderUtils.js
  58. 145 0
      examples/js/loaders/gltf/glTFShaders.js
  59. 204 0
      examples/js/loaders/gltf/gltfUtilities.js
  60. 1 2
      examples/js/materials/ShadowMaterial.js
  61. 0 1
      examples/js/modifiers/ExplodeModifier.js
  62. 387 350
      examples/js/modifiers/SubdivisionModifier.js
  63. 0 2
      examples/js/nodes/materials/PhongNode.js
  64. 0 2
      examples/js/nodes/materials/StandardNode.js
  65. 177 0
      examples/js/pmrem/PMREMCubeUVPacker.js
  66. 244 0
      examples/js/pmrem/PMREMGenerator.js
  67. 12 15
      examples/js/postprocessing/EffectComposer.js
  68. 166 0
      examples/js/postprocessing/ManualMSAARenderPass.js
  69. 121 0
      examples/js/postprocessing/TAARenderPass.js
  70. 48 0
      examples/js/shaders/CompositeShader.js
  71. 0 1
      examples/js/shaders/GammaCorrectionShader.js
  72. 1 0
      examples/models/gltf/CesiumMan/README.txt
  73. BIN
      examples/models/gltf/CesiumMan/glTF-MaterialsCommon/Cesium_Man.bin
  74. 2111 0
      examples/models/gltf/CesiumMan/glTF-MaterialsCommon/Cesium_Man.gltf
  75. BIN
      examples/models/gltf/CesiumMan/glTF-MaterialsCommon/Cesium_Man.jpg
  76. BIN
      examples/models/gltf/CesiumMan/glTF/Cesium_Man.bin
  77. 2207 0
      examples/models/gltf/CesiumMan/glTF/Cesium_Man.gltf
  78. BIN
      examples/models/gltf/CesiumMan/glTF/Cesium_Man.jpg
  79. 25 0
      examples/models/gltf/CesiumMan/glTF/Cesium_Man0FS.glsl
  80. 22 0
      examples/models/gltf/CesiumMan/glTF/Cesium_Man0VS.glsl
  81. 1 0
      examples/models/gltf/CesiumMilkTruck/README.txt
  82. BIN
      examples/models/gltf/CesiumMilkTruck/glTF-MaterialsCommon/CesiumMilkTruck.bin
  83. 610 0
      examples/models/gltf/CesiumMilkTruck/glTF-MaterialsCommon/CesiumMilkTruck.gltf
  84. BIN
      examples/models/gltf/CesiumMilkTruck/glTF-MaterialsCommon/CesiumMilkTruck.png
  85. BIN
      examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck.bin
  86. 705 0
      examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck.gltf
  87. BIN
      examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck.png
  88. 17 0
      examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck0FS.glsl
  89. 12 0
      examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck0VS.glsl
  90. 18 0
      examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck1FS.glsl
  91. 15 0
      examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck1VS.glsl
  92. 7 13
      examples/models/gltf/duck/README.txt
  93. BIN
      examples/models/gltf/duck/duck.bin
  94. 0 122
      examples/models/gltf/duck/duck.dae
  95. BIN
      examples/models/gltf/duck/glTF-MaterialsCommon/duck.bin
  96. 291 0
      examples/models/gltf/duck/glTF-MaterialsCommon/duck.gltf
  97. 0 0
      examples/models/gltf/duck/glTF-MaterialsCommon/duckCM.png
  98. BIN
      examples/models/gltf/duck/glTF/duck.bin
  99. 119 154
      examples/models/gltf/duck/glTF/duck.gltf
  100. 14 13
      examples/models/gltf/duck/glTF/duck0FS.glsl

File diff suppressed because it is too large
+ 345 - 170
build/three.js


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


+ 58 - 0
docs/api/extras/geometries/BoxBufferGeometry.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:BoxGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#BoxBufferGeometry'></iframe>
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
+		var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
+		var cube = new THREE.Mesh( geometry, material );
+		scene.add( cube );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float width], [page:Float height], [page:Float depth], [page:Integer widthSegments], [page:Integer heightSegments], [page:Integer depthSegments])</h3>
+		<div>
+		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 />
+		widthSegments — Optional. Number of segmented faces along the width of the sides. Default is 1.<br />
+		heightSegments — Optional. Number of segmented faces along the height of the sides. Default is 1.<br />
+		depthSegments — Optional. Number of segmented faces along the depth of the sides. Default is 1.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<h3>.parameters</h3>
+ 		<div>
+			<p>Using the above example code above as our basis:</p>
+			<code>
+		geometry.parameters; // outputs an object {width: 1, height: 1, depth: 1, widthSegments: undefined, heightSegments: undefined}
+		cube.geometry.parameters; // as above
+		cube.geometry.parameters.width; // === 1
+		cube.geometry.parameters.widthSegments // === undefined.
+			</code>
+ 		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 44 - 0
docs/api/extras/geometries/CircleBufferGeometry.html

@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:CircleGeometry].</div>
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#CircleBufferGeometry'></iframe>
+
+		<code>
+		var geometry = new THREE.CircleBufferGeometry( 5, 32 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var circle = new THREE.Mesh( geometry, material );
+		scene.add( circle );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]([page:Float radius], [page:Integer segments], [page:Float thetaStart], [page:Float thetaLength])</h3>
+		<div>
+		radius — Radius of the circle, default = 50.<br />
+		segments — Number of segments (triangles), minimum = 3, default = 8.<br />
+		thetaStart — Start angle for first segment, default = 0 (three o'clock position).<br />
+		thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete circle.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 56 - 0
docs/api/extras/geometries/CylinderBufferGeometry.html

@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:CylinderGeometry].</div>
+
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#CylinderBufferGeometry'></iframe>
+
+		<code>var geometry = new THREE.CylinderBufferGeometry( 5, 5, 20, 32 );
+		var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
+		var cylinder = new THREE.Mesh( geometry, material );
+		scene.add( cylinder );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radiusTop], [page:Float radiusBottom], [page:Float height], [page:Integer radiusSegments], [page:Integer heightSegments], [page:Boolean openEnded], [page:Float thetaStart], [page:Float thetaLength])</h3>
+		<div>
+		radiusTop — Radius of the cylinder at the top. Default is 20.<br />
+		radiusBottom — Radius of the cylinder at the bottom. Default is 20.<br />
+		height — Height of the cylinder. Default is 100.<br />
+		radiusSegments — Number of segmented faces around the circumference of the cylinder. Default is 8<br />
+		heightSegments — Number of rows of faces along the height of the cylinder. Default is 1.<br />
+		openEnded — A Boolean indicating whether the ends of the cylinder are open or capped. Default is false, meaning capped.<br />
+		thetaStart — Start angle for first segment, default = 0 (three o'clock position).<br />
+		thetaLength — The central angle, often called theta, of the circular sector. The default is 2*Pi, which makes for a complete cylinder.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the constructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 52 - 0
docs/api/extras/geometries/LatheBufferGeometry.html

@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:LatheGeometry].</div>
+
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#LatheBufferGeometry'></iframe>
+
+		<code>
+		var points = [];
+		for ( var i = 0; i < 10; i ++ ) {
+			points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
+		}
+		var geometry = new THREE.LatheBufferGeometry( points );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var lathe = new THREE.Mesh( geometry, material );
+		scene.add( lathe );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Array points], [page:Integer segments], [page:Float phiStart], [page:Float phiLength])</h3>
+		<div>
+		points — Array of Vector2s. The x-coordinate of each point must be greater than zero.<br />
+		segments — the number of circumference segments to generate. Default is 12.<br />
+		phiStart — the starting angle in radians. Default is 0.<br />
+		phiLength — the radian (0 to 2PI) range of the lathed section 2PI is a closed lathe, less than 2PI is a portion. Default is 2PI.
+		</div>
+		<div>
+		This creates a LatheBufferGeometry based on the parameters.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 50 - 0
docs/api/extras/geometries/PlaneBufferGeometry.html

@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:PlaneGeometry].</div>
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#PlaneBufferGeometry'></iframe>
+
+		<code>var geometry = new THREE.PlaneBufferGeometry( 5, 20, 32 );
+		var material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
+		var plane = new THREE.Mesh( geometry, material );
+		scene.add( plane );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float width], [page:Float height], [page:Integer widthSegments], [page:Integer heightSegments])</h3>
+		<div>
+		width — Width along the X axis.<br />
+		height — Height along the Y axis.<br />
+		widthSegments — Optional. Default is 1. <br />
+		heightSegments — Optional. Default is 1.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 45 - 0
docs/api/extras/geometries/RingBufferGeometry.html

@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:RingGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#RingBufferGeometry'></iframe>
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.RingBufferGeometry( 1, 5, 32 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
+		var mesh = new THREE.Mesh( geometry, material );
+		scene.add( mesh );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float innerRadius], [page:Float outerRadius], [page:Integer thetaSegments], [page:Integer phiSegments], [page:Float thetaStart], [page:Float thetaLength])</h3>
+		<div>
+		innerRadius — Default is 0, but it doesn't work right when innerRadius is set to 0.<br />
+		outerRadius — Default is 50. <br />
+		thetaSegments — Number of segments.  A higher number means the ring will be more round.  Minimum is 3.  Default is 8. <br />
+		phiSegments — Minimum is 1.  Default is 8.<br />
+		thetaStart — Starting angle. Default is 0. <br />
+		thetaLength — Central angle.  Default is Math.PI * 2.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 57 - 0
docs/api/extras/geometries/SphereBufferGeometry.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:SphereGeometry].</div>
+
+		<h2>Example</h2>
+
+		<iframe src='scenes/geometry-browser.html#SphereBufferGeometry'></iframe>
+
+		<code>var geometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
+		var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
+		var sphere = new THREE.Mesh( geometry, material );
+		scene.add( sphere );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radius], [page:Integer widthSegments], [page:Integer heightSegments], [page:Float phiStart], [page:Float phiLength], [page:Float thetaStart], [page:Float thetaLength])</h3>
+
+		<div>
+		radius — sphere radius. Default is 50.<br />
+		widthSegments — number of horizontal segments. Minimum value is 3, and the default is 8.<br />
+		heightSegments — number of vertical segments. Minimum value is 2, and the default is 6.<br />
+		phiStart — specify horizontal starting angle. Default is 0.<br />
+		phiLength — specify horizontal sweep angle size. Default is Math.PI * 2.<br />
+		thetaStart — specify vertical starting angle. Default is 0.<br />
+		thetaLength — specify vertical sweep angle size. Default is Math.PI.<br />
+		</div>
+
+		<div>
+		The geometry is created by sweeping and calculating vertexes around the Y axis (horizontal sweep) and the Z axis (vertical sweep). Thus, incomplete spheres (akin to <em>'sphere slices'</em>) can be created through the use of different values of phiStart, phiLength, thetaStart and thetaLength, in order to define the points in which we start (or end) calculating those vertices.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 51 - 0
docs/api/extras/geometries/TorusBufferGeometry.html

@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:TorusGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#TorusBufferGeometry'></iframe>
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.TorusBufferGeometry( 10, 3, 16, 100 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var torus = new THREE.Mesh( geometry, material );
+		scene.add( torus );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radius], [page:Float tube], [page:Integer radialSegments], [page:Integer tubularSegments], [page:Float arc])</h3>
+		<div>
+		radius — Default is 100. <br />
+		tube — Diameter of the tube.  Default is 40. <br />
+		radialSegments — Default is 8 <br />
+		tubularSegments — Default is 6. <br />
+		arc — Central angle.  Default is Math.PI * 2.
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 57 - 0
docs/api/extras/geometries/TorusKnotBufferGeometry.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:TorusKnotGeometry].</div>
+
+		<iframe src='scenes/geometry-browser.html#TorusKnotBufferGeometry'></iframe>
+
+
+		<h2>Example</h2>
+
+		<code>var geometry = new THREE.TorusKnotBufferGeometry( 10, 3, 100, 16 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
+		var torusKnot = new THREE.Mesh( geometry, material );
+		scene.add( torusKnot );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Float radius], [page:Float tube], [page:Integer tubularSegments], [page:Integer radialSegments], [page:Integer p], [page:Integer q])</h3>
+		<div>
+			<ul>
+				<li>radius — Default is 100.</li>
+				<li>tube — Diameter of the tube. Default is 40.</li>
+				<li>tubularSegments — Default is 64.</li>
+				<li>radialSegments — Default is 8.</li>
+				<li>p — This value determines, how many times the geometry winds around its axis of rotational symmetry. Default is 2.</li>
+				<li>q — This value determines, how many times the geometry winds around a circle in the interior of the torus. Default is 3.</li>
+			</ul>
+		</div>
+
+
+		<h2>Properties</h2>
+
+
+		<div>
+		Each of the contructor parameters is accessible as a property of the same name. Any modification of these properties after instantiation does not change the geometry.
+		</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 221 - 0
docs/api/materials/MeshStandardMaterial.html

@@ -0,0 +1,221 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">TODO</div>
+
+		<iframe src='scenes/material-browser.html#MeshStandardMaterial'></iframe>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Object parameters])</h3>
+		<div>
+		parameters -- an object with one or more of the material's properties defining the material's appearance.
+		</div>
+		<div>
+		color — geometry color in hexadecimal. Default is 0xffffff.<br />
+		roughness — Set roughness. Default is 0.5.<br />
+		metalness — Set metalness. Default is 0.5.<br />
+		map — Set texture map. Default is null.<br />
+		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
+		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
+		emissive - Set emissive color. Default is 0x000000.<br />
+		emissiveMap — Set emissive map. Default is null.<br />
+		emissiveIntensity — Set emissive map intensity. Default is 1.<br />
+		bumpMap — Set bump map. Default is null.<br />
+		bumpMapScale — Set bump map scale. Default is 1.<br />
+		normalMap — Set normal map. Default is null.<br />
+		normalMapScale — Set normal map scale. Default is (1, 1).<br />
+		displacementMap — Set displacement map. Default is null.<br />
+		displacementScale — Set displacement scale. Default is 1.<br />
+		displacementBias — Set displacement offset. Default is 0.<br />
+		roughnessMap - Set roughness map. Default is null.<br />
+		metalnessMap - Set metalness map. Default is null.<br />
+		alphaMap — Set alpha map. Default is null.<br />
+		envMap — Set env map. Default is null.<br />
+		envMapIntensity — Set env map intensity. Default is 1.0.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
+		fog — Define whether the material color is affected by global fog settings. Default is true.<br />
+		shading — Define shading type. Default is THREE.SmoothShading.<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 />
+		vertexColors — Define how the vertices gets colored. Default is THREE.NoColors.<br />
+		skinning — Define whether the material uses skinning. Default is false.<br />
+		morphTargets — Define whether the material uses morphTargets. Default is false.<br />
+		morphNormals — Define whether the material uses morphNormals. Default is false.
+		</div>
+		<div>
+		Example:<br>
+		materials.push( new THREE.MeshStandardMaterial( { color: 0x550000, envMap: reflectionCube, roughness: 0.1, metalness: 1.0 } ) );
+
+		</div>
+
+
+		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
+
+		<h3>[property:Color color]</h3>
+		<div>
+		Diffuse color of the material. Default is white.<br />
+		</div>
+
+		<h3>[property:Float roughness]</h3>
+		<div>
+		TODO.<br />
+		</div>
+
+		<h3>[property:Float metalness]</h3>
+		<div>
+		TODO<br />
+		</div>
+
+		<h3>[property:Texture map]</h3>
+		<div>Set color texture map. Default is null. The texture map color is modulated by the diffuse color.</div>
+
+		<h3>[property:Texture lightMap]</h3>
+		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
+
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Texture aoMap]</h3>
+		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Color emissive]</h3>
+		<div>
+			Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
+		</div>
+
+		<h3>[property:Texture emissiveMap]</h3>
+		<div>Set emisssive (glow) map. Default is null. The emissive map color is modulated by the emissive color and the emissive intensity. If you have an emissive map, be sure to set the emissive color to something other than black.</div>
+
+		<h3>[property:Float emissiveIntensity]</h3>
+		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
+
+		<h3>[property:Texture bumpMap]</h3>
+		<div>
+			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
+			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
+			be ignored.
+		</div>
+
+		<h3>[property:Float bumpScale]</h3>
+		<div>
+			How much the bump map affects the material. Typical ranges are 0-1. Default is 1.
+		</div>
+
+		<h3>[property:Texture normalMap]</h3>
+		<div>
+			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
+			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
+		</div>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<div>
+			How much the normal map affects the material. Typical ranges are 0-1. Default is (1, 1).
+		</div>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<div>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps which only affect the light and shade of the material the displaced vertices can cast shadows, block other objects, and otherwise act as real geometry.
+			The displacement texture is an image where the value of each pixel (white being the highest) is mapped against, and repositions, the vertices of the mesh.
+		</div>
+
+		<h3>[property:Float displacementScale]</h3>
+		<div>
+			How much the displacement map affects the mesh (where black is no displacement, and white is maximum displacement). Without a displacement map set, this value is not applied. Default is 1.
+		</div>
+
+		<h3>[property:Float displacementBias]</h3>
+		<div>
+			The offset of the displacement map's values on the mesh's vertices. Without a displacement map set, this value is not applied. Default is 0.
+		</div>
+
+		<h3>[property:Texture roughnessMap]</h3>
+		<div>
+			TODO.
+		</div>
+
+		<h3>[property:Texture metalnessMap]</h3>
+		<div>
+			TODO.
+		</div>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<div>The alpha map is a grayscale texture that controls the opacity across the surface (black: fully transparent; white: fully opaque). Default is null.</div>
+		<div>Only the color of the texture is used, ignoring the alpha channel if one exists. For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the green channel when sampling this texture due to the extra bit of precision provided for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and luminance/alpha textures will also still work as expected.</div>
+
+		<h3>[property:TextureCube envMap]</h3>
+		<div>Set env map. Default is null.</div>
+
+		<h3>[property:Float envMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Float refractionRatio]</h3>
+		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
+
+		<h3>[property:Boolean fog]</h3>
+		<div>Define whether the material color is affected by global fog settings. Default is *true*.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>[property:Integer shading]</h3>
+		<div>How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.</div>
+
+		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading].</div>
+
+		<h3>[property:Boolean wireframe]</h3>
+		<div>Whether the triangles' edges are displayed instead of surfaces. Default is *false*.</div>
+
+		<h3>[property:Float wireframeLinewidth]</h3>
+		<div>Line thickness for wireframe mode. Default is *1.0*.</div>
+		<div>Due to limitations in the <a href="https://code.google.com/p/angleproject/" target="_blank">ANGLE layer</a>, on Windows platforms linewidth will always be 1 regardless of the set value.</div>
+
+		<h3>[property: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>
+
+		<h3>[property: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>[property:Integer vertexColors]</h3>
+		<div>Define how the vertices gets colored. Possible values are THREE.NoColors, THREE.FaceColors and THREE.VertexColors. Default is THREE.NoColors.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>[property:Boolean skinning]</h3>
+		<div>Define whether the material uses skinning. Default is *false*.</div>
+
+		<h3>[property:Boolean morphTargets]</h3>
+		<div>Define whether the material uses morphTargets. Default is *false*.</div>
+
+		<h3>[property:boolean morphNormals]</h3>
+		<div>
+			Defines whether the material uses morphNormals. Set as true to pass morphNormal attributes from the [page:Geometry]
+			to the shader. Default is *false*.
+		</div>
+
+		<h2>Methods</h2>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 3 - 4
editor/js/Menubar.Add.js

@@ -198,13 +198,12 @@ Menubar.Add = function ( editor ) {
 
 		var radius = 2;
 		var tube = 0.8;
-		var radialSegments = 64;
-		var tubularSegments = 12;
+		var tubularSegments = 64;
+		var radialSegments = 12;
 		var p = 2;
 		var q = 3;
-		var heightScale = 1;
 
-		var geometry = new THREE.TorusKnotGeometry( radius, tube, radialSegments, tubularSegments, p, q, heightScale );
+		var geometry = new THREE.TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q );
 		var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
 		mesh.name = 'TorusKnot ' + ( ++ meshCount );
 

+ 10 - 2
editor/js/Sidebar.Geometry.LatheGeometry.js

@@ -63,9 +63,17 @@ Sidebar.Geometry.LatheGeometry = function( editor, object ) {
 
 	var addPointButton = new UI.Button( '+' ).onClick( function() {
 
-		var point = pointsUI[ pointsUI.length - 1 ];
+		if( pointsUI.length === 0 ){
 
-		pointsList.add( createPointRow( point.x.getValue(), point.y.getValue() ) );
+			pointsList.add( createPointRow( 0, 0 ) );
+
+		} else {
+
+			var point = pointsUI[ pointsUI.length - 1 ];
+
+			pointsList.add( createPointRow( point.x.getValue(), point.y.getValue() ) );
+
+		}
 
 		update();
 

+ 12 - 23
editor/js/Sidebar.Geometry.TorusKnotGeometry.js

@@ -30,16 +30,6 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 
 	container.add( tubeRow );
 
-	// radialSegments
-
-	var radialSegmentsRow = new UI.Row();
-	var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
-
-	radialSegmentsRow.add( new UI.Text( 'Radial segments' ).setWidth( '90px' ) );
-	radialSegmentsRow.add( radialSegments );
-
-	container.add( radialSegmentsRow );
-
 	// tubularSegments
 
 	var tubularSegmentsRow = new UI.Row();
@@ -50,6 +40,16 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 
 	container.add( tubularSegmentsRow );
 
+	// radialSegments
+
+	var radialSegmentsRow = new UI.Row();
+	var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update );
+
+	radialSegmentsRow.add( new UI.Text( 'Radial segments' ).setWidth( '90px' ) );
+	radialSegmentsRow.add( radialSegments );
+
+	container.add( radialSegmentsRow );
+
 	// p
 
 	var pRow = new UI.Row();
@@ -70,16 +70,6 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 
 	container.add( qRow );
 
-	// heightScale
-
-	var heightScaleRow = new UI.Row();
-	var heightScale = new UI.Number( parameters.heightScale ).onChange( update );
-
-	pRow.add( new UI.Text( 'Height scale' ).setWidth( '90px' ) );
-	pRow.add( heightScale );
-
-	container.add( heightScaleRow );
-
 
 	//
 
@@ -88,11 +78,10 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) {
 		editor.execute( new SetGeometryCommand( object, new THREE.TorusKnotGeometry(
 			radius.getValue(),
 			tube.getValue(),
-			radialSegments.getValue(),
 			tubularSegments.getValue(),
+			radialSegments.getValue(),
 			p.getValue(),
-			q.getValue(),
-			heightScale.getValue()
+			q.getValue()
 		) ) );
 
 	}

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

@@ -177,15 +177,7 @@ var APP = {
 
 			for ( var i = 0, l = array.length; i < l; i ++ ) {
 
-				try {
-
-					array[ i ]( event );
-
-				} catch ( e ) {
-
-					console.error( ( e.message || e ), ( e.stack || "" ) );
-
-				}
+				array[ i ]( event );
 
 			}
 
@@ -197,7 +189,15 @@ var APP = {
 
 			request = requestAnimationFrame( animate );
 
-			dispatch( events.update, { time: time, delta: time - prevTime } );
+			try {
+
+				dispatch( events.update, { time: time, delta: time - prevTime } );
+
+			} catch ( e ) {
+
+				console.error( ( e.message || e ), ( e.stack || "" ) );
+
+			}
 
 			if ( vr === true ) {
 

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

@@ -5292,10 +5292,6 @@
           "!type": "boolean",
           "!doc": "Whether to generate mipmaps (if possible) for a texture. True by default."
         },
-        "shareDepthFrom": {
-          "!type": "+THREE.WebGLRenderTarget",
-          "!doc": "Shares the depth from another WebGLRenderTarget. Default is null."
-        },
         "setSize": {
           "!type": "fn(width: number, height: number)",
           "!doc": "Sets the size of the renderTarget."

+ 2 - 1
examples/canvas_ascii_effect.html

@@ -116,8 +116,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_camera_orthographic.html

@@ -145,8 +145,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_camera_orthographic2.html

@@ -208,8 +208,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_geometry_birds.html

@@ -420,8 +420,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 2 - 1
examples/canvas_geometry_cube.html

@@ -193,8 +193,9 @@
 
 				requestAnimationFrame( animate );
 
+				stats.begin();
 				render();
-				stats.update();
+				stats.end();
 
 			}
 

+ 11 - 3
examples/files.js

@@ -57,6 +57,7 @@ var files = {
 		"webgl_kinect",
 		"webgl_lensflares",
 		"webgl_lights_hemisphere",
+		"webgl_lights_physical",
 		"webgl_lights_pointlights",
 		"webgl_lights_pointlights2",
 		"webgl_lines_colors",
@@ -88,6 +89,7 @@ var files = {
 		"webgl_loader_msgpack",
 		"webgl_loader_obj",
 		"webgl_loader_obj_mtl",
+		"webgl_loader_nrrd",
 		"webgl_loader_pcd",
 		"webgl_loader_pdb",
 		"webgl_loader_ply",
@@ -119,6 +121,7 @@ var files = {
 		"webgl_materials_cubemap_refraction",
 		"webgl_materials_displacementmap",
 		"webgl_materials_envmaps",
+		"webgl_materials_envmaps_hdr",
 		"webgl_materials_grass",
 		"webgl_materials_lightmap",
 		"webgl_materials_nodes",
@@ -134,11 +137,11 @@ var files = {
 		"webgl_materials_texture_manualmipmap",
 		"webgl_materials_texture_pvrtc",
 		"webgl_materials_texture_tga",
+		"webgl_materials_transparency",
 		"webgl_materials_variations_basic",
 		"webgl_materials_variations_lambert",
 		"webgl_materials_variations_phong",
 		"webgl_materials_variations_standard",
-		"webgl_materials_variations_standard2",
 		"webgl_materials_video",
 		"webgl_materials_wireframe",
 		"webgl_mirror",
@@ -159,6 +162,7 @@ var files = {
 		"webgl_objects_update",
 		"webgl_octree",
 		"webgl_octree_raycasting",
+		"webgl_panorama_dualfisheye",
 		"webgl_panorama_equirectangular",
 		"webgl_particles_general",
 		"webgl_performance",
@@ -177,9 +181,11 @@ var files = {
 		"webgl_postprocessing_glitch",
 		"webgl_postprocessing_godrays",
 		"webgl_postprocessing_masking",
+		"webgl_postprocessing_msaa",
 		"webgl_postprocessing_nodes",
 		"webgl_postprocessing_smaa",
 		"webgl_postprocessing_ssao",
+		"webgl_postprocessing_taa",
 		"webgl_raycast_texture",
 		"webgl_read_float_buffer",
 		"webgl_rtt",
@@ -203,6 +209,7 @@ var files = {
 		"webgl_terrain_dynamic",
 		"webgl_test_memory",
 		"webgl_test_memory2",
+		"webgl_tonemapping",
 		"webgl_trails",
 		"webgl_video_panorama_equirectangular"
 	],
@@ -230,8 +237,9 @@ var files = {
 	],
 	"webvr": [
 		"webvr_cubes",
-		"webvr_video",
-		"webvr_stereo_pano"
+		"webvr_panorama",
+		"webvr_rollercoaster",
+		"webvr_video"
 	],
 	"css3d": [
 		"css3d_molecules",

+ 1 - 4
examples/index.html

@@ -289,10 +289,7 @@
 		button.textContent = 'View source';
 		button.addEventListener( 'click', function ( event ) {
 
-			var array = location.href.split( '/' );
-			array.pop();
-
-			window.open( 'view-source:' + array.join( '/' ) + '/' + selected + '.html' );
+			window.open( 'https://github.com/mrdoob/three.js/blob/master/examples/' + selected + '.html' );
 
 		}, false );
 		button.style.display = 'none';

+ 26 - 0
examples/js/Encodings.js

@@ -0,0 +1,26 @@
+/**
+ * @author Ben Houston / http://clara.io / bhouston
+ * @author Prashant Sharma / spidersharma03
+ */
+
+THREE.Encodings = function() {
+  if( THREE.toHalf === undefined ) throw new Error("THREE.Encodings is required for HDRCubeMapLoader when loading half data.");
+}
+
+THREE.Encodings.RGBEByteToRGBFloat = function( sourceArray, sourceOffset, destArray, destOffset ) {
+  var e = sourceArray[sourceOffset+3];
+  var scale = Math.pow(2.0, e - 128.0) / 255.0;
+
+  destArray[destOffset+0] = sourceArray[sourceOffset+0] * scale;
+  destArray[destOffset+1] = sourceArray[sourceOffset+1] * scale;
+  destArray[destOffset+2] = sourceArray[sourceOffset+2] * scale;
+}
+
+THREE.Encodings.RGBEByteToRGBHalf = function( sourceArray, sourceOffset, destArray, destOffset ) {
+  var e = sourceArray[sourceOffset+3];
+  var scale = Math.pow(2.0, e - 128.0) / 255.0;
+
+  destArray[destOffset+0] = THREE.toHalf( sourceArray[sourceOffset+0] * scale );
+  destArray[destOffset+1] = THREE.toHalf( sourceArray[sourceOffset+1] * scale );
+  destArray[destOffset+2] = THREE.toHalf( sourceArray[sourceOffset+2] * scale );
+}

+ 51 - 0
examples/js/Half.js

@@ -0,0 +1,51 @@
+/**
+ * Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
+ */
+
+THREE.toHalf = (function() {
+  var floatView = new Float32Array(1);
+  var int32View = new Int32Array(floatView.buffer);
+
+  /* This method is faster than the OpenEXR implementation (very often
+   * used, eg. in Ogre), with the additional benefit of rounding, inspired
+   * by James Tursa?s half-precision code. */
+  return function toHalf(val) {
+
+    floatView[0] = val;
+    var x = int32View[0];
+
+    var bits = (x >> 16) & 0x8000; /* Get the sign */
+    var m = (x >> 12) & 0x07ff; /* Keep one extra bit for rounding */
+    var e = (x >> 23) & 0xff; /* Using int is faster here */
+
+    /* If zero, or denormal, or exponent underflows too much for a denormal
+     * half, return signed zero. */
+    if (e < 103) {
+      return bits;
+    }
+
+    /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
+    if (e > 142) {
+      bits |= 0x7c00;
+      /* If exponent was 0xff and one mantissa bit was set, it means NaN,
+           * not Inf, so make sure we set one mantissa bit too. */
+      bits |= ((e == 255) ? 0 : 1) && (x & 0x007fffff);
+      return bits;
+    }
+
+    /* If exponent underflows but not too much, return a denormal */
+    if (e < 113) {
+      m |= 0x0800;
+      /* Extra rounding may overflow and set mantissa to 0 and exponent
+       * to 1, which is OK. */
+      bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
+      return bits;
+    }
+
+    bits |= ((e - 112) << 10) | (m >> 1);
+    /* Extra rounding. An overflow will set mantissa to 0 and increment
+     * the exponent, which is OK. */
+    bits += m & 1;
+    return bits;
+  };
+}());

+ 0 - 4
examples/js/Ocean.js

@@ -12,10 +12,6 @@
 
 	this.scene = new THREE.Scene();
 
-	// Enable necessary extensions
-	this.renderer.context.getExtension( 'OES_texture_float' );
-	this.renderer.context.getExtension( 'OES_texture_float_linear' );
-
 	// Assign optional parameters as variables and object properties
 	function optionalParameter( value, defaultValue ) {
 

+ 6 - 8
examples/js/ParametricGeometries.js

@@ -170,18 +170,16 @@ THREE.ParametricGeometries.TubeGeometry.prototype.constructor = THREE.Parametric
   * Parametric Replacement for TorusKnotGeometry
   *
   *********************************************/
-THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsR, segmentsT, p, q, heightScale ) {
+THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsT, segmentsR, p, q ) {
 
 	var scope = this;
 
 	this.radius = radius || 200;
 	this.tube = tube || 40;
-	this.segmentsR = segmentsR || 64;
-	this.segmentsT = segmentsT || 8;
+	this.segmentsT = segmentsT || 64;
+	this.segmentsR = segmentsR || 8;
 	this.p = p || 2;
 	this.q = q || 3;
-	this.heightScale = heightScale || 1;
-
 
 	var TorusKnotCurve = THREE.Curve.create(
 
@@ -198,13 +196,13 @@ THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segments
 				ty = ( 1 + r * Math.cos( q * t ) ) * Math.sin( p * t ),
 				tz = r * Math.sin( q * t );
 
-			return new THREE.Vector3( tx, ty * heightScale, tz ).multiplyScalar( radius );
+			return new THREE.Vector3( tx, ty, tz ).multiplyScalar( radius );
 
 		}
 
 	);
-	var segments = segmentsR;
-	var radiusSegments = segmentsT;
+	var segments = segmentsT;
+	var radiusSegments = segmentsR;
 	var extrudePath = new TorusKnotCurve();
 
 	THREE.ParametricGeometries.TubeGeometry.call( this, extrudePath, segments, tube, radiusSegments, true, false );

+ 544 - 0
examples/js/RollerCoaster.js

@@ -0,0 +1,544 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+var RollerCoasterGeometry = function ( curve, size ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+	var normals = [];
+	var colors = [];
+
+	var color1 = [ 1, 1, 1 ];
+	var color2 = [ 1, 1, 0 ];
+
+	var up = new THREE.Vector3( 0, 1, 0 );
+	var forward = new THREE.Vector3();
+	var right = new THREE.Vector3();
+
+	var quaternion = new THREE.Quaternion();
+	var prevQuaternion = new THREE.Quaternion();
+	prevQuaternion.setFromAxisAngle( up , Math.PI / 2 );
+
+	var point = new THREE.Vector3();
+	var prevPoint = new THREE.Vector3();
+	prevPoint.copy( curve.getPointAt( 0 ) );
+
+	// shapes
+
+	var step = [
+		new THREE.Vector3( -2.25,  0, 0 ),
+		new THREE.Vector3(  0,  -0.5, 0 ),
+		new THREE.Vector3(  0, -1.75, 0 ),
+
+		new THREE.Vector3(  0,  -0.5, 0 ),
+		new THREE.Vector3(  2.25,  0, 0 ),
+		new THREE.Vector3(  0, -1.75, 0 )
+	];
+
+	var PI2 = Math.PI * 2;
+
+	var sides = 5;
+	var tube1 = [];
+
+	for ( var i = 0; i < sides; i ++ ) {
+
+		var angle = ( i / sides ) * PI2;
+		tube1.push( new THREE.Vector3( Math.sin( angle ) * 0.6, Math.cos( angle ) * 0.6, 0 ) );
+
+	}
+
+	var sides = 6;
+	var tube2 = [];
+
+	for ( var i = 0; i < sides; i ++ ) {
+
+		var angle = ( i / sides ) * PI2;
+		tube2.push( new THREE.Vector3( Math.sin( angle ) * 0.25, Math.cos( angle ) * 0.25, 0 ) );
+
+	}
+
+	var vector = new THREE.Vector3();
+	var normal = new THREE.Vector3();
+
+	var drawShape = function ( shape, color ) {
+
+		normal.set( 0, 0, -1 ).applyQuaternion( quaternion );
+
+		for ( var j = 0; j < shape.length; j ++ ) {
+
+			vector.copy( shape[ j ] );
+			vector.applyQuaternion( quaternion );
+			vector.add( point );
+
+			vertices.push( vector.x, vector.y, vector.z );
+			normals.push( normal.x, normal.y, normal.z );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+		}
+
+		normal.set( 0, 0, 1 ).applyQuaternion( quaternion );
+
+		for ( var j = shape.length - 1; j >= 0; j -- ) {
+
+			vector.copy( shape[ j ] );
+			vector.applyQuaternion( quaternion );
+			vector.add( point );
+
+			vertices.push( vector.x, vector.y, vector.z );
+			normals.push( normal.x, normal.y, normal.z );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+		}
+
+	};
+
+	var vector1 = new THREE.Vector3();
+	var vector2 = new THREE.Vector3();
+	var vector3 = new THREE.Vector3();
+	var vector4 = new THREE.Vector3();
+
+	var normal1 = new THREE.Vector3();
+	var normal2 = new THREE.Vector3();
+	var normal3 = new THREE.Vector3();
+	var normal4 = new THREE.Vector3();
+
+	var extrudeShape = function ( shape, offset, color ) {
+
+		for ( var j = 0, jl = shape.length; j < jl; j ++ ) {
+
+			var point1 = shape[ j ];
+			var point2 = shape[ ( j + 1 ) % jl ];
+
+			vector1.copy( point1 ).add( offset );
+			vector1.applyQuaternion( quaternion );
+			vector1.add( point );
+
+			vector2.copy( point2 ).add( offset );
+			vector2.applyQuaternion( quaternion );
+			vector2.add( point );
+
+			vector3.copy( point2 ).add( offset );
+			vector3.applyQuaternion( prevQuaternion );
+			vector3.add( prevPoint );
+
+			vector4.copy( point1 ).add( offset );
+			vector4.applyQuaternion( prevQuaternion );
+			vector4.add( prevPoint );
+
+			vertices.push( vector1.x, vector1.y, vector1.z );
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector3.x, vector3.y, vector3.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			//
+
+			normal1.copy( point1 );
+			normal1.applyQuaternion( quaternion );
+			normal1.normalize();
+
+			normal2.copy( point2 );
+			normal2.applyQuaternion( quaternion );
+			normal2.normalize();
+
+			normal3.copy( point2 );
+			normal3.applyQuaternion( prevQuaternion );
+			normal3.normalize();
+
+			normal4.copy( point1 );
+			normal4.applyQuaternion( prevQuaternion );
+			normal4.normalize();
+
+			normals.push( normal1.x, normal1.y, normal1.z );
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal3.x, normal3.y, normal3.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+			colors.push( color[ 0 ], color[ 1 ], color[ 2 ] );
+
+		}
+
+	};
+
+	var offset = new THREE.Vector3();
+
+	for ( var i = 1; i <= size; i ++ ) {
+
+		point.copy( curve.getPointAt( i / size ) );
+
+		up.set( 0, 1, 0 );
+
+		forward.subVectors( point, prevPoint ).normalize();
+		right.crossVectors( up, forward ).normalize();
+		up.crossVectors( forward, right );
+
+		var angle = Math.atan2( forward.x, forward.z );
+
+		quaternion.setFromAxisAngle( up, angle );
+
+		if ( i % 2 === 0 ) {
+
+			drawShape( step, color2 );
+
+		}
+
+		extrudeShape( tube1, offset.set( 0, -1.25, 0 ), color2 );
+		extrudeShape( tube2, offset.set( 2, 0, 0 ), color1 );
+		extrudeShape( tube2, offset.set( -2, 0, 0 ), color1 );
+
+		prevPoint.copy( point );
+		prevQuaternion.copy( quaternion );
+
+	}
+
+	// console.log( vertices.length );
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+	this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+	this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
+
+};
+
+RollerCoasterGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var RollerCoasterLiftersGeometry = function ( curve, size ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+	var normals = [];
+
+	var quaternion = new THREE.Quaternion();
+
+	var up = new THREE.Vector3( 0, 1, 0 );
+
+	var point = new THREE.Vector3();
+	var tangent = new THREE.Vector3();
+
+	// shapes
+
+	var tube1 = [
+		new THREE.Vector3(  0,  0.5, -0.5 ),
+		new THREE.Vector3(  0,  0.5,  0.5 ),
+		new THREE.Vector3(  0, -0.5,  0 )
+	];
+
+	var tube2 = [
+		new THREE.Vector3( -0.5, 0,  0.5 ),
+		new THREE.Vector3( -0.5, 0, -0.5 ),
+		new THREE.Vector3(  0.5, 0,  0 )
+	];
+
+	var tube3 = [
+		new THREE.Vector3(  0.5, 0, -0.5 ),
+		new THREE.Vector3(  0.5, 0,  0.5 ),
+		new THREE.Vector3( -0.5, 0,  0 )
+	];
+
+	var vector1 = new THREE.Vector3();
+	var vector2 = new THREE.Vector3();
+	var vector3 = new THREE.Vector3();
+	var vector4 = new THREE.Vector3();
+
+	var normal1 = new THREE.Vector3();
+	var normal2 = new THREE.Vector3();
+	var normal3 = new THREE.Vector3();
+	var normal4 = new THREE.Vector3();
+
+	var extrudeShape = function ( shape, fromPoint, toPoint ) {
+
+		for ( var j = 0, jl = shape.length; j < jl; j ++ ) {
+
+			var point1 = shape[ j ];
+			var point2 = shape[ ( j + 1 ) % jl ];
+
+			vector1.copy( point1 )
+			vector1.applyQuaternion( quaternion );
+			vector1.add( fromPoint );
+
+			vector2.copy( point2 )
+			vector2.applyQuaternion( quaternion );
+			vector2.add( fromPoint );
+
+			vector3.copy( point2 )
+			vector3.applyQuaternion( quaternion );
+			vector3.add( toPoint );
+
+			vector4.copy( point1 )
+			vector4.applyQuaternion( quaternion );
+			vector4.add( toPoint );
+
+			vertices.push( vector1.x, vector1.y, vector1.z );
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			vertices.push( vector2.x, vector2.y, vector2.z );
+			vertices.push( vector3.x, vector3.y, vector3.z );
+			vertices.push( vector4.x, vector4.y, vector4.z );
+
+			//
+
+			normal1.copy( point1 );
+			normal1.applyQuaternion( quaternion );
+			normal1.normalize();
+
+			normal2.copy( point2 );
+			normal2.applyQuaternion( quaternion );
+			normal2.normalize();
+
+			normal3.copy( point2 );
+			normal3.applyQuaternion( quaternion );
+			normal3.normalize();
+
+			normal4.copy( point1 );
+			normal4.applyQuaternion( quaternion );
+			normal4.normalize();
+
+			normals.push( normal1.x, normal1.y, normal1.z );
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+			normals.push( normal2.x, normal2.y, normal2.z );
+			normals.push( normal3.x, normal3.y, normal3.z );
+			normals.push( normal4.x, normal4.y, normal4.z );
+
+		}
+
+	};
+
+	var fromPoint = new THREE.Vector3();
+	var toPoint = new THREE.Vector3();
+
+	for ( var i = 1; i <= size; i ++ ) {
+
+		point.copy( curve.getPointAt( i / size ) );
+		tangent.copy( curve.getTangentAt( i / size ) );
+
+		var angle = Math.atan2( tangent.x, tangent.z );
+
+		quaternion.setFromAxisAngle( up, angle );
+
+		//
+
+		if ( point.y > 100 ) {
+
+			fromPoint.set( -7.5, -3.5, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( 7.5, -3.5, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube1, fromPoint, toPoint );
+
+			fromPoint.set( -7, -3, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( -7, -point.y, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube2, fromPoint, toPoint );
+
+			fromPoint.set( 7, -3, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( 7, -point.y, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube3, fromPoint, toPoint );
+
+		} else {
+
+			fromPoint.set( 0, -2, 0 );
+			fromPoint.applyQuaternion( quaternion );
+			fromPoint.add( point );
+
+			toPoint.set( 0, -point.y, 0 );
+			toPoint.applyQuaternion( quaternion );
+			toPoint.add( point );
+
+			extrudeShape( tube3, fromPoint, toPoint );
+
+		}
+
+	}
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+	this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+
+};
+
+RollerCoasterLiftersGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var RollerCoasterShadowGeometry = function ( curve, size ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+
+	var up = new THREE.Vector3( 0, 1, 0 );
+	var forward = new THREE.Vector3();
+
+	var quaternion = new THREE.Quaternion();
+	var prevQuaternion = new THREE.Quaternion();
+	prevQuaternion.setFromAxisAngle( up , Math.PI / 2 );
+
+	var point = new THREE.Vector3();
+
+	var prevPoint = new THREE.Vector3();
+	prevPoint.copy( curve.getPointAt( 0 ) );
+	prevPoint.y = 0;
+
+	var vector1 = new THREE.Vector3();
+	var vector2 = new THREE.Vector3();
+	var vector3 = new THREE.Vector3();
+	var vector4 = new THREE.Vector3();
+
+	for ( var i = 1; i <= size; i ++ ) {
+
+		point.copy( curve.getPointAt( i / size ) );
+		point.y = 0;
+
+		forward.subVectors( point, prevPoint );
+
+		var angle = Math.atan2( forward.x, forward.z );
+
+		quaternion.setFromAxisAngle( up, angle );
+
+		vector1.set( -3, 0, 0 );
+		vector1.applyQuaternion( quaternion );
+		vector1.add( point );
+
+		vector2.set(  3, 0, 0 );
+		vector2.applyQuaternion( quaternion );
+		vector2.add( point );
+
+		vector3.set(  3, 0, 0 );
+		vector3.applyQuaternion( prevQuaternion );
+		vector3.add( prevPoint );
+
+		vector4.set( -3, 0, 0 );
+		vector4.applyQuaternion( prevQuaternion );
+		vector4.add( prevPoint );
+
+		vertices.push( vector1.x, vector1.y, vector1.z );
+		vertices.push( vector2.x, vector2.y, vector2.z );
+		vertices.push( vector4.x, vector4.y, vector4.z );
+
+		vertices.push( vector2.x, vector2.y, vector2.z );
+		vertices.push( vector3.x, vector3.y, vector3.z );
+		vertices.push( vector4.x, vector4.y, vector4.z );
+
+		prevPoint.copy( point );
+		prevQuaternion.copy( quaternion );
+
+	}
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+
+};
+
+RollerCoasterShadowGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var SkyGeometry = function () {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+
+	for ( var i = 0; i < 100; i ++ ) {
+
+		var x = Math.random() * 8000 - 4000;
+		var y = Math.random() * 500 + 500;
+		var z = Math.random() * 8000 - 4000;
+
+		var size = Math.random() * 400 + 200;
+
+		vertices.push( x - size, y, z - size );
+		vertices.push( x + size, y, z - size );
+		vertices.push( x - size, y, z + size );
+
+		vertices.push( x + size, y, z - size );
+		vertices.push( x + size, y, z + size );
+		vertices.push( x - size, y, z + size );
+
+	}
+
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+
+};
+
+SkyGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+
+var TreesGeometry = function ( landscape ) {
+
+	THREE.BufferGeometry.call( this );
+
+	var vertices = [];
+	var colors = [];
+
+	var raycaster = new THREE.Raycaster();
+	raycaster.ray.direction.set( 0, -1, 0 );
+
+	for ( var i = 0; i < 2000; i ++ ) {
+
+		var x = Math.random() * 5000 - 2500;
+		var z = Math.random() * 5000 - 2500;
+
+		raycaster.ray.origin.set( x, 500, z );
+
+		var intersections = raycaster.intersectObject( landscape );
+
+		if ( intersections.length === 0 ) continue;
+
+		var y = intersections[ 0 ].point.y;
+
+		var height = Math.random() * 50 + 5;
+
+		var angle = Math.random() * Math.PI * 2;
+
+		vertices.push( x + Math.sin( angle ) * 10, y, z + Math.cos( angle ) * 10 );
+		vertices.push( x, y + height, z );
+		vertices.push( x + Math.sin( angle + Math.PI ) * 10, y, z + Math.cos( angle + Math.PI ) * 10 );
+
+		angle += Math.PI / 2;
+
+		vertices.push( x + Math.sin( angle ) * 10, y, z + Math.cos( angle ) * 10 );
+		vertices.push( x, y + height, z );
+		vertices.push( x + Math.sin( angle + Math.PI ) * 10, y, z + Math.cos( angle + Math.PI ) * 10 );
+
+		var random = Math.random() * 0.1;
+
+		for ( var j = 0; j < 6; j ++ ) {
+
+			colors.push( 0.2 + random, 0.4 + random, 0 );
+
+		}
+
+	}
+
+	this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
+	this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
+
+};
+
+TreesGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );

+ 4 - 10
examples/js/ShaderSkin.js

@@ -25,7 +25,6 @@ THREE.ShaderSkin = {
 		uniforms: THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
 
 			{
@@ -84,7 +83,6 @@ THREE.ShaderSkin = {
 
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
@@ -247,11 +245,9 @@ THREE.ShaderSkin = {
 
 				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;",
 
-				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-				THREE.ShaderChunk[ "fog_fragment" ],
-
-				"gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+				"gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 
+				THREE.ShaderChunk[ "fog_fragment" ],
 
 			"}"
 
@@ -311,7 +307,6 @@ THREE.ShaderSkin = {
 		uniforms: THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
 
 			{
@@ -370,7 +365,6 @@ THREE.ShaderSkin = {
 			"varying vec3 vViewPosition;",
 
 			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 
@@ -550,10 +544,10 @@ THREE.ShaderSkin = {
 
 				"}",
 
-				THREE.ShaderChunk[ "fog_fragment" ],
-
 				"gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 
+				THREE.ShaderChunk[ "fog_fragment" ],
+
 			"}"
 
 		].join( "\n" ),

+ 0 - 2
examples/js/ShaderTerrain.js

@@ -18,7 +18,6 @@ THREE.ShaderTerrain = {
 		uniforms: THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
 
 			{
@@ -88,7 +87,6 @@ THREE.ShaderTerrain = {
 
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],

+ 448 - 0
examples/js/Volume.js

@@ -0,0 +1,448 @@
+/**
+ * This class had been written to handle the output of the NRRD loader.
+ * It contains a volume of data and informations about it.
+ * For now it only handles 3 dimensional data.
+ * See the webgl_loader_nrrd.html example and the loaderNRRD.js file to see how to use this class.
+ * @class
+ * @author Valentin Demeusy / https://github.com/stity
+ * @param   {number}        xLength         Width of the volume
+ * @param   {number}        yLength         Length of the volume
+ * @param   {number}        zLength         Depth of the volume
+ * @param   {string}        type            The type of data (uint8, uint16, ...)
+ * @param   {ArrayBuffer}   arrayBuffer     The buffer with volume data
+ */
+THREE.Volume = function( xLength, yLength, zLength, type, arrayBuffer ) {
+
+	if ( arguments.length > 0 ) {
+
+		/**
+		 * @member {number} xLength Width of the volume in the IJK coordinate system
+		 */
+		this.xLength = Number( xLength ) || 1;
+		/**
+		 * @member {number} yLength Height of the volume in the IJK coordinate system
+		 */
+		this.yLength = Number( yLength ) || 1;
+		/**
+		 * @member {number} zLength Depth of the volume in the IJK coordinate system
+		 */
+		this.zLength = Number( zLength ) || 1;
+
+		/**
+		 * @member {TypedArray} data Data of the volume
+		 */
+
+		switch ( type ) {
+
+			case 'Uint8' :
+			case 'uint8' :
+			case 'uchar' :
+			case 'unsigned char' :
+			case 'uint8_t' :
+				this.data = new Uint8Array( arrayBuffer );
+				break;
+			case 'Int8' :
+			case 'int8' :
+			case 'signed char' :
+			case 'int8_t' :
+				this.data = new Int8Array( arrayBuffer );
+				break;
+			case 'Int16' :
+			case 'int16' :
+			case 'short' :
+			case 'short int' :
+			case 'signed short' :
+			case 'signed short int' :
+			case 'int16_t' :
+				this.data = new Int16Array( arrayBuffer );
+				break;
+			case 'Uint16' :
+			case 'uint16' :
+			case 'ushort' :
+			case 'unsigned short' :
+			case 'unsigned short int' :
+			case 'uint16_t' :
+				this.data = new Uint16Array( arrayBuffer );
+				break;
+			case 'Int32' :
+			case 'int32' :
+			case 'int' :
+			case 'signed int' :
+			case 'int32_t' :
+				this.data = new Int32Array( arrayBuffer );
+				break;
+			case 'Uint32' :
+			case 'uint32' :
+			case 'uint' :
+			case 'unsigned int' :
+			case 'uint32' :
+			case 'uint32_t' :
+				this.data = new Uint32Array( arrayBuffer );
+				break;
+			case 'longlong' :
+			case 'long long' :
+			case 'long long int' :
+			case 'signed long long' :
+			case 'signed long long int' :
+			case 'int64' :
+			case 'int64_t' :
+			case 'ulonglong' :
+			case 'unsigned long long' :
+			case 'unsigned long long int' :
+			case 'uint64' :
+			case 'uint64_t' :
+				throw 'Error in THREE.Volume constructor : this type is not supported in JavaScript';
+				break;
+			case 'Float32' :
+			case 'float32' :
+			case 'float' :
+				this.data = new Float32Array( arrayBuffer );
+				break;
+			case 'Float64' :
+			case 'float64' :
+			case 'double' :
+				this.data = new Float64Array( arrayBuffer );
+				break;
+			default :
+				this.data = new Uint8Array( arrayBuffer );
+
+		}
+
+		if ( this.data.length !== this.xLength * this.yLength * this.zLength ) {
+
+			throw 'Error in THREE.Volume constructor, lengths are not matching arrayBuffer size';
+
+		}
+
+	}
+
+	/**
+	 * @member {Array}  spacing Spacing to apply to the volume from IJK to RAS coordinate system
+	 */
+	this.spacing = [ 1, 1, 1 ];
+	/**
+	 * @member {Array}  offset Offset of the volume in the RAS coordinate system
+	 */
+	this.offset = [ 0, 0, 0 ];
+	/**
+	 * @member {THREE.Martrix3} matrix The IJK to RAS matrix
+	 */
+	this.matrix = new THREE.Matrix3();
+	this.matrix.identity();
+	/**
+	 * @member {THREE.Martrix3} inverseMatrix The RAS to IJK matrix
+	 */
+	/**
+	 * @member {number} lowerThreshold The voxels with values under this threshold won't appear in the slices.
+	 *                      If changed, geometryNeedsUpdate is automatically set to true on all the slices associated to this volume
+	 */
+	var lowerThreshold = - Infinity;
+	Object.defineProperty( this, 'lowerThreshold', {
+		get : function() {
+
+			return lowerThreshold;
+
+		},
+		set : function( value ) {
+
+			lowerThreshold = value;
+			this.sliceList.forEach( function( slice ) {
+
+				slice.geometryNeedsUpdate = true
+
+			} );
+
+		}
+	} );
+	/**
+	 * @member {number} upperThreshold The voxels with values over this threshold won't appear in the slices.
+	 *                      If changed, geometryNeedsUpdate is automatically set to true on all the slices associated to this volume
+	 */
+	var upperThreshold = Infinity;
+	Object.defineProperty( this, 'upperThreshold', {
+		get : function() {
+
+			return upperThreshold;
+
+		},
+		set : function( value ) {
+
+			upperThreshold = value;
+			this.sliceList.forEach( function( slice ) {
+
+				slice.geometryNeedsUpdate = true;
+
+			} );
+
+		}
+	} );
+
+
+	/**
+	 * @member {Array} sliceList The list of all the slices associated to this volume
+	 */
+	this.sliceList = [];
+
+
+	/**
+	 * @member {Array} RASDimensions This array holds the dimensions of the volume in the RAS space
+	 */
+
+}
+
+THREE.Volume.prototype = {
+
+	constructor : THREE.Volume,
+
+	/**
+	 * @member {Function} getData Shortcut for data[access(i,j,k)]
+	 * @memberof THREE.Volume
+	 * @param {number} i    First coordinate
+	 * @param {number} j    Second coordinate
+	 * @param {number} k    Third coordinate
+	 * @returns {number}  value in the data array
+	 */
+	getData : function( i, j, k ) {
+
+		return this.data[ k * this.xLength * this.yLength + j * this.xLength + i ];
+
+	},
+
+	/**
+	 * @member {Function} access compute the index in the data array corresponding to the given coordinates in IJK system
+	 * @memberof THREE.Volume
+	 * @param {number} i    First coordinate
+	 * @param {number} j    Second coordinate
+	 * @param {number} k    Third coordinate
+	 * @returns {number}  index
+	 */
+	access : function( i, j, k ) {
+
+		return k * this.xLength * this.yLength + j * this.xLength + i;
+
+	},
+
+	/**
+	 * @member {Function} reverseAccess Retrieve the IJK coordinates of the voxel corresponding of the given index in the data
+	 * @memberof THREE.Volume
+	 * @param {number} index index of the voxel
+	 * @returns {Array}  [x,y,z]
+	 */
+	reverseAccess : function( index ) {
+
+		var z = Math.floor( index / ( this.yLength * this.xLength ) );
+		var y = Math.floor( ( index - z * this.yLength * this.xLength ) / this.xLength );
+		var x = index - z * this.yLength * this.xLength - y * this.xLength;
+		return [ x, y, z ];
+
+	},
+
+	/**
+	 * @member {Function} map Apply a function to all the voxels, be careful, the value will be replaced
+	 * @memberof THREE.Volume
+	 * @param {Function} functionToMap A function to apply to every voxel, will be called with the following parameters :
+	 *                                 value of the voxel
+	 *                                 index of the voxel
+	 *                                 the data (TypedArray)
+	 * @param {Object}   context    You can specify a context in which call the function, default if this Volume
+	 * @returns {THREE.Volume}   this
+	 */
+	map : function( functionToMap, context ) {
+
+		var length = this.data.length;
+		context = context || this;
+
+		for ( var i = 0; i < length; i ++ ) {
+
+			this.data[ i ] = functionToMap.call( context, this.data[ i ], i, this.data );
+
+		}
+
+		return this;
+
+	},
+
+	/**
+	 * @member {Function} extractPerpendicularPlane Compute the orientation of the slice and returns all the information relative to the geometry such as sliceAccess, the plane matrix (orientation and position in RAS coordinate) and the dimensions of the plane in both coordinate system.
+	 * @memberof THREE.Volume
+	 * @param {string}            axis  the normal axis to the slice 'x' 'y' or 'z'
+	 * @param {number}            index the index of the slice
+	 * @returns {Object} an object containing all the usefull information on the geometry of the slice
+	 */
+	extractPerpendicularPlane : function( axis, RASIndex ) {
+
+		var iLength,
+		jLength,
+		sliceAccess,
+		planeMatrix = ( new THREE.Matrix4() ).identity(),
+		volume = this,
+		planeWidth,
+		planeHeight,
+		firstSpacing,
+		secondSpacing,
+		positionOffset,
+		IJKIndex;
+
+		var axisInIJK = new THREE.Vector3(),
+		firstDirection = new THREE.Vector3(),
+		secondDirection = new THREE.Vector3();
+
+		var dimensions = new THREE.Vector3( this.xLength, this.yLength, this.zLength );
+
+
+		switch ( axis ) {
+
+			case 'x' :
+				axisInIJK.set( 1, 0, 0 );
+				firstDirection.set( 0, 0, - 1 );
+				secondDirection.set( 0, - 1, 0 );
+				firstSpacing = this.spacing[ 2 ];
+				secondSpacing = this.spacing[ 1 ];
+				IJKIndex = new THREE.Vector3( RASIndex, 0, 0 );
+
+				planeMatrix.multiply( ( new THREE.Matrix4() ).makeRotationY( Math.PI / 2 ) );
+				positionOffset = ( volume.RASDimensions[ 0 ] - 1 ) / 2;
+				planeMatrix.setPosition( new THREE.Vector3( RASIndex - positionOffset, 0, 0 ) );
+				break;
+			case 'y' :
+				axisInIJK.set( 0, 1, 0 );
+				firstDirection.set( 1, 0, 0 );
+				secondDirection.set( 0, 0, 1 );
+				firstSpacing = this.spacing[ 0 ];
+				secondSpacing = this.spacing[ 2 ];
+				IJKIndex = new THREE.Vector3( 0, RASIndex, 0 );
+
+				planeMatrix.multiply( ( new THREE.Matrix4() ).makeRotationX( - Math.PI / 2 ) );
+				positionOffset = ( volume.RASDimensions[ 1 ] - 1 ) / 2;
+				planeMatrix.setPosition( new THREE.Vector3( 0, RASIndex - positionOffset, 0 ) );
+				break;
+			case 'z' :
+			default :
+				axisInIJK.set( 0, 0, 1 );
+				firstDirection.set( 1, 0, 0 );
+				secondDirection.set( 0, - 1, 0 );
+				firstSpacing = this.spacing[ 0 ];
+				secondSpacing = this.spacing[ 1 ];
+				IJKIndex = new THREE.Vector3( 0, 0, RASIndex );
+
+				positionOffset = ( volume.RASDimensions[ 2 ] - 1 ) / 2;
+				planeMatrix.setPosition( new THREE.Vector3( 0, 0, RASIndex - positionOffset ) );
+				break;
+		}
+
+		firstDirection.applyMatrix4( volume.inverseMatrix ).normalize();
+		firstDirection.argVar = 'i';
+		secondDirection.applyMatrix4( volume.inverseMatrix ).normalize();
+		secondDirection.argVar = 'j';
+		axisInIJK.applyMatrix4( volume.inverseMatrix ).normalize();
+		iLength = Math.floor( Math.abs( firstDirection.dot( dimensions ) ) );
+		jLength = Math.floor( Math.abs( secondDirection.dot( dimensions ) ) );
+		planeWidth = Math.abs( iLength * firstSpacing );
+		planeHeight = Math.abs( jLength * secondSpacing );
+
+		IJKIndex = Math.abs( Math.round( IJKIndex.applyMatrix4( volume.inverseMatrix ).dot( axisInIJK ) ) );
+		var base = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ];
+		var iDirection = [ firstDirection, secondDirection, axisInIJK ].find( function( x ) {
+
+			return Math.abs( x.dot( base[ 0 ] ) ) > 0.9;
+
+		} );
+		var jDirection = [ firstDirection, secondDirection, axisInIJK ].find( function( x ) {
+
+			return Math.abs( x.dot( base[ 1 ] ) ) > 0.9;
+
+		} );
+		var kDirection = [ firstDirection, secondDirection, axisInIJK ].find( function( x ) {
+
+			return Math.abs( x.dot( base[ 2 ] ) ) > 0.9;
+
+		} );
+		var argumentsWithInversion = [ 'volume.xLength-1-', 'volume.yLength-1-', 'volume.zLength-1-' ];
+		var arguments = [ 'i', 'j', 'k' ];
+		var argArray = [ iDirection, jDirection, kDirection ].map( function( direction, n ) {
+
+			return ( direction.dot( base[ n ] ) > 0 ? '' : argumentsWithInversion[ n ] ) + ( direction === axisInIJK ? 'IJKIndex' : direction.argVar )
+
+		} );
+		var argString = argArray.join( ',' );
+		sliceAccess = eval( '(function sliceAccess (i,j) {return volume.access( ' + argString + ');})' );
+
+
+		return {
+			iLength : iLength,
+			jLength : jLength,
+			sliceAccess : sliceAccess,
+			matrix : planeMatrix,
+			planeWidth : planeWidth,
+			planeHeight : planeHeight
+		}
+
+	},
+
+	/**
+	 * @member {Function} extractSlice Returns a slice corresponding to the given axis and index
+	 *                        The coordinate are given in the Right Anterior Superior coordinate format
+	 * @memberof THREE.Volume
+	 * @param {string}            axis  the normal axis to the slice 'x' 'y' or 'z'
+	 * @param {number}            index the index of the slice
+	 * @returns {THREE.VolumeSlice} the extracted slice
+	 */
+	extractSlice : function( axis, index ) {
+
+		var slice = new THREE.VolumeSlice( this, index, axis );
+		this.sliceList.push( slice );
+		return slice;
+
+	},
+
+	/**
+	 * @member {Function} repaintAllSlices Call repaint on all the slices extracted from this volume
+	 * @see THREE.VolumeSlice.repaint
+	 * @memberof THREE.Volume
+	 * @returns {THREE.Volume} this
+	 */
+	repaintAllSlices : function() {
+
+		this.sliceList.forEach( function( slice ) {
+
+			slice.repaint();
+
+		} );
+
+		return this;
+
+	},
+
+	/**
+	 * @member {Function} computeMinMax Compute the minimum and the maximum of the data in the volume
+	 * @memberof THREE.Volume
+	 * @returns {Array} [min,max]
+	 */
+	computeMinMax : function() {
+
+		var min = Infinity;
+		var max = - Infinity;
+
+		// buffer the length
+		var datasize = this.data.length;
+
+		var i = 0;
+		for ( i = 0; i < datasize; i ++ ) {
+
+			if ( ! isNaN( this.data[ i ] ) ) {
+
+				var value = this.data[ i ];
+				min = Math.min( min, value );
+				max = Math.max( max, value );
+
+			}
+
+		}
+		this.min = min;
+		this.max = max;
+
+		return [ min, max ];
+
+	}
+
+}

+ 217 - 0
examples/js/VolumeSlice.js

@@ -0,0 +1,217 @@
+/**
+ * This class has been made to hold a slice of a volume data
+ * @class
+ * @author Valentin Demeusy / https://github.com/stity
+ * @param   {THREE.Volume} volume    The associated volume
+ * @param   {number}       [index=0] The index of the slice
+ * @param   {string}       [axis='z']      For now only 'x', 'y' or 'z' but later it will change to a normal vector
+ * @see THREE.Volume
+ */
+THREE.VolumeSlice = function( volume, index, axis ) {
+
+	var slice = this;
+	/**
+	 * @member {THREE.Volume} volume The associated volume
+	 */
+	this.volume = volume;
+	/**
+	 * @member {Number} index The index of the slice, if changed, will automatically call updateGeometry at the next repaint
+	 */
+	index = index || 0;
+	Object.defineProperty( this, 'index', {
+		get : function() {
+
+			return index;
+
+		},
+		set : function( value ) {
+
+			index = value;
+			slice.geometryNeedsUpdate = true;
+			return index;
+
+		}
+	} );
+	/**
+	 * @member {String} axis The normal axis
+	 */
+	this.axis = axis || 'z';
+
+	/**
+	 * @member {HTMLCanvasElement} canvas The final canvas used for the texture
+	 */
+	/**
+	 * @member {CanvasRenderingContext2D} ctx Context of the canvas
+	 */
+	this.canvas = document.createElement( 'canvas' );
+	/**
+	 * @member {HTMLCanvasElement} canvasBuffer The intermediary canvas used to paint the data
+	 */
+	/**
+	 * @member {CanvasRenderingContext2D} ctxBuffer Context of the canvas buffer
+	 */
+	this.canvasBuffer = document.createElement( 'canvas' );
+	this.updateGeometry();
+
+
+	var canvasMap = new THREE.Texture( this.canvas );
+	canvasMap.minFilter = THREE.LinearFilter;
+	canvasMap.wrapS = canvasMap.wrapT = THREE.ClampToEdgeWrapping;
+	var material = new THREE.MeshBasicMaterial( { map: canvasMap, side: THREE.DoubleSide, transparent : true } );
+	/**
+	 * @member {THREE.Mesh} mesh The mesh ready to get used in the scene
+	 */
+	this.mesh = new THREE.Mesh( this.geometry, material );
+	/**
+	 * @member {Boolean} geometryNeedsUpdate If set to true, updateGeometry will be triggered at the next repaint
+	 */
+	this.geometryNeedsUpdate = true;
+	this.repaint();
+
+	/**
+	 * @member {Number} iLength Width of slice in the original coordinate system, corresponds to the width of the buffer canvas
+	 */
+
+	/**
+	 * @member {Number} jLength Height of slice in the original coordinate system, corresponds to the height of the buffer canvas
+	 */
+
+	/**
+	 * @member {Function} sliceAccess Function that allow the slice to access right data
+	 * @see THREE.Volume.extractPerpendicularPlane
+	 * @param {Number} i The first coordinate
+	 * @param {Number} j The second coordinate
+	 * @returns {Number} the index corresponding to the voxel in volume.data of the given position in the slice
+	 */
+
+
+}
+
+THREE.VolumeSlice.prototype = {
+
+	constructor : THREE.VolumeSlice,
+
+	/**
+	 * @member {Function} repaint Refresh the texture and the geometry if geometryNeedsUpdate is set to true
+	 * @memberof THREE.VolumeSlice
+	 */
+	repaint : function() {
+
+		if ( this.geometryNeedsUpdate ) {
+
+			this.updateGeometry();
+
+		}
+
+		var iLength = this.iLength,
+		jLength = this.jLength,
+		sliceAccess = this.sliceAccess,
+		volume = this.volume,
+		axis = this.axis,
+		index = this.index,
+		canvas = this.canvasBuffer,
+		ctx = this.ctxBuffer;
+
+
+		// get the imageData and pixel array from the canvas
+		var imgData = ctx.getImageData( 0, 0, iLength, jLength );
+		var data = imgData.data;
+		var volumeData = volume.data;
+		var upperThreshold = volume.upperThreshold;
+		var lowerThreshold = volume.lowerThreshold;
+		var windowLow = volume.windowLow;
+		var windowHigh = volume.windowHigh;
+
+		// manipulate some pixel elements
+		var pixelCount = 0;
+
+		if ( volume.dataType === 'label' ) {
+
+			//this part is currently useless but will be used when colortables will be handled
+			for ( var j = 0; j < jLength; j ++ ) {
+
+				for ( var i = 0; i < iLength; i ++ ) {
+
+					var label = volumeData[ sliceAccess( i, j ) ];
+					label = label >= this.colorMap.length ? ( label % this.colorMap.length ) + 1 : label;
+					var color = this.colorMap[ label ];
+					data[ 4 * pixelCount ] = ( color >> 24 ) & 0xff;
+					data[ 4 * pixelCount + 1 ] = ( color >> 16 ) & 0xff;
+					data[ 4 * pixelCount + 2 ] = ( color >> 8 ) & 0xff;
+					data[ 4 * pixelCount + 3 ] = color & 0xff;
+					pixelCount ++;
+
+				}
+
+			}
+
+		}
+		else {
+
+			for ( var j = 0; j < jLength; j ++ ) {
+
+				for ( var i = 0; i < iLength; i ++ ) {
+
+					var value = volumeData[ sliceAccess( i, j ) ];
+					var alpha = 0xff;
+					//apply threshold
+					alpha = upperThreshold >= value ? ( lowerThreshold <= value ? alpha : 0 ) : 0;
+					//apply window level
+					value = Math.floor( 255 * ( value - windowLow ) / ( windowHigh - windowLow ) );
+					value = value > 255 ? 255 : ( value < 0 ? 0 : value | 0 );
+
+					data[ 4 * pixelCount ] = value;
+					data[ 4 * pixelCount + 1 ] = value;
+					data[ 4 * pixelCount + 2 ] = value;
+					data[ 4 * pixelCount + 3 ] = alpha;
+					pixelCount ++;
+
+				}
+
+			}
+
+		}
+		ctx.putImageData( imgData, 0, 0 );
+		this.ctx.drawImage( canvas, 0, 0, iLength, jLength, 0, 0, this.canvas.width, this.canvas.height );
+
+
+		this.mesh.material.map.needsUpdate = true;
+
+	},
+
+	/**
+	 * @member {Function} Refresh the geometry according to axis and index
+	 * @see THREE.Volume.extractPerpendicularPlane
+	 * @memberof THREE.VolumeSlice
+	 */
+	updateGeometry : function() {
+
+		var extracted = this.volume.extractPerpendicularPlane( this.axis, this.index );
+		this.sliceAccess = extracted.sliceAccess;
+		this.jLength = extracted.jLength;
+		this.iLength = extracted.iLength;
+		this.matrix = extracted.matrix;
+
+		this.canvas.width = extracted.planeWidth;
+		this.canvas.height = extracted.planeHeight;
+		this.canvasBuffer.width = this.iLength;
+		this.canvasBuffer.height = this.jLength;
+		this.ctx = this.canvas.getContext( '2d' );
+		this.ctxBuffer = this.canvasBuffer.getContext( '2d' );
+
+		this.geometry = new THREE.PlaneGeometry( extracted.planeWidth, extracted.planeHeight );
+
+		if ( this.mesh ) {
+
+			this.mesh.geometry = this.geometry;
+			//reset mesh matrix
+			this.mesh.matrix = ( new THREE.Matrix4() ).identity();
+			this.mesh.applyMatrix( this.matrix );
+
+		}
+
+		this.geometryNeedsUpdate = false;
+
+	}
+
+}

+ 97 - 0
examples/js/WebVR.js

@@ -0,0 +1,97 @@
+/**
+ * @author mrdoob / http://mrdoob.com
+ * Based on @tojiro's vr-samples-utils.js
+ */
+
+var WEBVR = {
+
+	isLatestAvailable: function () {
+
+		return navigator.getVRDisplays !== undefined;
+
+	},
+
+	isAvailable: function () {
+
+		return navigator.getVRDisplays !== undefined || navigator.getVRDevices !== undefined;
+
+	},
+
+	getMessage: function () {
+
+		var message;
+
+		if ( navigator.getVRDisplays ) {
+
+			navigator.getVRDisplays().then( function ( displays ) {
+
+				if ( displays.length === 0 ) message = 'WebVR supported, but no VRDisplays found.';
+
+			} );
+
+		} else if ( navigator.getVRDevices ) {
+
+			message = 'Your browser supports WebVR but not the latest version. See <a href="http://webvr.info">webvr.info</a> for more info.';
+
+		} else {
+
+			message = 'Your browser does not support WebVR. See <a href="http://webvr.info">webvr.info</a> for assistance.';
+
+		}
+
+		if ( message !== undefined ) {
+
+			var container = document.createElement( 'div' );
+			container.style.position = 'absolute';
+			container.style.left = '0';
+			container.style.top = '0';
+			container.style.right = '0';
+			container.style.zIndex = '999';
+			container.align = 'center';
+
+			var error = document.createElement( 'div' );
+			error.style.fontFamily = 'sans-serif';
+			error.style.fontSize = '16px';
+			error.style.fontStyle = 'normal';
+			error.style.lineHeight = '26px';
+			error.style.backgroundColor = '#fff';
+			error.style.color = '#000';
+			error.style.padding = '10px 20px';
+			error.style.margin = '50px';
+			error.style.display = 'inline-block';
+			error.innerHTML = message;
+			container.appendChild( error );
+
+			return container;
+
+		}
+
+	},
+
+	getButton: function ( effect ) {
+
+		var button = document.createElement( 'button' );
+		button.style.position = 'absolute';
+		button.style.left = 'calc(50% - 30px)';
+		button.style.bottom = '20px';
+		button.style.border = '0';
+		button.style.padding = '8px';
+		button.style.cursor = 'pointer';
+		button.style.backgroundColor = '#000';
+		button.style.color = '#fff';
+		button.style.fontFamily = 'sans-serif';
+		button.style.fontSize = '13px';
+		button.style.fontStyle = 'normal';
+		button.style.zIndex = '999';
+		button.textContent = 'ENTER VR';
+		button.onclick = function() {
+
+			effect.setFullScreen( true );
+
+		};
+
+		return button;
+
+	}
+
+};

+ 6 - 12
examples/js/controls/EditorControls.js

@@ -26,6 +26,7 @@ THREE.EditorControls = function ( object, domElement ) {
 	var normalMatrix = new THREE.Matrix3();
 	var pointer = new THREE.Vector2();
 	var pointerOld = new THREE.Vector2();
+	var spherical = new THREE.Spherical();
 
 	// events
 
@@ -86,21 +87,14 @@ THREE.EditorControls = function ( object, domElement ) {
 
 		vector.copy( object.position ).sub( center );
 
-		var theta = Math.atan2( vector.x, vector.z );
-		var phi = Math.atan2( Math.sqrt( vector.x * vector.x + vector.z * vector.z ), vector.y );
+		spherical.setFromVector3( vector );
 
-		theta += delta.x;
-		phi += delta.y;
+		spherical.theta += delta.x;
+		spherical.phi += delta.y;
 
-		var EPS = 0.000001;
+		spherical.makeSafe();
 
-		phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
-
-		var radius = vector.length();
-
-		vector.x = radius * Math.sin( phi ) * Math.sin( theta );
-		vector.y = radius * Math.cos( phi );
-		vector.z = radius * Math.sin( phi ) * Math.cos( theta );
+		vector.setFromSpherical( spherical );
 
 		object.position.copy( center ).add( vector );
 

+ 21 - 39
examples/js/controls/OrbitControls.js

@@ -133,12 +133,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 			offset.applyQuaternion( quat );
 
 			// angle from z-axis around y-axis
-
-			theta = Math.atan2( offset.x, offset.z );
-
-			// angle from y-axis
-
-			phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
+			spherical.setFromVector3( offset );
 
 			if ( scope.autoRotate && state === STATE.NONE ) {
 
@@ -146,29 +141,27 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 			}
 
-			theta += thetaDelta;
-			phi += phiDelta;
+			spherical.theta += sphericalDelta.theta;
+			spherical.phi += sphericalDelta.phi;
 
 			// restrict theta to be between desired limits
-			theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, theta ) );
+			spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
 
 			// restrict phi to be between desired limits
-			phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, phi ) );
+			spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
+
+			spherical.makeSafe();
 
-			// restrict phi to be betwee EPS and PI-EPS
-			phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
 
-			var radius = offset.length() * scale;
+			spherical.radius *= scale;
 
 			// restrict radius to be between desired limits
-			radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, radius ) );
+			spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
 
 			// move target to panned location
 			scope.target.add( panOffset );
 
-			offset.x = radius * Math.sin( phi ) * Math.sin( theta );
-			offset.y = radius * Math.cos( phi );
-			offset.z = radius * Math.sin( phi ) * Math.cos( theta );
+			offset.setFromSpherical( spherical );
 
 			// rotate offset back to "camera-up-vector-is-up" space
 			offset.applyQuaternion( quatInverse );
@@ -179,13 +172,12 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 			if ( scope.enableDamping === true ) {
 
-				thetaDelta *= ( 1 - scope.dampingFactor );
-				phiDelta *= ( 1 - scope.dampingFactor );
+				sphericalDelta.theta *= ( 1 - scope.dampingFactor );
+				sphericalDelta.phi *= ( 1 - scope.dampingFactor );
 
 			} else {
 
-				thetaDelta = 0;
-				phiDelta = 0;
+				sphericalDelta.set( 0, 0, 0 );
 
 			}
 
@@ -254,11 +246,9 @@ THREE.OrbitControls = function ( object, domElement ) {
 	var EPS = 0.000001;
 
 	// current position in spherical coordinates
-	var theta;
-	var phi;
+	var spherical = new THREE.Spherical();
+	var sphericalDelta = new THREE.Spherical();
 
-	var phiDelta = 0;
-	var thetaDelta = 0;
 	var scale = 1;
 	var panOffset = new THREE.Vector3();
 	var zoomChanged = false;
@@ -289,13 +279,13 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function rotateLeft( angle ) {
 
-		thetaDelta -= angle;
+		sphericalDelta.theta -= angle;
 
 	}
 
 	function rotateUp( angle ) {
 
-		phiDelta -= angle;
+		sphericalDelta.phi -= angle;
 
 	}
 
@@ -305,11 +295,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		return function panLeft( distance, objectMatrix ) {
 
-			var te = objectMatrix.elements;
-
-			// get X column of objectMatrix
-			v.set( te[ 0 ], te[ 1 ], te[ 2 ] );
-
+			v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
 			v.multiplyScalar( - distance );
 
 			panOffset.add( v );
@@ -324,11 +310,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		return function panUp( distance, objectMatrix ) {
 
-			var te = objectMatrix.elements;
-
-			// get Y column of objectMatrix
-			v.set( te[ 4 ], te[ 5 ], te[ 6 ] );
-
+			v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix
 			v.multiplyScalar( distance );
 
 			panOffset.add( v );
@@ -363,8 +345,8 @@ THREE.OrbitControls = function ( object, domElement ) {
 			} else if ( scope.object instanceof THREE.OrthographicCamera ) {
 
 				// orthographic
-				panLeft( deltaX * ( scope.object.right - scope.object.left ) / element.clientWidth, scope.object.matrix );
-				panUp( deltaY * ( scope.object.top - scope.object.bottom ) / element.clientHeight, scope.object.matrix );
+				panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
+				panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
 
 			} else {
 

+ 19 - 0
examples/js/controls/TrackballControls.js

@@ -356,6 +356,8 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		window.removeEventListener( 'keydown', keydown );
+
 		_prevState = _state;
 
 		if ( _state !== STATE.NONE ) {
@@ -384,12 +386,17 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		_state = _prevState;
 
+		window.addEventListener( 'keydown', keydown, false );
+
 	}
 
 	function mousedown( event ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		if ( _state === STATE.NONE ) {
 
 			_state = event.button;
@@ -424,6 +431,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		if ( _state === STATE.ROTATE && ! _this.noRotate ) {
 
 			_movePrev.copy( _moveCurr );
@@ -445,6 +455,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		_state = STATE.NONE;
 
 		document.removeEventListener( 'mousemove', mousemove );
@@ -457,6 +470,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		var delta = 0;
 
 		if ( event.wheelDelta ) {
@@ -513,6 +529,9 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 		if ( _this.enabled === false ) return;
 
+		event.preventDefault();
+		event.stopPropagation();
+
 		switch ( event.touches.length ) {
 
 			case 1:

+ 5 - 3
examples/js/effects/AnaglyphEffect.js

@@ -71,11 +71,13 @@ THREE.AnaglyphEffect = function ( renderer, width, height ) {
 
 	this.setSize = function ( width, height ) {
 
-		_renderTargetL.setSize( width, height );
-		_renderTargetR.setSize( width, height );
-
 		renderer.setSize( width, height );
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
+		_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 
 	this.render = function ( scene, camera ) {

+ 4 - 2
examples/js/effects/CardboardEffect.js

@@ -70,10 +70,12 @@ THREE.CardboardEffect = function ( renderer ) {
 
 	this.setSize = function ( width, height ) {
 
-		_renderTarget.setSize( width, height );
-
 		renderer.setSize( width, height );
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTarget.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 
 	this.render = function ( scene, camera ) {

+ 5 - 3
examples/js/effects/ParallaxBarrierEffect.js

@@ -70,11 +70,13 @@ THREE.ParallaxBarrierEffect = function ( renderer ) {
 
 	this.setSize = function ( width, height ) {
 
-		_renderTargetL.setSize( width, height );
-		_renderTargetR.setSize( width, height );
-
 		renderer.setSize( width, height );
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
+		_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 
 	this.render = function ( scene, camera ) {

+ 71 - 4
examples/js/exporters/OBJExporter.js

@@ -123,11 +123,11 @@ THREE.OBJExporter.prototype = {
 					var face = faces[ i ];
 
 					for ( var m = 0; m < 3; m ++ ) {
-					
+
 					    indices[ m ] = ( indexVertex + face[ faceVertexKeys[ m ] ] + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + m + 1 ) : '' ) + '/' + ( indexNormals + j + m + 1 );
-					
+
 					}
-					
+
 					output += 'f ' + indices.join( ' ' ) + "\n";
 
 				}
@@ -145,9 +145,76 @@ THREE.OBJExporter.prototype = {
 
 		};
 
+		var parseLine = function( line ) {
+
+			var geometry = line.geometry;
+			var type = line.type;
+
+			if ( geometry instanceof THREE.BufferGeometry ) {
+
+				geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+
+			}
+
+			if ( geometry instanceof THREE.Geometry ) {
+
+				output += 'o ' + line.name + '\n';
+
+				var vertices = geometry.vertices;
+
+				for ( var i = 0, l = vertices.length; i < l; i++ ) {
+
+					var vertex = vertices[ i ].clone();
+					vertex.applyMatrix4( line.matrixWorld );
+
+					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
+
+				}
+
+				if ( type === 'Line' ) {
+
+					output += 'l ';
+
+					for ( var j = 1, m = vertices.length; j <= m; j++ ) {
+
+						output += j + ' ';
+
+					}
+
+					output += '\n';
+
+				}
+
+				if ( type === 'LineSegments' ) {
+
+					for ( var j = 1, k = j + 1, m = vertices.length; j < m; j += 2, k = j + 1 ) {
+
+						output += 'l ' + j + ' ' + k + '\n';
+
+					}
+
+				}
+
+			} else {
+
+				console.warn('THREE.OBJExporter.parseLine(): geometry type unsupported', line);
+
+			}
+		};
+
 		object.traverse( function ( child ) {
 
-			if ( child instanceof THREE.Mesh ) parseMesh( child );
+			if ( child instanceof THREE.Mesh ) {
+
+				parseMesh( child );
+
+			}
+
+			if ( child instanceof THREE.Line ) {
+
+				parseLine( child );
+
+			}
 
 		} );
 

+ 25 - 19
examples/js/exporters/STLBinaryExporter.js

@@ -17,11 +17,29 @@ THREE.STLBinaryExporter.prototype = {
 
 		return function parse( scene ) {
 
+			// We collect objects first, as we may need to convert from BufferGeometry to Geometry
+			var objects = [];
 			var triangles = 0;
 			scene.traverse( function ( object ) {
 
 				if ( ! ( object instanceof THREE.Mesh ) ) return;
-				triangles += object.geometry.faces.length;
+
+				var geometry = object.geometry;
+				if ( geometry instanceof THREE.BufferGeometry ) {
+
+					geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+
+				}
+
+				if ( ! ( geometry instanceof THREE.Geometry ) ) return;
+				triangles += geometry.faces.length;
+
+				objects.push( {
+
+					geometry: geometry,
+					matrix: object.matrixWorld
+
+				} );
 
 			} );
 
@@ -31,25 +49,13 @@ THREE.STLBinaryExporter.prototype = {
 			var output = new DataView( arrayBuffer );
 			output.setUint32( offset, triangles, true ); offset += 4;
 
-			scene.traverse( function ( object ) {
-
-				if ( ! ( object instanceof THREE.Mesh ) ) return;
-
-				var geometry = object.geometry;
-				if ( geometry instanceof THREE.BufferGeometry ) {
-                            
-					geometry = new THREE.Geometry().fromBufferGeometry( geometry );
-                            
-				}
-
-				if ( ! ( geometry instanceof THREE.Geometry ) ) return;
-
-				var matrixWorld = object.matrixWorld;
+			// Traversing our collected objects
+			objects.forEach( function ( object ) {
 
-				var vertices = geometry.vertices;
-				var faces = geometry.faces;
+				var vertices = object.geometry.vertices;
+				var faces = object.geometry.faces;
 
-				normalMatrixWorld.getNormalMatrix( matrixWorld );
+				normalMatrixWorld.getNormalMatrix( object.matrix );
 
 				for ( var i = 0, l = faces.length; i < l; i ++ ) {
 
@@ -65,7 +71,7 @@ THREE.STLBinaryExporter.prototype = {
 
 					for ( var j = 0; j < 3; j ++ ) {
 
-						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( matrixWorld );
+						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( object.matrix );
 
 						output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
 						output.setFloat32( offset, vector.y, true ); offset += 4;

+ 15 - 0
examples/js/libs/inflate.min.js

@@ -0,0 +1,15 @@
+/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';var m=this;function q(c,d){var a=c.split("."),b=m;!(a[0]in b)&&b.execScript&&b.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&void 0!==d?b[e]=d:b=b[e]?b[e]:b[e]={}};var s="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function t(c){var d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,l,p,n,r,K;for(n=0;n<d;++n)c[n]>a&&(a=c[n]),c[n]<b&&(b=c[n]);e=1<<a;f=new (s?Uint32Array:Array)(e);g=1;h=0;for(k=2;g<=a;){for(n=0;n<d;++n)if(c[n]===g){l=0;p=h;for(r=0;r<g;++r)l=l<<1|p&1,p>>=1;K=g<<16|n;for(r=l;r<e;r+=k)f[r]=K;++h}++g;h<<=1;k<<=1}return[f,a,b]};function u(c,d){this.g=[];this.h=32768;this.d=this.f=this.a=this.l=0;this.input=s?new Uint8Array(c):c;this.m=!1;this.i=v;this.s=!1;if(d||!(d={}))d.index&&(this.a=d.index),d.bufferSize&&(this.h=d.bufferSize),d.bufferType&&(this.i=d.bufferType),d.resize&&(this.s=d.resize);switch(this.i){case w:this.b=32768;this.c=new (s?Uint8Array:Array)(32768+this.h+258);break;case v:this.b=0;this.c=new (s?Uint8Array:Array)(this.h);this.e=this.A;this.n=this.w;this.j=this.z;break;default:throw Error("invalid inflate mode");
+}}var w=0,v=1,x={u:w,t:v};
+u.prototype.k=function(){for(;!this.m;){var c=y(this,3);c&1&&(this.m=!0);c>>>=1;switch(c){case 0:var d=this.input,a=this.a,b=this.c,e=this.b,f=d.length,g=void 0,h=void 0,k=b.length,l=void 0;this.d=this.f=0;if(a+1>=f)throw Error("invalid uncompressed block header: LEN");g=d[a++]|d[a++]<<8;if(a+1>=f)throw Error("invalid uncompressed block header: NLEN");h=d[a++]|d[a++]<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case w:for(;e+
+g>b.length;){l=k-e;g-=l;if(s)b.set(d.subarray(a,a+l),e),e+=l,a+=l;else for(;l--;)b[e++]=d[a++];this.b=e;b=this.e();e=this.b}break;case v:for(;e+g>b.length;)b=this.e({p:2});break;default:throw Error("invalid inflate mode");}if(s)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.a=a;this.b=e;this.c=b;break;case 1:this.j(z,A);break;case 2:B(this);break;default:throw Error("unknown BTYPE: "+c);}}return this.n()};
+var C=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=s?new Uint16Array(C):C,E=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],F=s?new Uint16Array(E):E,G=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],H=s?new Uint8Array(G):G,I=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],J=s?new Uint16Array(I):I,L=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,
+13],M=s?new Uint8Array(L):L,N=new (s?Uint8Array:Array)(288),O,P;O=0;for(P=N.length;O<P;++O)N[O]=143>=O?8:255>=O?9:279>=O?7:8;var z=t(N),Q=new (s?Uint8Array:Array)(30),R,S;R=0;for(S=Q.length;R<S;++R)Q[R]=5;var A=t(Q);function y(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h;b<d;){if(f>=g)throw Error("input buffer is broken");a|=e[f++]<<b;b+=8}h=a&(1<<d)-1;c.f=a>>>d;c.d=b-d;c.a=f;return h}
+function T(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h=d[0],k=d[1],l,p;b<k&&!(f>=g);)a|=e[f++]<<b,b+=8;l=h[a&(1<<k)-1];p=l>>>16;c.f=a>>p;c.d=b-p;c.a=f;return l&65535}
+function B(c){function d(a,c,b){var d,e=this.q,f,g;for(g=0;g<a;)switch(d=T(this,c),d){case 16:for(f=3+y(this,2);f--;)b[g++]=e;break;case 17:for(f=3+y(this,3);f--;)b[g++]=0;e=0;break;case 18:for(f=11+y(this,7);f--;)b[g++]=0;e=0;break;default:e=b[g++]=d}this.q=e;return b}var a=y(c,5)+257,b=y(c,5)+1,e=y(c,4)+4,f=new (s?Uint8Array:Array)(D.length),g,h,k,l;for(l=0;l<e;++l)f[D[l]]=y(c,3);if(!s){l=e;for(e=f.length;l<e;++l)f[D[l]]=0}g=t(f);h=new (s?Uint8Array:Array)(a);k=new (s?Uint8Array:Array)(b);c.q=0;
+c.j(t(d.call(c,a,g,h)),t(d.call(c,b,g,k)))}u.prototype.j=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length-258,f,g,h,k;256!==(f=T(this,c));)if(256>f)b>=e&&(this.b=b,a=this.e(),b=this.b),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=T(this,d);h=J[f];0<M[f]&&(h+=y(this,M[f]));b>=e&&(this.b=b,a=this.e(),b=this.b);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
+u.prototype.z=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length,f,g,h,k;256!==(f=T(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=T(this,d);h=J[f];0<M[f]&&(h+=y(this,M[f]));b+k>e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
+u.prototype.e=function(){var c=new (s?Uint8Array:Array)(this.b-32768),d=this.b-32768,a,b,e=this.c;if(s)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;a<b;++a)c[a]=e[a+32768]}this.g.push(c);this.l+=c.length;if(s)e.set(e.subarray(d,d+32768));else for(a=0;32768>a;++a)e[a]=e[d+a];this.b=32768;return e};
+u.prototype.A=function(c){var d,a=this.input.length/this.a+1|0,b,e,f,g=this.input,h=this.c;c&&("number"===typeof c.p&&(a=c.p),"number"===typeof c.v&&(a+=c.v));2>a?(b=(g.length-this.a)/this.o[2],f=258*(b/2)|0,e=f<h.length?h.length+f:h.length<<1):e=h.length*a;s?(d=new Uint8Array(e),d.set(h)):d=h;return this.c=d};
+u.prototype.n=function(){var c=0,d=this.c,a=this.g,b,e=new (s?Uint8Array:Array)(this.l+(this.b-32768)),f,g,h,k;if(0===a.length)return s?this.c.subarray(32768,this.b):this.c.slice(32768,this.b);f=0;for(g=a.length;f<g;++f){b=a[f];h=0;for(k=b.length;h<k;++h)e[c++]=b[h]}f=32768;for(g=this.b;f<g;++f)e[c++]=d[f];this.g=[];return this.buffer=e};
+u.prototype.w=function(){var c,d=this.b;s?this.s?(c=new Uint8Array(d),c.set(this.c.subarray(0,d))):c=this.c.subarray(0,d):(this.c.length>d&&(this.c.length=d),c=this.c);return this.buffer=c};function U(c,d){var a,b;this.input=c;this.a=0;if(d||!(d={}))d.index&&(this.a=d.index),d.verify&&(this.B=d.verify);a=c[this.a++];b=c[this.a++];switch(a&15){case V:this.method=V;break;default:throw Error("unsupported compression method");}if(0!==((a<<8)+b)%31)throw Error("invalid fcheck flag:"+((a<<8)+b)%31);if(b&32)throw Error("fdict flag is not supported");this.r=new u(c,{index:this.a,bufferSize:d.bufferSize,bufferType:d.bufferType,resize:d.resize})}
+U.prototype.k=function(){var c=this.input,d,a;d=this.r.k();this.a=this.r.a;if(this.B){a=(c[this.a++]<<24|c[this.a++]<<16|c[this.a++]<<8|c[this.a++])>>>0;var b=d;if("string"===typeof b){var e=b.split(""),f,g;f=0;for(g=e.length;f<g;f++)e[f]=(e[f].charCodeAt(0)&255)>>>0;b=e}for(var h=1,k=0,l=b.length,p,n=0;0<l;){p=1024<l?1024:l;l-=p;do h+=b[n++],k+=h;while(--p);h%=65521;k%=65521}if(a!==(k<<16|h)>>>0)throw Error("invalid adler-32 checksum");}return d};var V=8;q("Zlib.Inflate",U);q("Zlib.Inflate.prototype.decompress",U.prototype.k);var W={ADAPTIVE:x.t,BLOCK:x.u},X,Y,Z,$;if(Object.keys)X=Object.keys(W);else for(Y in X=[],Z=0,W)X[Z++]=Y;Z=0;for($=X.length;Z<$;++Z)Y=X[Z],q("Zlib.Inflate.BufferType."+Y,W[Y]);}).call(this);

+ 51 - 0
examples/js/libs/zlib_and_gzip.min.js

@@ -0,0 +1,51 @@
+/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';function q(b){throw b;}var t=void 0,u=!0,aa=this;function A(b,a){var c=b.split("."),d=aa;!(c[0]in d)&&d.execScript&&d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)!c.length&&a!==t?d[e]=a:d=d[e]?d[e]:d[e]={}};var B="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function F(b,a){this.index="number"===typeof a?a:0;this.m=0;this.buffer=b instanceof(B?Uint8Array:Array)?b:new (B?Uint8Array:Array)(32768);2*this.buffer.length<=this.index&&q(Error("invalid index"));this.buffer.length<=this.index&&this.f()}F.prototype.f=function(){var b=this.buffer,a,c=b.length,d=new (B?Uint8Array:Array)(c<<1);if(B)d.set(b);else for(a=0;a<c;++a)d[a]=b[a];return this.buffer=d};
+F.prototype.d=function(b,a,c){var d=this.buffer,e=this.index,f=this.m,g=d[e],k;c&&1<a&&(b=8<a?(H[b&255]<<24|H[b>>>8&255]<<16|H[b>>>16&255]<<8|H[b>>>24&255])>>32-a:H[b]>>8-a);if(8>a+f)g=g<<a|b,f+=a;else for(k=0;k<a;++k)g=g<<1|b>>a-k-1&1,8===++f&&(f=0,d[e++]=H[g],g=0,e===d.length&&(d=this.f()));d[e]=g;this.buffer=d;this.m=f;this.index=e};F.prototype.finish=function(){var b=this.buffer,a=this.index,c;0<this.m&&(b[a]<<=8-this.m,b[a]=H[b[a]],a++);B?c=b.subarray(0,a):(b.length=a,c=b);return c};
+var ba=new (B?Uint8Array:Array)(256),ca;for(ca=0;256>ca;++ca){for(var K=ca,da=K,ea=7,K=K>>>1;K;K>>>=1)da<<=1,da|=K&1,--ea;ba[ca]=(da<<ea&255)>>>0}var H=ba;function ja(b,a,c){var d,e="number"===typeof a?a:a=0,f="number"===typeof c?c:b.length;d=-1;for(e=f&7;e--;++a)d=d>>>8^O[(d^b[a])&255];for(e=f>>3;e--;a+=8)d=d>>>8^O[(d^b[a])&255],d=d>>>8^O[(d^b[a+1])&255],d=d>>>8^O[(d^b[a+2])&255],d=d>>>8^O[(d^b[a+3])&255],d=d>>>8^O[(d^b[a+4])&255],d=d>>>8^O[(d^b[a+5])&255],d=d>>>8^O[(d^b[a+6])&255],d=d>>>8^O[(d^b[a+7])&255];return(d^4294967295)>>>0}
+var ka=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,
+2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,
+2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,
+2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,
+3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,
+936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],O=B?new Uint32Array(ka):ka;function P(){}P.prototype.getName=function(){return this.name};P.prototype.getData=function(){return this.data};P.prototype.Y=function(){return this.Z};A("Zlib.GunzipMember",P);A("Zlib.GunzipMember.prototype.getName",P.prototype.getName);A("Zlib.GunzipMember.prototype.getData",P.prototype.getData);A("Zlib.GunzipMember.prototype.getMtime",P.prototype.Y);function la(b){this.buffer=new (B?Uint16Array:Array)(2*b);this.length=0}la.prototype.getParent=function(b){return 2*((b-2)/4|0)};la.prototype.push=function(b,a){var c,d,e=this.buffer,f;c=this.length;e[this.length++]=a;for(e[this.length++]=b;0<c;)if(d=this.getParent(c),e[c]>e[d])f=e[c],e[c]=e[d],e[d]=f,f=e[c+1],e[c+1]=e[d+1],e[d+1]=f,c=d;else break;return this.length};
+la.prototype.pop=function(){var b,a,c=this.buffer,d,e,f;a=c[0];b=c[1];this.length-=2;c[0]=c[this.length];c[1]=c[this.length+1];for(f=0;;){e=2*f+2;if(e>=this.length)break;e+2<this.length&&c[e+2]>c[e]&&(e+=2);if(c[e]>c[f])d=c[f],c[f]=c[e],c[e]=d,d=c[f+1],c[f+1]=c[e+1],c[e+1]=d;else break;f=e}return{index:b,value:a,length:this.length}};function ma(b){var a=b.length,c=0,d=Number.POSITIVE_INFINITY,e,f,g,k,h,l,s,p,m,n;for(p=0;p<a;++p)b[p]>c&&(c=b[p]),b[p]<d&&(d=b[p]);e=1<<c;f=new (B?Uint32Array:Array)(e);g=1;k=0;for(h=2;g<=c;){for(p=0;p<a;++p)if(b[p]===g){l=0;s=k;for(m=0;m<g;++m)l=l<<1|s&1,s>>=1;n=g<<16|p;for(m=l;m<e;m+=h)f[m]=n;++k}++g;k<<=1;h<<=1}return[f,c,d]};function na(b,a){this.k=qa;this.I=0;this.input=B&&b instanceof Array?new Uint8Array(b):b;this.b=0;a&&(a.lazy&&(this.I=a.lazy),"number"===typeof a.compressionType&&(this.k=a.compressionType),a.outputBuffer&&(this.a=B&&a.outputBuffer instanceof Array?new Uint8Array(a.outputBuffer):a.outputBuffer),"number"===typeof a.outputIndex&&(this.b=a.outputIndex));this.a||(this.a=new (B?Uint8Array:Array)(32768))}var qa=2,ra={NONE:0,v:1,o:qa,ba:3},sa=[],S;
+for(S=0;288>S;S++)switch(u){case 143>=S:sa.push([S+48,8]);break;case 255>=S:sa.push([S-144+400,9]);break;case 279>=S:sa.push([S-256+0,7]);break;case 287>=S:sa.push([S-280+192,8]);break;default:q("invalid literal: "+S)}
+na.prototype.g=function(){var b,a,c,d,e=this.input;switch(this.k){case 0:c=0;for(d=e.length;c<d;){a=B?e.subarray(c,c+65535):e.slice(c,c+65535);c+=a.length;var f=a,g=c===d,k=t,h=t,l=t,s=t,p=t,m=this.a,n=this.b;if(B){for(m=new Uint8Array(this.a.buffer);m.length<=n+f.length+5;)m=new Uint8Array(m.length<<1);m.set(this.a)}k=g?1:0;m[n++]=k|0;h=f.length;l=~h+65536&65535;m[n++]=h&255;m[n++]=h>>>8&255;m[n++]=l&255;m[n++]=l>>>8&255;if(B)m.set(f,n),n+=f.length,m=m.subarray(0,n);else{s=0;for(p=f.length;s<p;++s)m[n++]=
+f[s];m.length=n}this.b=n;this.a=m}break;case 1:var r=new F(B?new Uint8Array(this.a.buffer):this.a,this.b);r.d(1,1,u);r.d(1,2,u);var v=ta(this,e),x,Q,y;x=0;for(Q=v.length;x<Q;x++)if(y=v[x],F.prototype.d.apply(r,sa[y]),256<y)r.d(v[++x],v[++x],u),r.d(v[++x],5),r.d(v[++x],v[++x],u);else if(256===y)break;this.a=r.finish();this.b=this.a.length;break;case qa:var E=new F(B?new Uint8Array(this.a.buffer):this.a,this.b),Ka,R,X,Y,Z,pb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],fa,La,ga,Ma,oa,wa=Array(19),
+Na,$,pa,C,Oa;Ka=qa;E.d(1,1,u);E.d(Ka,2,u);R=ta(this,e);fa=ua(this.W,15);La=va(fa);ga=ua(this.V,7);Ma=va(ga);for(X=286;257<X&&0===fa[X-1];X--);for(Y=30;1<Y&&0===ga[Y-1];Y--);var Pa=X,Qa=Y,J=new (B?Uint32Array:Array)(Pa+Qa),w,L,z,ha,I=new (B?Uint32Array:Array)(316),G,D,M=new (B?Uint8Array:Array)(19);for(w=L=0;w<Pa;w++)J[L++]=fa[w];for(w=0;w<Qa;w++)J[L++]=ga[w];if(!B){w=0;for(ha=M.length;w<ha;++w)M[w]=0}w=G=0;for(ha=J.length;w<ha;w+=L){for(L=1;w+L<ha&&J[w+L]===J[w];++L);z=L;if(0===J[w])if(3>z)for(;0<
+z--;)I[G++]=0,M[0]++;else for(;0<z;)D=138>z?z:138,D>z-3&&D<z&&(D=z-3),10>=D?(I[G++]=17,I[G++]=D-3,M[17]++):(I[G++]=18,I[G++]=D-11,M[18]++),z-=D;else if(I[G++]=J[w],M[J[w]]++,z--,3>z)for(;0<z--;)I[G++]=J[w],M[J[w]]++;else for(;0<z;)D=6>z?z:6,D>z-3&&D<z&&(D=z-3),I[G++]=16,I[G++]=D-3,M[16]++,z-=D}b=B?I.subarray(0,G):I.slice(0,G);oa=ua(M,7);for(C=0;19>C;C++)wa[C]=oa[pb[C]];for(Z=19;4<Z&&0===wa[Z-1];Z--);Na=va(oa);E.d(X-257,5,u);E.d(Y-1,5,u);E.d(Z-4,4,u);for(C=0;C<Z;C++)E.d(wa[C],3,u);C=0;for(Oa=b.length;C<
+Oa;C++)if($=b[C],E.d(Na[$],oa[$],u),16<=$){C++;switch($){case 16:pa=2;break;case 17:pa=3;break;case 18:pa=7;break;default:q("invalid code: "+$)}E.d(b[C],pa,u)}var Ra=[La,fa],Sa=[Ma,ga],N,Ta,ia,za,Ua,Va,Wa,Xa;Ua=Ra[0];Va=Ra[1];Wa=Sa[0];Xa=Sa[1];N=0;for(Ta=R.length;N<Ta;++N)if(ia=R[N],E.d(Ua[ia],Va[ia],u),256<ia)E.d(R[++N],R[++N],u),za=R[++N],E.d(Wa[za],Xa[za],u),E.d(R[++N],R[++N],u);else if(256===ia)break;this.a=E.finish();this.b=this.a.length;break;default:q("invalid compression type")}return this.a};
+function xa(b,a){this.length=b;this.Q=a}
+var ya=function(){function b(a){switch(u){case 3===a:return[257,a-3,0];case 4===a:return[258,a-4,0];case 5===a:return[259,a-5,0];case 6===a:return[260,a-6,0];case 7===a:return[261,a-7,0];case 8===a:return[262,a-8,0];case 9===a:return[263,a-9,0];case 10===a:return[264,a-10,0];case 12>=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,
+a-31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:q("invalid length: "+a)}}var a=[],c,d;for(c=3;258>=c;c++)d=b(c),a[c]=d[2]<<24|d[1]<<
+16|d[0];return a}(),Aa=B?new Uint32Array(ya):ya;
+function ta(b,a){function c(a,c){var b=a.Q,d=[],e=0,f;f=Aa[a.length];d[e++]=f&65535;d[e++]=f>>16&255;d[e++]=f>>24;var g;switch(u){case 1===b:g=[0,b-1,0];break;case 2===b:g=[1,b-2,0];break;case 3===b:g=[2,b-3,0];break;case 4===b:g=[3,b-4,0];break;case 6>=b:g=[4,b-5,1];break;case 8>=b:g=[5,b-7,1];break;case 12>=b:g=[6,b-9,2];break;case 16>=b:g=[7,b-13,2];break;case 24>=b:g=[8,b-17,3];break;case 32>=b:g=[9,b-25,3];break;case 48>=b:g=[10,b-33,4];break;case 64>=b:g=[11,b-49,4];break;case 96>=b:g=[12,b-
+65,5];break;case 128>=b:g=[13,b-97,5];break;case 192>=b:g=[14,b-129,6];break;case 256>=b:g=[15,b-193,6];break;case 384>=b:g=[16,b-257,7];break;case 512>=b:g=[17,b-385,7];break;case 768>=b:g=[18,b-513,8];break;case 1024>=b:g=[19,b-769,8];break;case 1536>=b:g=[20,b-1025,9];break;case 2048>=b:g=[21,b-1537,9];break;case 3072>=b:g=[22,b-2049,10];break;case 4096>=b:g=[23,b-3073,10];break;case 6144>=b:g=[24,b-4097,11];break;case 8192>=b:g=[25,b-6145,11];break;case 12288>=b:g=[26,b-8193,12];break;case 16384>=
+b:g=[27,b-12289,12];break;case 24576>=b:g=[28,b-16385,13];break;case 32768>=b:g=[29,b-24577,13];break;default:q("invalid distance")}f=g;d[e++]=f[0];d[e++]=f[1];d[e++]=f[2];var h,k;h=0;for(k=d.length;h<k;++h)m[n++]=d[h];v[d[0]]++;x[d[3]]++;r=a.length+c-1;p=null}var d,e,f,g,k,h={},l,s,p,m=B?new Uint16Array(2*a.length):[],n=0,r=0,v=new (B?Uint32Array:Array)(286),x=new (B?Uint32Array:Array)(30),Q=b.I,y;if(!B){for(f=0;285>=f;)v[f++]=0;for(f=0;29>=f;)x[f++]=0}v[256]=1;d=0;for(e=a.length;d<e;++d){f=k=0;
+for(g=3;f<g&&d+f!==e;++f)k=k<<8|a[d+f];h[k]===t&&(h[k]=[]);l=h[k];if(!(0<r--)){for(;0<l.length&&32768<d-l[0];)l.shift();if(d+3>=e){p&&c(p,-1);f=0;for(g=e-d;f<g;++f)y=a[d+f],m[n++]=y,++v[y];break}0<l.length?(s=Ba(a,d,l),p?p.length<s.length?(y=a[d-1],m[n++]=y,++v[y],c(s,0)):c(p,-1):s.length<Q?p=s:c(s,0)):p?c(p,-1):(y=a[d],m[n++]=y,++v[y])}l.push(d)}m[n++]=256;v[256]++;b.W=v;b.V=x;return B?m.subarray(0,n):m}
+function Ba(b,a,c){var d,e,f=0,g,k,h,l,s=b.length;k=0;l=c.length;a:for(;k<l;k++){d=c[l-k-1];g=3;if(3<f){for(h=f;3<h;h--)if(b[d+h-1]!==b[a+h-1])continue a;g=f}for(;258>g&&a+g<s&&b[d+g]===b[a+g];)++g;g>f&&(e=d,f=g);if(258===g)break}return new xa(f,a-e)}
+function ua(b,a){var c=b.length,d=new la(572),e=new (B?Uint8Array:Array)(c),f,g,k,h,l;if(!B)for(h=0;h<c;h++)e[h]=0;for(h=0;h<c;++h)0<b[h]&&d.push(h,b[h]);f=Array(d.length/2);g=new (B?Uint32Array:Array)(d.length/2);if(1===f.length)return e[d.pop().index]=1,e;h=0;for(l=d.length/2;h<l;++h)f[h]=d.pop(),g[h]=f[h].value;k=Ca(g,g.length,a);h=0;for(l=f.length;h<l;++h)e[f[h].index]=k[h];return e}
+function Ca(b,a,c){function d(b){var c=h[b][l[b]];c===a?(d(b+1),d(b+1)):--g[c];++l[b]}var e=new (B?Uint16Array:Array)(c),f=new (B?Uint8Array:Array)(c),g=new (B?Uint8Array:Array)(a),k=Array(c),h=Array(c),l=Array(c),s=(1<<c)-a,p=1<<c-1,m,n,r,v,x;e[c-1]=a;for(n=0;n<c;++n)s<p?f[n]=0:(f[n]=1,s-=p),s<<=1,e[c-2-n]=(e[c-1-n]/2|0)+a;e[0]=f[0];k[0]=Array(e[0]);h[0]=Array(e[0]);for(n=1;n<c;++n)e[n]>2*e[n-1]+f[n]&&(e[n]=2*e[n-1]+f[n]),k[n]=Array(e[n]),h[n]=Array(e[n]);for(m=0;m<a;++m)g[m]=c;for(r=0;r<e[c-1];++r)k[c-
+1][r]=b[r],h[c-1][r]=r;for(m=0;m<c;++m)l[m]=0;1===f[c-1]&&(--g[0],++l[c-1]);for(n=c-2;0<=n;--n){v=m=0;x=l[n+1];for(r=0;r<e[n];r++)v=k[n+1][x]+k[n+1][x+1],v>b[m]?(k[n][r]=v,h[n][r]=a,x+=2):(k[n][r]=b[m],h[n][r]=m,++m);l[n]=0;1===f[n]&&d(n)}return g}
+function va(b){var a=new (B?Uint16Array:Array)(b.length),c=[],d=[],e=0,f,g,k,h;f=0;for(g=b.length;f<g;f++)c[b[f]]=(c[b[f]]|0)+1;f=1;for(g=16;f<=g;f++)d[f]=e,e+=c[f]|0,e<<=1;f=0;for(g=b.length;f<g;f++){e=d[b[f]];d[b[f]]+=1;k=a[f]=0;for(h=b[f];k<h;k++)a[f]=a[f]<<1|e&1,e>>>=1}return a};function Da(b,a){this.input=b;this.b=this.c=0;this.i={};a&&(a.flags&&(this.i=a.flags),"string"===typeof a.filename&&(this.filename=a.filename),"string"===typeof a.comment&&(this.A=a.comment),a.deflateOptions&&(this.l=a.deflateOptions));this.l||(this.l={})}
+Da.prototype.g=function(){var b,a,c,d,e,f,g,k,h=new (B?Uint8Array:Array)(32768),l=0,s=this.input,p=this.c,m=this.filename,n=this.A;h[l++]=31;h[l++]=139;h[l++]=8;b=0;this.i.fname&&(b|=Ea);this.i.fcomment&&(b|=Fa);this.i.fhcrc&&(b|=Ga);h[l++]=b;a=(Date.now?Date.now():+new Date)/1E3|0;h[l++]=a&255;h[l++]=a>>>8&255;h[l++]=a>>>16&255;h[l++]=a>>>24&255;h[l++]=0;h[l++]=Ha;if(this.i.fname!==t){g=0;for(k=m.length;g<k;++g)f=m.charCodeAt(g),255<f&&(h[l++]=f>>>8&255),h[l++]=f&255;h[l++]=0}if(this.i.comment){g=
+0;for(k=n.length;g<k;++g)f=n.charCodeAt(g),255<f&&(h[l++]=f>>>8&255),h[l++]=f&255;h[l++]=0}this.i.fhcrc&&(c=ja(h,0,l)&65535,h[l++]=c&255,h[l++]=c>>>8&255);this.l.outputBuffer=h;this.l.outputIndex=l;e=new na(s,this.l);h=e.g();l=e.b;B&&(l+8>h.buffer.byteLength?(this.a=new Uint8Array(l+8),this.a.set(new Uint8Array(h.buffer)),h=this.a):h=new Uint8Array(h.buffer));d=ja(s,t,t);h[l++]=d&255;h[l++]=d>>>8&255;h[l++]=d>>>16&255;h[l++]=d>>>24&255;k=s.length;h[l++]=k&255;h[l++]=k>>>8&255;h[l++]=k>>>16&255;h[l++]=
+k>>>24&255;this.c=p;B&&l<h.length&&(this.a=h=h.subarray(0,l));return h};var Ha=255,Ga=2,Ea=8,Fa=16;A("Zlib.Gzip",Da);A("Zlib.Gzip.prototype.compress",Da.prototype.g);function T(b,a){this.p=[];this.q=32768;this.e=this.j=this.c=this.u=0;this.input=B?new Uint8Array(b):b;this.w=!1;this.r=Ia;this.M=!1;if(a||!(a={}))a.index&&(this.c=a.index),a.bufferSize&&(this.q=a.bufferSize),a.bufferType&&(this.r=a.bufferType),a.resize&&(this.M=a.resize);switch(this.r){case Ja:this.b=32768;this.a=new (B?Uint8Array:Array)(32768+this.q+258);break;case Ia:this.b=0;this.a=new (B?Uint8Array:Array)(this.q);this.f=this.U;this.B=this.R;this.s=this.T;break;default:q(Error("invalid inflate mode"))}}
+var Ja=0,Ia=1,Ya={O:Ja,N:Ia};
+T.prototype.h=function(){for(;!this.w;){var b=U(this,3);b&1&&(this.w=u);b>>>=1;switch(b){case 0:var a=this.input,c=this.c,d=this.a,e=this.b,f=a.length,g=t,k=t,h=d.length,l=t;this.e=this.j=0;c+1>=f&&q(Error("invalid uncompressed block header: LEN"));g=a[c++]|a[c++]<<8;c+1>=f&&q(Error("invalid uncompressed block header: NLEN"));k=a[c++]|a[c++]<<8;g===~k&&q(Error("invalid uncompressed block header: length verify"));c+g>a.length&&q(Error("input buffer is broken"));switch(this.r){case Ja:for(;e+g>d.length;){l=
+h-e;g-=l;if(B)d.set(a.subarray(c,c+l),e),e+=l,c+=l;else for(;l--;)d[e++]=a[c++];this.b=e;d=this.f();e=this.b}break;case Ia:for(;e+g>d.length;)d=this.f({F:2});break;default:q(Error("invalid inflate mode"))}if(B)d.set(a.subarray(c,c+g),e),e+=g,c+=g;else for(;g--;)d[e++]=a[c++];this.c=c;this.b=e;this.a=d;break;case 1:this.s(Za,$a);break;case 2:ab(this);break;default:q(Error("unknown BTYPE: "+b))}}return this.B()};
+var bb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],cb=B?new Uint16Array(bb):bb,db=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],eb=B?new Uint16Array(db):db,fb=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],gb=B?new Uint8Array(fb):fb,hb=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],ib=B?new Uint16Array(hb):hb,jb=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,
+10,11,11,12,12,13,13],kb=B?new Uint8Array(jb):jb,lb=new (B?Uint8Array:Array)(288),V,mb;V=0;for(mb=lb.length;V<mb;++V)lb[V]=143>=V?8:255>=V?9:279>=V?7:8;var Za=ma(lb),nb=new (B?Uint8Array:Array)(30),ob,qb;ob=0;for(qb=nb.length;ob<qb;++ob)nb[ob]=5;var $a=ma(nb);function U(b,a){for(var c=b.j,d=b.e,e=b.input,f=b.c,g=e.length,k;d<a;)f>=g&&q(Error("input buffer is broken")),c|=e[f++]<<d,d+=8;k=c&(1<<a)-1;b.j=c>>>a;b.e=d-a;b.c=f;return k}
+function rb(b,a){for(var c=b.j,d=b.e,e=b.input,f=b.c,g=e.length,k=a[0],h=a[1],l,s;d<h&&!(f>=g);)c|=e[f++]<<d,d+=8;l=k[c&(1<<h)-1];s=l>>>16;b.j=c>>s;b.e=d-s;b.c=f;return l&65535}
+function ab(b){function a(a,b,c){var d,e=this.J,f,g;for(g=0;g<a;)switch(d=rb(this,b),d){case 16:for(f=3+U(this,2);f--;)c[g++]=e;break;case 17:for(f=3+U(this,3);f--;)c[g++]=0;e=0;break;case 18:for(f=11+U(this,7);f--;)c[g++]=0;e=0;break;default:e=c[g++]=d}this.J=e;return c}var c=U(b,5)+257,d=U(b,5)+1,e=U(b,4)+4,f=new (B?Uint8Array:Array)(cb.length),g,k,h,l;for(l=0;l<e;++l)f[cb[l]]=U(b,3);if(!B){l=e;for(e=f.length;l<e;++l)f[cb[l]]=0}g=ma(f);k=new (B?Uint8Array:Array)(c);h=new (B?Uint8Array:Array)(d);
+b.J=0;b.s(ma(a.call(b,c,g,k)),ma(a.call(b,d,g,h)))}T.prototype.s=function(b,a){var c=this.a,d=this.b;this.C=b;for(var e=c.length-258,f,g,k,h;256!==(f=rb(this,b));)if(256>f)d>=e&&(this.b=d,c=this.f(),d=this.b),c[d++]=f;else{g=f-257;h=eb[g];0<gb[g]&&(h+=U(this,gb[g]));f=rb(this,a);k=ib[f];0<kb[f]&&(k+=U(this,kb[f]));d>=e&&(this.b=d,c=this.f(),d=this.b);for(;h--;)c[d]=c[d++-k]}for(;8<=this.e;)this.e-=8,this.c--;this.b=d};
+T.prototype.T=function(b,a){var c=this.a,d=this.b;this.C=b;for(var e=c.length,f,g,k,h;256!==(f=rb(this,b));)if(256>f)d>=e&&(c=this.f(),e=c.length),c[d++]=f;else{g=f-257;h=eb[g];0<gb[g]&&(h+=U(this,gb[g]));f=rb(this,a);k=ib[f];0<kb[f]&&(k+=U(this,kb[f]));d+h>e&&(c=this.f(),e=c.length);for(;h--;)c[d]=c[d++-k]}for(;8<=this.e;)this.e-=8,this.c--;this.b=d};
+T.prototype.f=function(){var b=new (B?Uint8Array:Array)(this.b-32768),a=this.b-32768,c,d,e=this.a;if(B)b.set(e.subarray(32768,b.length));else{c=0;for(d=b.length;c<d;++c)b[c]=e[c+32768]}this.p.push(b);this.u+=b.length;if(B)e.set(e.subarray(a,a+32768));else for(c=0;32768>c;++c)e[c]=e[a+c];this.b=32768;return e};
+T.prototype.U=function(b){var a,c=this.input.length/this.c+1|0,d,e,f,g=this.input,k=this.a;b&&("number"===typeof b.F&&(c=b.F),"number"===typeof b.P&&(c+=b.P));2>c?(d=(g.length-this.c)/this.C[2],f=258*(d/2)|0,e=f<k.length?k.length+f:k.length<<1):e=k.length*c;B?(a=new Uint8Array(e),a.set(k)):a=k;return this.a=a};
+T.prototype.B=function(){var b=0,a=this.a,c=this.p,d,e=new (B?Uint8Array:Array)(this.u+(this.b-32768)),f,g,k,h;if(0===c.length)return B?this.a.subarray(32768,this.b):this.a.slice(32768,this.b);f=0;for(g=c.length;f<g;++f){d=c[f];k=0;for(h=d.length;k<h;++k)e[b++]=d[k]}f=32768;for(g=this.b;f<g;++f)e[b++]=a[f];this.p=[];return this.buffer=e};
+T.prototype.R=function(){var b,a=this.b;B?this.M?(b=new Uint8Array(a),b.set(this.a.subarray(0,a))):b=this.a.subarray(0,a):(this.a.length>a&&(this.a.length=a),b=this.a);return this.buffer=b};function sb(b){this.input=b;this.c=0;this.t=[];this.D=!1}sb.prototype.X=function(){this.D||this.h();return this.t.slice()};
+sb.prototype.h=function(){for(var b=this.input.length;this.c<b;){var a=new P,c=t,d=t,e=t,f=t,g=t,k=t,h=t,l=t,s=t,p=this.input,m=this.c;a.G=p[m++];a.H=p[m++];(31!==a.G||139!==a.H)&&q(Error("invalid file signature:"+a.G+","+a.H));a.z=p[m++];switch(a.z){case 8:break;default:q(Error("unknown compression method: "+a.z))}a.n=p[m++];l=p[m++]|p[m++]<<8|p[m++]<<16|p[m++]<<24;a.Z=new Date(1E3*l);a.fa=p[m++];a.ea=p[m++];0<(a.n&4)&&(a.aa=p[m++]|p[m++]<<8,m+=a.aa);if(0<(a.n&Ea)){h=[];for(k=0;0<(g=p[m++]);)h[k++]=
+String.fromCharCode(g);a.name=h.join("")}if(0<(a.n&Fa)){h=[];for(k=0;0<(g=p[m++]);)h[k++]=String.fromCharCode(g);a.A=h.join("")}0<(a.n&Ga)&&(a.S=ja(p,0,m)&65535,a.S!==(p[m++]|p[m++]<<8)&&q(Error("invalid header crc16")));c=p[p.length-4]|p[p.length-3]<<8|p[p.length-2]<<16|p[p.length-1]<<24;p.length-m-4-4<512*c&&(f=c);d=new T(p,{index:m,bufferSize:f});a.data=e=d.h();m=d.c;a.ca=s=(p[m++]|p[m++]<<8|p[m++]<<16|p[m++]<<24)>>>0;ja(e,t,t)!==s&&q(Error("invalid CRC-32 checksum: 0x"+ja(e,t,t).toString(16)+
+" / 0x"+s.toString(16)));a.da=c=(p[m++]|p[m++]<<8|p[m++]<<16|p[m++]<<24)>>>0;(e.length&4294967295)!==c&&q(Error("invalid input size: "+(e.length&4294967295)+" / "+c));this.t.push(a);this.c=m}this.D=u;var n=this.t,r,v,x=0,Q=0,y;r=0;for(v=n.length;r<v;++r)Q+=n[r].data.length;if(B){y=new Uint8Array(Q);for(r=0;r<v;++r)y.set(n[r].data,x),x+=n[r].data.length}else{y=[];for(r=0;r<v;++r)y[r]=n[r].data;y=Array.prototype.concat.apply([],y)}return y};A("Zlib.Gunzip",sb);A("Zlib.Gunzip.prototype.decompress",sb.prototype.h);A("Zlib.Gunzip.prototype.getMembers",sb.prototype.X);function tb(b){if("string"===typeof b){var a=b.split(""),c,d;c=0;for(d=a.length;c<d;c++)a[c]=(a[c].charCodeAt(0)&255)>>>0;b=a}for(var e=1,f=0,g=b.length,k,h=0;0<g;){k=1024<g?1024:g;g-=k;do e+=b[h++],f+=e;while(--k);e%=65521;f%=65521}return(f<<16|e)>>>0};function ub(b,a){var c,d;this.input=b;this.c=0;if(a||!(a={}))a.index&&(this.c=a.index),a.verify&&(this.$=a.verify);c=b[this.c++];d=b[this.c++];switch(c&15){case vb:this.method=vb;break;default:q(Error("unsupported compression method"))}0!==((c<<8)+d)%31&&q(Error("invalid fcheck flag:"+((c<<8)+d)%31));d&32&&q(Error("fdict flag is not supported"));this.L=new T(b,{index:this.c,bufferSize:a.bufferSize,bufferType:a.bufferType,resize:a.resize})}
+ub.prototype.h=function(){var b=this.input,a,c;a=this.L.h();this.c=this.L.c;this.$&&(c=(b[this.c++]<<24|b[this.c++]<<16|b[this.c++]<<8|b[this.c++])>>>0,c!==tb(a)&&q(Error("invalid adler-32 checksum")));return a};var vb=8;function wb(b,a){this.input=b;this.a=new (B?Uint8Array:Array)(32768);this.k=W.o;var c={},d;if((a||!(a={}))&&"number"===typeof a.compressionType)this.k=a.compressionType;for(d in a)c[d]=a[d];c.outputBuffer=this.a;this.K=new na(this.input,c)}var W=ra;
+wb.prototype.g=function(){var b,a,c,d,e,f,g,k=0;g=this.a;b=vb;switch(b){case vb:a=Math.LOG2E*Math.log(32768)-8;break;default:q(Error("invalid compression method"))}c=a<<4|b;g[k++]=c;switch(b){case vb:switch(this.k){case W.NONE:e=0;break;case W.v:e=1;break;case W.o:e=2;break;default:q(Error("unsupported compression type"))}break;default:q(Error("invalid compression method"))}d=e<<6|0;g[k++]=d|31-(256*c+d)%31;f=tb(this.input);this.K.b=k;g=this.K.g();k=g.length;B&&(g=new Uint8Array(g.buffer),g.length<=
+k+4&&(this.a=new Uint8Array(g.length+4),this.a.set(g),g=this.a),g=g.subarray(0,k+4));g[k++]=f>>24&255;g[k++]=f>>16&255;g[k++]=f>>8&255;g[k++]=f&255;return g};function xb(b,a){var c,d,e,f;if(Object.keys)c=Object.keys(a);else for(d in c=[],e=0,a)c[e++]=d;e=0;for(f=c.length;e<f;++e)d=c[e],A(b+"."+d,a[d])};A("Zlib.Inflate",ub);A("Zlib.Inflate.prototype.decompress",ub.prototype.h);xb("Zlib.Inflate.BufferType",{ADAPTIVE:Ya.N,BLOCK:Ya.O});A("Zlib.Deflate",wb);A("Zlib.Deflate.compress",function(b,a){return(new wb(b,a)).g()});A("Zlib.Deflate.prototype.compress",wb.prototype.g);xb("Zlib.Deflate.CompressionType",{NONE:W.NONE,FIXED:W.v,DYNAMIC:W.o});}).call(this); //@ sourceMappingURL=zlib_and_gzip.min.js.map

File diff suppressed because it is too large
+ 4 - 0
examples/js/libs/zlib_and_gzip.min.js.map


+ 99 - 6
examples/js/loaders/ColladaLoader2.js

@@ -420,7 +420,87 @@ THREE.ColladaLoader.prototype = {
 						break;
 
 					case 'texture':
-						data[ child.nodeName ] = child.getAttribute( 'texture' );
+						data[ child.nodeName ] = { id: child.getAttribute( 'texture' ), extra: parseEffectParameterTexture( child ) };
+						break;
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function parseEffectParameterTexture( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'extra':
+						data = parseEffectParameterTextureExtra( child );
+						break;
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function parseEffectParameterTextureExtra( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'technique':
+						data[ child.nodeName ] = parseEffectParameterTextureExtraTechnique( child );
+						break;
+
+				}
+
+			}
+
+			return data;
+
+		}
+
+		function parseEffectParameterTextureExtraTechnique( xml ) {
+
+			var data = {};
+
+			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
+
+				var child = xml.childNodes[ i ];
+
+				if ( child.nodeType !== 1 ) continue;
+
+				switch ( child.nodeName ) {
+
+					case 'repeatU':
+					case 'repeatV':
+					case 'offsetU':
+					case 'offsetV':
+						data[ child.nodeName ] = parseFloat( child.textContent );
+						break;
+
+					case 'wrapU':
+					case 'wrapV':
+						data[ child.nodeName ] = parseInt( child.textContent );
 						break;
 
 				}
@@ -497,24 +577,37 @@ THREE.ColladaLoader.prototype = {
 
 			material.name = data.name;
 
-			function getTexture( sid ) {
+			function getTexture( textureObject ) {
 
-				var sampler = effect.profile.samplers[ sid ];
+				var sampler = effect.profile.samplers[ textureObject.id ];
 
 				if ( sampler !== undefined ) {
 
 					var surface = effect.profile.surfaces[ sampler.source ];
 
 					var texture = new THREE.Texture( getImage( surface.init_from ) );
-					texture.wrapS = THREE.RepeatWrapping;
-					texture.wrapT = THREE.RepeatWrapping;
+
+					var extra = textureObject.extra;
+
+					if ( extra !== undefined && extra.technique !== undefined ) {
+
+						var technique = extra.technique;
+
+						texture.wrapS = technique.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
+						texture.wrapT = technique.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
+
+						texture.offset.set( technique.offsetU, technique.offsetV );
+						texture.repeat.set( technique.repeatU, technique.repeatV );
+
+					}
+
 					texture.needsUpdate = true;
 
 					return texture;
 
 				}
 
-				console.error( 'ColladaLoder: Undefined sampler', sid );
+				console.error( 'ColladaLoder: Undefined sampler', textureObject.id );
 
 				return null;
 

+ 83 - 0
examples/js/loaders/HDRCubeTextureLoader.js

@@ -0,0 +1,83 @@
+/**
+* @author Prashant Sharma / spidersharma03
+* @author Ben Houston / http://clara.io / bhouston
+*/
+
+THREE.HDRCubeTextureLoader = function (manager) {
+  this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+  // override in sub classes
+  this.hdrLoader = new THREE.RGBELoader();
+
+  if( THREE.Encodings === undefined ) throw new Error( "HDRCubeMapLoader requires THREE.Encodings" );
+}
+
+THREE.HDRCubeTextureLoader.prototype.load = function(type, urls, onLoad, onProgress, onError) {
+  var texture = new THREE.CubeTexture();
+
+  texture.type = type;
+  texture.encoding = (type === THREE.UnsignedByteType) ? THREE.RGBEEncoding : THREE.LinearEncoding;
+  texture.format = (type === THREE.UnsignedByteType ) ? THREE.RGBAFormat : THREE.RGBFormat;
+  texture.minFilter = (texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
+  texture.magFilter = (texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
+  texture.generateMipmaps = (texture.encoding !== THREE.RGBEEncoding );
+  texture.anisotropy = 0;
+
+  var scope = this.hdrLoader;
+
+  var loaded = 0;
+
+  function loadHDRData(i, onLoad, onProgress, onError) {
+    var loader = new THREE.XHRLoader( this.manager );
+    loader.setResponseType( 'arraybuffer' );
+
+    loader.load( urls[i], function ( buffer ) {
+      loaded++;
+
+      var texData = scope._parser( buffer );
+
+      if ( ! texData ) return;
+
+      if(type === THREE.FloatType) {
+        var numElements = ( texData.data.length / 4 )*3;
+        var floatdata = new Float32Array( numElements );
+        for( var j=0; j<numElements; j++) {
+          THREE.Encodings.RGBEByteToRGBFloat( texData.data, j*4, floatdata, j*3 );
+        }
+        texData.data = floatdata;
+      }
+      else if(type === THREE.HalfFloatType) {
+        var numElements = ( texData.data.length / 4 )*3;
+        var halfdata = new Uint16Array( numElements );
+        for( var j=0; j<numElements; j++) {
+          THREE.Encodings.RGBEByteToRGBHalf( texData.data, j*4, halfdata, j*3 );
+        }
+        texData.data = halfdata;
+      }
+
+      if ( undefined !== texData.image ) {
+        texture[i].images = texData.image;
+      }
+      else if ( undefined !== texData.data ) {
+        var dataTexture = new THREE.DataTexture(texData.data, texData.width, texData.height);
+        dataTexture.format = texture.format;
+        dataTexture.type = texture.type;
+        dataTexture.encoding = texture.encoding;
+        dataTexture.minFilter = texture.minFilter;
+        dataTexture.magFilter = texture.magFilter;
+        dataTexture.generateMipmaps = texture.generateMipmaps;
+
+        texture.images[i] = dataTexture;
+      }
+
+      if(loaded === 6) {
+        texture.needsUpdate = true;
+        if ( onLoad ) onLoad( texture );
+      }
+    }, onProgress, onError );
+  }
+
+  for(var i=0; i<urls.length; i++) {
+    loadHDRData(i, onLoad, onProgress, onError);
+  }
+  return texture;
+};

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

@@ -3634,7 +3634,6 @@ THREE.ShaderLib[ 'mmd' ] = {
 		THREE.UniformsLib[ "normalmap" ],
 		THREE.UniformsLib[ "displacementmap" ],
 		THREE.UniformsLib[ "fog" ],
-		THREE.UniformsLib[ "ambient" ],
 		THREE.UniformsLib[ "lights" ],
 
 		{
@@ -3755,7 +3754,6 @@ THREE.ShaderLib[ 'mmd' ] = {
 		THREE.ShaderChunk[ "envmap_pars_fragment" ],
 		THREE.ShaderChunk[ "fog_pars_fragment" ],
 		THREE.ShaderChunk[ "bsdfs" ],
-		THREE.ShaderChunk[ "ambient_pars" ],
 		THREE.ShaderChunk[ "lights_pars" ],
 		THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 		THREE.ShaderChunk[ "shadowmap_pars_fragment" ],

+ 591 - 0
examples/js/loaders/NRRDLoader.js

@@ -0,0 +1,591 @@
+THREE.NRRDLoader = function( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+
+};
+
+THREE.NRRDLoader.prototype = {
+
+	constructor: THREE.NRRDLoader,
+
+	load: function( url, onLoad, onProgress, onError ) {
+
+		var scope = this;
+
+		var loader = new THREE.XHRLoader( scope.manager );
+		loader.setResponseType( 'arraybuffer' );
+		loader.load( url, function( data ) {
+
+			onLoad( scope.parse( data ) );
+
+		}, onProgress, onError );
+
+	},
+
+	//this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X
+	parse: function( data ) {
+
+
+		var _data = data;
+
+		var _dataPointer = 0;
+
+		var _nativeLittleEndian = new Int8Array( new Int16Array( [ 1 ] ).buffer )[ 0 ] > 0;
+
+		var _littleEndian = true;
+
+		var _lastMin = - Infinity;
+
+		var _lastMax = Infinity;
+
+		var headerObject = {};
+
+		function scan( type, chunks ) {
+
+			if ( chunks === undefined || chunks === null ) {
+
+				chunks = 1;
+
+			}
+
+			var _chunkSize = 1;
+			var _array_type = Uint8Array;
+
+			switch ( type ) {
+
+			// 1 byte data types
+				case 'uchar':
+					break;
+				case 'schar':
+					_array_type = Int8Array;
+					break;
+					// 2 byte data types
+				case 'ushort':
+					_array_type = Uint16Array;
+					_chunkSize = 2;
+					break;
+				case 'sshort':
+					_array_type = Int16Array;
+					_chunkSize = 2;
+					break;
+					// 4 byte data types
+				case 'uint':
+					_array_type = Uint32Array;
+					_chunkSize = 4;
+					break;
+				case 'sint':
+					_array_type = Int32Array;
+					_chunkSize = 4;
+					break;
+				case 'float':
+					_array_type = Float32Array;
+					_chunkSize = 4;
+					break;
+				case 'complex':
+					_array_type = Float64Array;
+					_chunkSize = 8;
+					break;
+				case 'double':
+					_array_type = Float64Array;
+					_chunkSize = 8;
+					break;
+
+			}
+
+			// increase the data pointer in-place
+			var _bytes = new _array_type( _data.slice( _dataPointer,
+			_dataPointer += chunks * _chunkSize ) );
+
+			// if required, flip the endianness of the bytes
+			if ( _nativeLittleEndian != _littleEndian ) {
+
+				// we need to flip here since the format doesn't match the native endianness
+				_bytes = flipEndianness( _bytes, _chunkSize );
+
+			}
+
+			if ( chunks == 1 ) {
+
+				// if only one chunk was requested, just return one value
+				return _bytes[ 0 ];
+
+			}
+
+			// return the byte array
+			return _bytes;
+
+		}
+
+		//Flips typed array endianness in-place. Based on https://github.com/kig/DataStream.js/blob/master/DataStream.js.
+
+		function flipEndianness( array, chunkSize ) {
+
+			var u8 = new Uint8Array( array.buffer, array.byteOffset, array.byteLength );
+			for ( var i = 0; i < array.byteLength; i += chunkSize ) {
+
+				for ( var j = i + chunkSize - 1, k = i; j > k; j --, k ++ ) {
+
+					var tmp = u8[ k ];
+					u8[ k ] = u8[ j ];
+					u8[ j ] = tmp;
+
+				}
+
+			}
+
+			return array;
+
+		}
+
+		//parse the header
+		function parseHeader( header ) {
+
+			var data, field, fn, i, l, lines, m, _i, _len;
+			lines = header.split( /\r?\n/ );
+			for ( _i = 0, _len = lines.length; _i < _len; _i ++ ) {
+
+				l = lines[ _i ];
+				if ( l.match( /NRRD\d+/ ) ) {
+
+					headerObject.isNrrd = true;
+
+				} else if ( l.match( /^#/ ) ) {
+				} else if ( m = l.match( /(.*):(.*)/ ) ) {
+
+					field = m[ 1 ].trim();
+					data = m[ 2 ].trim();
+					fn = THREE.NRRDLoader.prototype.fieldFunctions[ field ];
+					if ( fn ) {
+
+						fn.call( headerObject, data );
+
+					} else {
+
+						headerObject[ field ] = data;
+
+					}
+
+				}
+
+			}
+			if ( ! headerObject.isNrrd ) {
+
+				throw new Error( 'Not an NRRD file' );
+
+			}
+			if ( headerObject.encoding === 'bz2' || headerObject.encoding === 'bzip2' ) {
+
+				throw new Error( 'Bzip is not supported' );
+
+			}
+			if ( ! headerObject.vectors ) {
+
+				//if no space direction is set, let's use the identity
+				headerObject.vectors = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ];
+				//apply spacing if defined
+				if ( headerObject.spacings ) {
+
+					for ( i = 0; i <= 2; i ++ ) {
+
+						if ( ! isNaN( headerObject.spacings[ i ] ) ) {
+
+							headerObject.vectors[ i ].multiplyScalar( headerObject.spacings[ i ] );
+
+						}
+
+					}
+
+				}
+
+			}
+
+		}
+
+		//parse the data when registred as one of this type : 'text', 'ascii', 'txt'
+		function parseDataAsText( data, start, end ) {
+
+			var number = '';
+			start = start || 0;
+			end = end || data.length;
+			var lastSpace = start;
+			var value;
+			//length of the result is the product of the sizes
+			var lengthOfTheResult = headerObject.sizes.reduce( function( previous, current ) {
+
+				return previous * current;
+
+			}, 1 );
+
+			var base = 10;
+			if ( headerObject.encoding === 'hex' ) {
+
+				base = 16;
+
+			}
+
+			var result = new headerObject.__array( lengthOfTheResult );
+			var resultIndex = 0;
+			var parsingFunction = parseInt;
+			if ( headerObject.__array === Float32Array || headerObject.__array === Float64Array ) {
+
+				parsingFunction = parseFloat;
+
+			}
+			for ( var i = start; i < end; i ++ ) {
+
+				value = data[ i ];
+				//if value is not a space
+				if ( ( value < 9 || value > 13 ) && value !== 32 ) {
+
+					number += String.fromCharCode( value );
+
+				}
+				else {
+
+					if ( number !== '' ) {
+
+						result[ resultIndex ] = parsingFunction( number, base );
+						resultIndex ++;
+
+					}
+					number = '';
+
+				}
+
+			}
+			if ( number !== '' ) {
+
+				result[ resultIndex ] = parsingFunction( number, base );
+				resultIndex ++;
+
+			}
+			return result;
+
+		}
+
+		var _bytes = scan( 'uchar', data.byteLength );
+		var _length = _bytes.length;
+		var _header = null;
+		var _data_start = 0;
+		var i;
+		for ( i = 1; i < _length; i ++ ) {
+
+			if ( _bytes[ i - 1 ] == 10 && _bytes[ i ] == 10 ) {
+
+				// we found two line breaks in a row
+				// now we know what the header is
+				_header = this.parseChars( _bytes, 0, i - 2 );
+				// this is were the data starts
+				_data_start = i + 1;
+				break;
+
+			}
+
+		}
+		// parse the header
+		parseHeader( _header );
+
+		var _data = _bytes.subarray( _data_start ); // the data without header
+		if ( headerObject.encoding === 'gzip' || headerObject.encoding === 'gz' ) {
+
+			// we need to decompress the datastream
+			// here we start the unzipping and get a typed Uint8Array back
+			var inflate = new Zlib.Gunzip( new Uint8Array( _data ) );
+			_data = inflate.decompress();
+
+		}
+		else if ( headerObject.encoding === 'ascii' || headerObject.encoding === 'text' || headerObject.encoding === 'txt' || headerObject.encoding === 'hex' ) {
+
+			_data = parseDataAsText( _data );
+
+		}
+		// .. let's use the underlying array buffer
+		_data = _data.buffer;
+
+		var volume = new THREE.Volume();
+		volume.header = headerObject;
+		//
+		// parse the (unzipped) data to a datastream of the correct type
+		//
+		volume.data = new headerObject.__array( _data );
+		// get the min and max intensities
+		var min_max = volume.computeMinMax();
+		var min = min_max[ 0 ];
+		var max = min_max[ 1 ];
+		// attach the scalar range to the volume
+		volume.windowLow = min;
+		volume.windowHigh = max;
+
+		// get the image dimensions
+		volume.dimensions = [ headerObject.sizes[ 0 ], headerObject.sizes[ 1 ], headerObject.sizes[ 2 ] ];
+		volume.xLength = volume.dimensions[ 0 ];
+		volume.yLength = volume.dimensions[ 1 ];
+		volume.zLength = volume.dimensions[ 2 ];
+		// spacing
+		var spacingX = ( new THREE.Vector3( headerObject.vectors[ 0 ][ 0 ], headerObject.vectors[ 0 ][ 1 ],
+		headerObject.vectors[ 0 ][ 2 ] ) ).length();
+		var spacingY = ( new THREE.Vector3( headerObject.vectors[ 1 ][ 0 ], headerObject.vectors[ 1 ][ 1 ],
+		headerObject.vectors[ 1 ][ 2 ] ) ).length();
+		var spacingZ = ( new THREE.Vector3( headerObject.vectors[ 2 ][ 0 ], headerObject.vectors[ 2 ][ 1 ],
+		headerObject.vectors[ 2 ][ 2 ] ) ).length();
+		volume.spacing = [ spacingX, spacingY, spacingZ ];
+
+
+		// Create IJKtoRAS matrix
+		volume.matrix = new THREE.Matrix4();
+
+		var _spaceX = 1;
+		var _spaceY = 1;
+		var _spaceZ = 1;
+
+		if ( headerObject.space == "left-posterior-superior" ) {
+
+			_spaceX = - 1;
+			_spaceY = - 1;
+
+		}
+		else if ( headerObject.space === 'left-anterior-superior' ) {
+
+			_spaceX = - 1
+
+		}
+
+
+		if ( ! headerObject.vectors ) {
+
+			volume.matrix.set( _spaceX, 0, 0, 0,
+			0, _spaceY, 0, 0,
+			0, 0, _spaceZ, 0,
+			0, 0, 0, 1 );
+
+		}
+		else {
+
+			var v = headerObject.vectors;
+			var origin = headerObject.space_origin;
+
+			if ( ! origin ) {
+
+				origin = [ 0, 0, 0 ];
+
+			}
+
+			volume.matrix.set( _spaceX * v[ 0 ][ 0 ], _spaceX * v[ 1 ][ 0 ], _spaceX * v[ 2 ][ 0 ], 0,
+			_spaceY * v[ 0 ][ 1 ], _spaceY * v[ 1 ][ 1 ], _spaceY * v[ 2 ][ 1 ], 0,
+			_spaceZ * v[ 0 ][ 2 ], _spaceZ * v[ 1 ][ 2 ], _spaceZ * v[ 2 ][ 2 ], 0,
+			0, 0, 0, 1 );
+
+		}
+
+		volume.inverseMatrix = new THREE.Matrix4();
+		volume.inverseMatrix.getInverse( volume.matrix );
+		volume.RASDimensions = ( new THREE.Vector3( volume.xLength, volume.yLength, volume.zLength ) ).applyMatrix4( volume.matrix ).round().toArray().map( Math.abs );
+
+		// .. and set the default threshold
+		// only if the threshold was not already set
+		if ( volume.lowerThreshold === - Infinity ) {
+
+			volume.lowerThreshold = min;
+
+		}
+		if ( volume.upperThreshold === Infinity ) {
+
+			volume.upperThreshold = max;
+
+		}
+
+		return volume;
+
+	},
+
+	parseChars: function( array, start, end ) {
+
+		// without borders, use the whole array
+		if ( start === undefined ) {
+
+			start = 0;
+
+		}
+		if ( end === undefined ) {
+
+			end = array.length;
+
+		}
+
+		var output = '';
+		// create and append the chars
+		var i = 0;
+		for ( i = start; i < end; ++ i ) {
+
+			output += String.fromCharCode( array[ i ] );
+
+		}
+
+		return output;
+
+	},
+
+	fieldFunctions: {
+
+		type: function( data ) {
+
+			switch ( data ) {
+				case 'uchar':
+				case 'unsigned char':
+				case 'uint8':
+				case 'uint8_t':
+					this.__array = Uint8Array;
+					break;
+				case 'signed char':
+				case 'int8':
+				case 'int8_t':
+					this.__array = Int8Array;
+					break;
+				case 'short':
+				case 'short int':
+				case 'signed short':
+				case 'signed short int':
+				case 'int16':
+				case 'int16_t':
+					this.__array = Int16Array;
+					break;
+				case 'ushort':
+				case 'unsigned short':
+				case 'unsigned short int':
+				case 'uint16':
+				case 'uint16_t':
+					this.__array = Uint16Array;
+					break;
+				case 'int':
+				case 'signed int':
+				case 'int32':
+				case 'int32_t':
+					this.__array = Int32Array;
+					break;
+				case 'uint':
+				case 'unsigned int':
+				case 'uint32':
+				case 'uint32_t':
+					this.__array = Uint32Array;
+					break;
+				case 'float':
+					this.__array = Float32Array;
+					break;
+				case 'double':
+					this.__array = Float64Array;
+					break;
+				default:
+					throw new Error( 'Unsupported NRRD data type: ' + data );
+			}
+			return this.type = data;
+
+		},
+
+		endian: function( data ) {
+
+			return this.endian = data;
+
+		},
+
+		encoding: function( data ) {
+
+			return this.encoding = data;
+
+		},
+
+		dimension: function( data ) {
+
+			return this.dim = parseInt( data, 10 );
+
+		},
+
+		sizes: function( data ) {
+
+			var i;
+			return this.sizes = ( function() {
+
+				var _i, _len, _ref, _results;
+				_ref = data.split( /\s+/ );
+				_results = [];
+				for ( _i = 0, _len = _ref.length; _i < _len; _i ++ ) {
+
+					i = _ref[ _i ];
+					_results.push( parseInt( i, 10 ) );
+
+				}
+				return _results;
+
+			} )();
+
+		},
+
+		space: function( data ) {
+
+			return this.space = data;
+
+		},
+
+		'space origin' : function( data ) {
+
+			return this.space_origin = data.split( "(" )[ 1 ].split( ")" )[ 0 ].split( "," );
+
+		},
+
+		'space directions' : function( data ) {
+
+			var f, parts, v;
+			parts = data.match( /\(.*?\)/g );
+			return this.vectors = ( function() {
+
+				var _i, _len, _results;
+				_results = [];
+				for ( _i = 0, _len = parts.length; _i < _len; _i ++ ) {
+
+					v = parts[ _i ];
+					_results.push( ( function() {
+
+						var _j, _len2, _ref, _results2;
+						_ref = v.slice( 1, - 1 ).split( /,/ );
+						_results2 = [];
+						for ( _j = 0, _len2 = _ref.length; _j < _len2; _j ++ ) {
+
+							f = _ref[ _j ];
+							_results2.push( parseFloat( f ) );
+
+						}
+						return _results2;
+
+					} )() );
+
+				}
+				return _results;
+
+			} )();
+
+		},
+
+		spacings: function( data ) {
+
+			var f, parts;
+			parts = data.split( /\s+/ );
+			return this.spacings = ( function() {
+
+				var _i, _len, _results;
+				_results = [];
+				for ( _i = 0, _len = parts.length; _i < _len; _i ++ ) {
+
+					f = parts[ _i ];
+					_results.push( parseFloat( f ) );
+
+				}
+				return _results;
+
+			} )();
+
+		}
+	}
+
+};
+
+THREE.EventDispatcher.prototype.apply( THREE.NRRDLoader.prototype );

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

@@ -215,7 +215,7 @@ THREE.OBJLoader.prototype = {
 		// f vertex//normal vertex//normal vertex//normal ...
 		var face_pattern4 = /^f\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))(?:\s+((-?\d+)\/\/(-?\d+)))?/;
 
-		var object_pattern = /^[og]\s+(.+)/;
+		var object_pattern = /^[og]\s*(.+)?/;
 
 		var smoothing_pattern = /^s\s+(\d+|on|off)/;
 
@@ -306,7 +306,7 @@ THREE.OBJLoader.prototype = {
 				// or
 				// g group_name
 
-				var name = result[ 1 ].trim();
+				var name = result[ 0 ].substr( 1 ).trim();
 
 				if ( foundObjects === false ) {
 

+ 2 - 2
examples/js/loaders/PCDLoader.js

@@ -33,7 +33,7 @@ THREE.PCDLoader.prototype = {
 
 	binarryToStr: function( data ) {
 
-		text = "";
+		var text = "";
 		var charArray = new Uint8Array( data );
 		for ( var i = 0; i < data.byteLength; i ++ ) {
 
@@ -125,7 +125,7 @@ THREE.PCDLoader.prototype = {
 
 	parse: function( data, url ) {
 
-		textData = this.binarryToStr( data );
+		var textData = this.binarryToStr( data );
 
 		// Parse the header
 		// Header is always ascii format

+ 7 - 7
examples/js/loaders/VRMLLoader.js

@@ -582,7 +582,7 @@ THREE.VRMLLoader.prototype = {
 
 					if ( /USE/.exec( data ) ) {
 
-						var defineKey = /USE\s+?(\w+)/.exec( data )[ 1 ];
+						var defineKey = /USE\s+?([^\s]+)/.exec( data )[ 1 ];
 
 						if ( undefined == defines[ defineKey ] ) {
 
@@ -629,7 +629,7 @@ THREE.VRMLLoader.prototype = {
 
 					if ( /DEF/.exec( data.string ) ) {
 
-						object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
+						object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
 						defines[ object.name ] = object;
 
 					}
@@ -666,7 +666,7 @@ THREE.VRMLLoader.prototype = {
 
 					if ( /DEF/.exec( data.string ) ) {
 
-						object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
+						object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
 
 						defines[ object.name ] = object;
 
@@ -772,7 +772,7 @@ THREE.VRMLLoader.prototype = {
 
 								if ( child.string.indexOf ( 'DEF' ) > -1 ) {
 
-									var name = /DEF\s+(\w+)/.exec( child.string )[ 1 ];
+									var name = /DEF\s+([^\s]+)/.exec( child.string )[ 1 ];
 
 									defines[ name ] = geometry.vertices;
 
@@ -780,7 +780,7 @@ THREE.VRMLLoader.prototype = {
 
 								if ( child.string.indexOf ( 'USE' ) > -1 ) {
 
-									var defineKey = /USE\s+(\w+)/.exec( child.string )[ 1 ];
+									var defineKey = /USE\s+([^\s]+)/.exec( child.string )[ 1 ];
 
 									geometry.vertices = defines[ defineKey ];
 								}
@@ -862,7 +862,7 @@ THREE.VRMLLoader.prototype = {
 						// see if it's a define
 						if ( /DEF/.exec( data.string ) ) {
 
-							geometry.name = /DEF (\w+)/.exec( data.string )[ 1 ];
+							geometry.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
 							defines[ geometry.name ] = geometry;
 
 						}
@@ -920,7 +920,7 @@ THREE.VRMLLoader.prototype = {
 
 							if ( /DEF/.exec( data.string ) ) {
 
-								material.name = /DEF (\w+)/.exec( data.string )[ 1 ];
+								material.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
 
 								defines[ material.name ] = material;
 

+ 982 - 147
examples/js/loaders/VTKLoader.js

@@ -3,7 +3,7 @@
  * @author Alex Pletzer
  */
 
-THREE.VTKLoader = function ( manager ) {
+THREE.VTKLoader = function( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
@@ -15,261 +15,1096 @@ THREE.VTKLoader.prototype = {
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
-		// Will we bump into trouble reading the whole file into memory?
 		var scope = this;
+
 		var loader = new THREE.XHRLoader( scope.manager );
-		loader.load( url, function ( text ) {
+		loader.setResponseType( 'arraybuffer' );
+		loader.load( url, function( text ) {
 
 			onLoad( scope.parse( text ) );
 
-		},
-
-		onProgress, onError );
+		}, onProgress, onError );
 
 	},
 
 	parse: function ( data ) {
 
-		// connectivity of the triangles
-		var indices = [];
+		function parseASCII( data ) {
 
-		// triangles vertices
-		var positions = [];
+			// connectivity of the triangles
+			var indices = [];
 
-		// red, green, blue colors in the range 0 to 1
-		var colors = [];
+			// triangles vertices
+			var positions = [];
 
-		// normal vector, one per vertex
-		var normals = [];
+			// red, green, blue colors in the range 0 to 1
+			var colors = [];
 
-		var result;
+			// normal vector, one per vertex
+			var normals = [];
 
-		// pattern for reading vertices, 3 floats or integers
-		var pat3Floats = /(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)/g;
+			var result;
 
-		// pattern for connectivity, an integer followed by any number of ints
-		// the first integer is the number of polygon nodes
-		var patConnectivity = /^(\d+)\s+([\s\d]*)/;
+			// pattern for reading vertices, 3 floats or integers
+			var pat3Floats = /(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)/g;
 
-		// indicates start of vertex data section
-		var patPOINTS = /^POINTS /;
+			// pattern for connectivity, an integer followed by any number of ints
+			// the first integer is the number of polygon nodes
+			var patConnectivity = /^(\d+)\s+([\s\d]*)/;
 
-		// indicates start of polygon connectivity section
-		var patPOLYGONS = /^POLYGONS /;
+			// indicates start of vertex data section
+			var patPOINTS = /^POINTS /;
 
-		// POINT_DATA number_of_values
-		var patPOINT_DATA = /^POINT_DATA[ ]+(\d+)/;
+			// indicates start of polygon connectivity section
+			var patPOLYGONS = /^POLYGONS /;
 
-		// CELL_DATA number_of_polys
-		var patCELL_DATA = /^CELL_DATA[ ]+(\d+)/;
+			// indicates start of triangle strips section
+			var patTRIANGLE_STRIPS = /^TRIANGLE_STRIPS /;
 
-		// Start of color section
-		var patCOLOR_SCALARS = /^COLOR_SCALARS[ ]+(\w+)[ ]+3/;
+			// POINT_DATA number_of_values
+			var patPOINT_DATA = /^POINT_DATA[ ]+(\d+)/;
 
-		// NORMALS Normals float
-		var patNORMALS = /^NORMALS[ ]+(\w+)[ ]+(\w+)/;
+			// CELL_DATA number_of_polys
+			var patCELL_DATA = /^CELL_DATA[ ]+(\d+)/;
 
-		var inPointsSection = false;
-		var inPolygonsSection = false;
-		var inPointDataSection = false;
-		var inCellDataSection = false;
-		var inColorSection = false;
-		var inNormalsSection = false;
+			// Start of color section
+			var patCOLOR_SCALARS = /^COLOR_SCALARS[ ]+(\w+)[ ]+3/;
 
-		var lines = data.split( '\n' );
+			// NORMALS Normals float
+			var patNORMALS = /^NORMALS[ ]+(\w+)[ ]+(\w+)/;
 
-		for ( var i in lines ) {
+			var inPointsSection = false;
+			var inPolygonsSection = false;
+			var inTriangleStripSection = false;
+			var inPointDataSection = false;
+			var inCellDataSection = false;
+			var inColorSection = false;
+			var inNormalsSection = false;
 
-			var line = lines[ i ];
+			var lines = data.split( '\n' );
 
-			if ( inPointsSection ) {
+			for ( var i in lines ) {
 
-				// get the vertices
-				while ( ( result = pat3Floats.exec( line ) ) !== null ) {
+				var line = lines[ i ];
 
-					var x = parseFloat( result[ 1 ] );
-					var y = parseFloat( result[ 2 ] );
-					var z = parseFloat( result[ 3 ] );
-					positions.push( x, y, z );
+				if ( inPointsSection ) {
 
-				}
+					// get the vertices
+					while ( ( result = pat3Floats.exec( line ) ) !== null ) {
+
+						var x = parseFloat( result[ 1 ] );
+						var y = parseFloat( result[ 2 ] );
+						var z = parseFloat( result[ 3 ] );
+						positions.push( x, y, z );
+
+					}
 
-			} else if ( inPolygonsSection ) {
+				} else if ( inPolygonsSection ) {
 
-				if ( ( result = patConnectivity.exec( line ) ) !== null ) {
+					if ( ( result = patConnectivity.exec( line ) ) !== null ) {
 
-					// numVertices i0 i1 i2 ...
-					var numVertices = parseInt( result[ 1 ] );
-					var inds = result[ 2 ].split( /\s+/ );
+						// numVertices i0 i1 i2 ...
+						var numVertices = parseInt( result[ 1 ] );
+						var inds = result[ 2 ].split( /\s+/ );
 
-					if ( numVertices >= 3 ) {
+						if ( numVertices >= 3 ) {
 
-						var i0 = parseInt( inds[ 0 ] );
-						var i1, i2;
-						var k = 1;
-						// split the polygon in numVertices - 2 triangles
-						for ( var j = 0; j < numVertices - 2; ++ j ) {
+							var i0 = parseInt( inds[ 0 ] );
+							var i1, i2;
+							var k = 1;
+							// split the polygon in numVertices - 2 triangles
+							for ( var j = 0; j < numVertices - 2; ++ j ) {
 
-							i1 = parseInt( inds[ k ] );
-							i2 = parseInt( inds[ k  + 1 ] );
-							indices.push( i0, i1, i2 );
-							k ++;
+								i1 = parseInt( inds[ k ] );
+								i2 = parseInt( inds[ k + 1 ] );
+								indices.push( i0, i1, i2 );
+								k ++;
+
+							}
 
 						}
 
 					}
 
-				}
+				} else if ( inTriangleStripSection ) {
 
-			} else if ( inPointDataSection || inCellDataSection ) {
+					if ( ( result = patConnectivity.exec( line ) ) !== null ) {
 
-				if ( inColorSection ) {
+						// numVertices i0 i1 i2 ...
+						var numVertices = parseInt( result[ 1 ] );
+						var inds = result[ 2 ].split( /\s+/ );
 
-					// Get the colors
+						if ( numVertices >= 3 ) {
 
-					while ( ( result = pat3Floats.exec( line ) ) !== null ) {
+							var i0, i1, i2;
+							// split the polygon in numVertices - 2 triangles
+							for ( var j = 0; j < numVertices - 2; j ++ ) {
+
+								if ( j % 2 === 1 ) {
+
+									i0 = parseInt( inds[ j ] );
+									i1 = parseInt( inds[ j + 2 ] );
+									i2 = parseInt( inds[ j + 1 ] );
+									indices.push( i0, i1, i2 );
+
+								} else {
 
-						var r = parseFloat( result[ 1 ] );
-						var g = parseFloat( result[ 2 ] );
-						var b = parseFloat( result[ 3 ] );
-						colors.push( r, g, b );
+									i0 = parseInt( inds[ j ] );
+									i1 = parseInt( inds[ j + 1 ] );
+									i2 = parseInt( inds[ j + 2 ] );
+									indices.push( i0, i1, i2 );
+
+								}
+
+							}
+
+						}
 
 					}
 
-				} else if ( inNormalsSection ) {
+				} else if ( inPointDataSection || inCellDataSection ) {
 
-					// Get the normal vectors
+					if ( inColorSection ) {
 
-					while ( ( result = pat3Floats.exec( line ) ) !== null ) {
+						// Get the colors
+
+						while ( ( result = pat3Floats.exec( line ) ) !== null ) {
 
-						var nx = parseFloat( result[ 1 ] );
-						var ny = parseFloat( result[ 2 ] );
-						var nz = parseFloat( result[ 3 ] );
-						normals.push( nx, ny, nz );
+							var r = parseFloat( result[ 1 ] );
+							var g = parseFloat( result[ 2 ] );
+							var b = parseFloat( result[ 3 ] );
+							colors.push( r, g, b );
+
+						}
+
+					} else if ( inNormalsSection ) {
+
+						// Get the normal vectors
+
+						while ( ( result = pat3Floats.exec( line ) ) !== null ) {
+
+							var nx = parseFloat( result[ 1 ] );
+							var ny = parseFloat( result[ 2 ] );
+							var nz = parseFloat( result[ 3 ] );
+							normals.push( nx, ny, nz );
+
+						}
 
 					}
 
 				}
 
+				if ( patPOLYGONS.exec( line ) !== null ) {
+
+					inPolygonsSection = true;
+					inPointsSection = false;
+					inTriangleStripSection = false;
+
+				} else if ( patPOINTS.exec( line ) !== null ) {
+
+					inPolygonsSection = false;
+					inPointsSection = true;
+					inTriangleStripSection = false;
+
+				} else if ( patTRIANGLE_STRIPS.exec( line ) !== null ) {
+
+					inPolygonsSection = false;
+					inPointsSection = false;
+					inTriangleStripSection = true;
+
+				} else if ( patPOINT_DATA.exec( line ) !== null ) {
+
+					inPointDataSection = true;
+					inPointsSection = false;
+					inPolygonsSection = false;
+					inTriangleStripSection = false;
+
+				} else if ( patCELL_DATA.exec( line ) !== null ) {
+
+					inCellDataSection = true;
+					inPointsSection = false;
+					inPolygonsSection = false;
+					inTriangleStripSection = false;
+
+				} else if ( patCOLOR_SCALARS.exec( line ) !== null ) {
+
+					inColorSection = true;
+					inNormalsSection = false;
+					inPointsSection = false;
+					inPolygonsSection = false;
+					inTriangleStripSection = false;
+
+				} else if ( patNORMALS.exec( line ) !== null ) {
+
+					inNormalsSection = true;
+					inColorSection = false;
+					inPointsSection = false;
+					inPolygonsSection = false;
+					inTriangleStripSection = false;
+
+				}
+
+			}
+
+			var geometry;
+			var stagger = 'point';
+
+			if ( colors.length == indices.length ) {
+
+				stagger = 'cell';
+
 			}
 
-			if ( patPOLYGONS.exec( line ) !== null ) {
+			if ( stagger == 'point' ) {
 
-				inPolygonsSection = true;
-				inPointsSection = false;
+				// Nodal. Use BufferGeometry
+				geometry = new THREE.BufferGeometry();
+				geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
 
-			} else if ( patPOINTS.exec( line ) !== null ) {
+				if ( colors.length == positions.length ) {
 
-				inPolygonsSection = false;
-				inPointsSection = true;
+					geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
 
-			} else if ( patPOINT_DATA.exec( line ) !== null ) {
+				}
+
+				if ( normals.length == positions.length ) {
 
-				inPointDataSection = true;
-				inPointsSection = false;
-				inPolygonsSection = false;
+					geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
 
-			} else if ( patCELL_DATA.exec( line ) !== null ) {
+				}
 
-				inCellDataSection = true;
-				inPointsSection = false;
-				inPolygonsSection = false;
+			} else {
 
-			} else if ( patCOLOR_SCALARS.exec( line ) !== null ) {
+				// Cell centered colors. The only way to attach a solid color to each triangle
+				// is to use Geometry, which is less efficient than BufferGeometry
+				geometry = new THREE.Geometry();
 
-				inColorSection = true;
-				inNormalsSection = false;
-				inPointsSection = false;
-				inPolygonsSection = false;
+				var numTriangles = indices.length / 3;
+				var numPoints = positions.length / 3;
+				var va, vb, vc;
+				var face;
+				var ia, ib, ic;
+				var x, y, z;
+				var r, g, b;
 
-			} else if ( patNORMALS.exec( line ) !== null ) {
+				for ( var j = 0; j < numPoints; ++ j ) {
 
-				inNormalsSection = true;
-				inColorSection = false;
-				inPointsSection = false;
-				inPolygonsSection = false;
+					x = positions[ 3 * j + 0 ];
+					y = positions[ 3 * j + 1 ];
+					z = positions[ 3 * j + 2 ];
+					geometry.vertices.push( new THREE.Vector3( x, y, z ) );
+
+				}
+
+				for ( var i = 0; i < numTriangles; ++ i ) {
+
+					ia = indices[ 3 * i + 0 ];
+					ib = indices[ 3 * i + 1 ];
+					ic = indices[ 3 * i + 2 ];
+					geometry.faces.push( new THREE.Face3( ia, ib, ic ) );
+
+				}
+
+				if ( colors.length == numTriangles * 3 ) {
+
+					for ( var i = 0; i < numTriangles; ++ i ) {
+
+						face = geometry.faces[ i ];
+						r = colors[ 3 * i + 0 ];
+						g = colors[ 3 * i + 1 ];
+						b = colors[ 3 * i + 2 ];
+						face.color = new THREE.Color().setRGB( r, g, b );
+
+					}
+
+				}
 
 			}
 
+			return geometry;
+
 		}
 
-		var geometry;
-		var stagger = 'point';
+		function parseBinary( data ) {
+
+			var count, pointIndex, i, numberOfPoints, pt, s;
+			var buffer = new Uint8Array ( data );
+			var dataView = new DataView ( data );
+
+			// Points and normals, by default, are empty
+			var points = [];
+			var normals = [];
+			var indices = [];
+
+			// Going to make a big array of strings
+			var vtk = [];
+			var index = 0;
+
+			function findString( buffer, start ) {
+
+				var index = start;
+				var c = buffer[ index ];
+				var s = [];
+				while ( c != 10 ) {
+
+					s.push ( String.fromCharCode ( c ) );
+					index ++;
+					c = buffer[ index ];
+
+				}
+
+				return { start: start,
+						end: index,
+						next: index + 1,
+						parsedString: s.join( '' ) };
+
+			}
+
+			var state, line;
+
+			while ( true ) {
+
+				// Get a string
+				state = findString ( buffer, index );
+				line = state.parsedString;
+
+				if ( line.indexOf ( 'POINTS' ) === 0 ) {
+
+					vtk.push ( line );
+					// Add the points
+					numberOfPoints = parseInt ( line.split( ' ' )[ 1 ], 10 );
+
+					// Each point is 3 4-byte floats
+					count = numberOfPoints * 4 * 3;
+
+					points = new Float32Array( numberOfPoints * 3 );
+
+					pointIndex = state.next;
+					for ( i = 0; i < numberOfPoints; i ++ ) {
+
+						points[ 3 * i ] = dataView.getFloat32( pointIndex, false );
+						points[ 3 * i + 1 ] = dataView.getFloat32( pointIndex + 4, false );
+						points[ 3 * i + 2 ] = dataView.getFloat32( pointIndex + 8, false );
+						pointIndex = pointIndex + 12;
+
+					}
+					// increment our next pointer
+					state.next = state.next + count + 1;
+
+				} else if ( line.indexOf ( 'TRIANGLE_STRIPS' ) === 0 ) {
+
+					var numberOfStrips = parseInt ( line.split( ' ' )[ 1 ], 10 );
+					var size = parseInt ( line.split ( ' ' )[ 2 ], 10 );
+					// 4 byte integers
+					count = size * 4;
+
+					indices = new Uint32Array( 3 * size - 9 * numberOfStrips );
+					var indicesIndex = 0;
+
+					pointIndex = state.next;
+					for ( i = 0; i < numberOfStrips; i ++ ) {
+
+						// For each strip, read the first value, then record that many more points
+						var indexCount = dataView.getInt32( pointIndex, false );
+						var strip = [];
+						pointIndex += 4;
+						for ( s = 0; s < indexCount; s ++ ) {
+
+							strip.push ( dataView.getInt32( pointIndex, false ) );
+							pointIndex += 4;
+
+						}
+
+						// retrieves the n-2 triangles from the triangle strip
+						for ( var j = 0; j < indexCount - 2; j ++ ) {
+
+							if ( j % 2 ) {
+
+								indices[ indicesIndex ++ ] = strip[ j ];
+								indices[ indicesIndex ++ ] = strip[ j + 2 ];
+								indices[ indicesIndex ++ ] = strip[ j + 1 ];
+
+							} else {
+
 
-		if ( colors.length == indices.length ) {
+								indices[ indicesIndex ++ ] = strip[ j ];
+								indices[ indicesIndex ++ ] = strip[ j + 1 ];
+								indices[ indicesIndex ++ ] = strip[ j + 2 ];
 
-			stagger = 'cell';
+							}
+
+						}
+
+					}
+					// increment our next pointer
+					state.next = state.next + count + 1;
+
+				} else if ( line.indexOf ( 'POLYGONS' ) === 0 ) {
+
+					var numberOfStrips = parseInt ( line.split( ' ' )[ 1 ], 10 );
+					var size = parseInt ( line.split ( ' ' )[ 2 ], 10 );
+					// 4 byte integers
+					count = size * 4;
+
+					indices = new Uint32Array( 3 * size - 9 * numberOfStrips );
+					var indicesIndex = 0;
+
+					pointIndex = state.next;
+					for ( i = 0; i < numberOfStrips; i ++ ) {
+
+						// For each strip, read the first value, then record that many more points
+						var indexCount = dataView.getInt32( pointIndex, false );
+						var strip = [];
+						pointIndex += 4;
+						for ( s = 0; s < indexCount; s ++ ) {
+
+							strip.push ( dataView.getInt32( pointIndex, false ) );
+							pointIndex += 4;
+
+						}
+						var i0 = strip[ 0 ];
+						// divide the polygon in n-2 triangle
+						for ( var j = 1; j < indexCount - 1; j ++ ) {
+
+							indices[ indicesIndex ++ ] = strip[ 0 ];
+							indices[ indicesIndex ++ ] = strip[ j ];
+							indices[ indicesIndex ++ ] = strip[ j + 1 ];
+
+						}
+
+					}
+					// increment our next pointer
+					state.next = state.next + count + 1;
+
+				} else if ( line.indexOf ( 'POINT_DATA' ) === 0 ) {
+
+					numberOfPoints = parseInt ( line.split( ' ' )[ 1 ], 10 );
+
+					// Grab the next line
+					state = findString ( buffer, state.next );
+
+					// Now grab the binary data
+					count = numberOfPoints * 4 * 3;
+
+					normals = new Float32Array( numberOfPoints * 3 );
+					pointIndex = state.next;
+					for ( i = 0; i < numberOfPoints; i ++ ) {
+
+						normals[ 3 * i ] = dataView.getFloat32( pointIndex, false );
+						normals[ 3 * i + 1 ] = dataView.getFloat32( pointIndex + 4, false );
+						normals[ 3 * i + 2 ] = dataView.getFloat32( pointIndex + 8, false );
+						pointIndex += 12;
+
+					}
+
+					// Increment past our data
+					state.next = state.next + count;
+
+				}
+
+				// Increment index
+				index = state.next;
+
+				if ( index >= buffer.byteLength ) {
+
+					break;
+
+				}
+
+			}
+
+			var geometry = new THREE.BufferGeometry();
+			geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
+			geometry.addAttribute( 'position', new THREE.BufferAttribute( points, 3 ) );
+
+			if ( normals.length == points.length ) {
+
+				geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+
+			}
+
+			return geometry;
 
 		}
 
-		if ( stagger == 'point' ) {
+		function parseXML( stringFile ) {
+
+			// Changes XML to JSON, based on https://davidwalsh.name/convert-xml-json
+
+			function xmlToJson( xml ) {
+
+				// Create the return object
+				var obj = {};
+
+				if ( xml.nodeType == 1 ) { // element
+
+					// do attributes
+
+					if ( xml.attributes ) {
+
+						if ( xml.attributes.length > 0 ) {
+
+							obj[ 'attributes' ] = {};
+
+							for ( var j = 0; j < xml.attributes.length; j ++ ) {
 
-			// Nodal. Use BufferGeometry
-			geometry = new THREE.BufferGeometry();
-			geometry.setIndex( new THREE.BufferAttribute( new ( indices.length > 65535 ? Uint32Array : Uint16Array )( indices ), 1 ) );
-			geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
+								var attribute = xml.attributes.item( j );
+								obj[ 'attributes' ][ attribute.nodeName ] = attribute.nodeValue.trim();
 
-			if ( colors.length == positions.length ) {
+							}
 
-				geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
+						}
+
+					}
+
+				} else if ( xml.nodeType == 3 ) { // text
+
+					obj = xml.nodeValue.trim();
+
+				}
+
+				// do children
+				if ( xml.hasChildNodes() ) {
+
+					for ( var i = 0; i < xml.childNodes.length; i ++ ) {
+
+						var item = xml.childNodes.item( i );
+						var nodeName = item.nodeName;
+
+						if ( typeof( obj[ nodeName ] ) === 'undefined' ) {
+
+							var tmp = xmlToJson( item );
+
+							if ( tmp !== '' ) obj[ nodeName ] = tmp;
+
+						} else {
+
+							if ( typeof( obj[ nodeName ].push ) === 'undefined' ) {
+
+								var old = obj[ nodeName ];
+								obj[ nodeName ] = [ old ];
+
+							}
+
+							var tmp = xmlToJson( item );
+
+							if ( tmp !== '' ) obj[ nodeName ].push( tmp );
+
+						}
+
+					}
+
+				}
+
+				return obj;
 
 			}
 
-			if ( normals.length == positions.length ) {
+			// Taken from Base64-js
+			function Base64toByteArray( b64 ) {
+
+				var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
+				var i;
+				var lookup = [];
+				var revLookup = [];
+				var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+				var len = code.length;
+
+				for ( i = 0; i < len; i ++ ) {
+
+					lookup[ i ] = code[ i ];
+
+				}
+
+				for ( i = 0; i < len; ++ i ) {
+
+					revLookup[ code.charCodeAt( i ) ] = i;
+
+				}
+
+				revLookup[ '-'.charCodeAt( 0 ) ] = 62;
+				revLookup[ '_'.charCodeAt( 0 ) ] = 63;
+
+				var j, l, tmp, placeHolders, arr;
+				var len = b64.length;
+
+				if ( len % 4 > 0 ) {
+
+					throw new Error( 'Invalid string. Length must be a multiple of 4' );
+
+				}
+
+				placeHolders = b64[ len - 2 ] === '=' ? 2 : b64[ len - 1 ] === '=' ? 1 : 0;
+				arr = new Arr( len * 3 / 4 - placeHolders );
+				l = placeHolders > 0 ? len - 4 : len;
+
+				var L = 0;
+
+				for ( i = 0, j = 0; i < l; i += 4, j += 3 ) {
+
+					tmp = ( revLookup[ b64.charCodeAt( i ) ] << 18 ) | ( revLookup[ b64.charCodeAt( i + 1 ) ] << 12 ) | ( revLookup[ b64.charCodeAt( i + 2 ) ] << 6 ) | revLookup[ b64.charCodeAt( i + 3 ) ];
+					arr[ L ++ ] = ( tmp & 0xFF0000 ) >> 16;
+					arr[ L ++ ] = ( tmp & 0xFF00 ) >> 8;
+					arr[ L ++ ] = tmp & 0xFF;
+
+				}
+
+				if ( placeHolders === 2 ) {
+
+					tmp = ( revLookup[ b64.charCodeAt( i ) ] << 2 ) | ( revLookup[ b64.charCodeAt( i + 1 ) ] >> 4 );
+					arr[ L ++ ] = tmp & 0xFF;
+
+				} else if ( placeHolders === 1 ) {
 
-				geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+					tmp = ( revLookup[ b64.charCodeAt( i ) ] << 10 ) | ( revLookup[ b64.charCodeAt( i + 1 ) ] << 4 ) | ( revLookup[ b64.charCodeAt( i + 2 ) ] >> 2 );
+					arr[ L ++ ] = ( tmp >> 8 ) & 0xFF;
+					arr[ L ++ ] = tmp & 0xFF;
+
+				}
+
+				return arr;
 
 			}
 
-		} else {
+			function parseDataArray( ele, compressed ) {
+
+				// Check the format
+
+				if ( ele.attributes.format == 'binary' ) {
+
+					if ( compressed ) {
+
+						// Split the blob_header and compressed Data
+						if ( ele[ '#text' ].indexOf( '==' ) != - 1 ) {
+
+							var data = ele[ '#text' ].split( '==' );
+
+							// console.log( data );
+
+							if ( data.length == 2 ) {
+
+								var blob = data.shift();
+								var content = data.shift();
+
+								if ( content === '' ) {
+
+									content = blob + '==';
+
+								}
+
+							} else if ( data.length > 2 ) {
+
+								var blob = data.shift();
+								var content = data.shift();
+								content = content + '==';
+
+							} else if ( data.length < 2 ) {
+
+								var content = data.shift();
+								content = content + '==';
+
+							}
+
+							// Convert to bytearray
+							var arr = Base64toByteArray( content );
+
+							// decompress
+							var inflate = new Zlib.Inflate( arr, { resize: true, verify: true } );
+							var content = inflate.decompress();
+
+						} else {
+
+							var content = Base64toByteArray( ele[ '#text' ] );
+
+						}
+
+					} else {
+
+						var content = Base64toByteArray( ele[ '#text' ] );
+
+					}
+
+					var content = content.buffer;
+
+				} else {
+
+					if ( ele[ '#text' ] ) {
+
+						var content = ele[ '#text' ].replace( /\n/g, ' ' ).split( ' ' ).filter( function ( el, idx, arr ) {
+
+							if ( el !== '' ) return el;
+
+						} );
+
+					} else {
+
+						var content = new Int32Array( 0 ).buffer;
+
+					}
+
+				}
+
+				delete ele[ '#text' ];
+
+				// Get the content and optimize it
+
+				if ( ele.attributes.type == 'Float32' ) {
+
+					var txt = new Float32Array( content );
+
+					if ( ele.attributes.format == 'binary' ) {
+
+						if ( ! compressed ) {
+
+							txt = txt.filter( function( el, idx, arr ) {
+
+								if ( idx !== 0 ) return true;
 
-			// Cell centered colors. The only way to attach a solid color to each triangle
-			// is to use Geometry, which is less efficient than BufferGeometry
-			geometry = new THREE.Geometry();
+							} );
 
-			var numTriangles = indices.length / 3;
-			var numPoints = positions.length / 3;
-			var va, vb, vc;
-			var face;
-			var ia, ib, ic;
-			var x, y, z;
-			var r, g, b;
+						}
+
+					}
+
+				} else if ( ele.attributes.type === 'Int64' ) {
+
+					var txt = new Int32Array( content );
+
+					if ( ele.attributes.format == 'binary' ) {
+
+						if ( ! compressed ) {
+
+							txt = txt.filter( function ( el, idx, arr ) {
+
+								if ( idx !== 0 ) return true;
+
+							} );
+
+						}
+
+						txt = txt.filter( function ( el, idx, arr ) {
 
-			for ( var j = 0; j < numPoints; ++ j ) {
+							if ( idx % 2 !== 1 ) return true;
 
-				x = positions[ 3 * j + 0 ];
-				y = positions[ 3 * j + 1 ];
-				z = positions[ 3 * j + 2 ];
-				geometry.vertices.push( new THREE.Vector3( x, y, z ) );
+						} );
+
+					}
+
+				}
+
+				// console.log( txt );
+
+				return txt;
 
 			}
 
-			for ( var i = 0; i < numTriangles; ++ i ) {
+			// Main part
+			// Get Dom
+			var dom = null;
+
+			if ( window.DOMParser ) {
+
+				try {
+
+					dom = ( new DOMParser() ).parseFromString( stringFile, 'text/xml' );
+
+				} catch ( e ) {
+
+					dom = null;
+
+				}
+
+			} else if ( window.ActiveXObject ) {
+
+				try {
+
+					dom = new ActiveXObject( 'Microsoft.XMLDOM' );
+					dom.async = false;
+
+					if ( ! dom.loadXML( xml ) ) {
+
+						throw new Error( dom.parseError.reason + dom.parseError.srcText );
+
+					}
+
+				} catch ( e ) {
+
+					dom = null;
+
+				}
+
+			} else {
 
-				ia = indices[ 3 * i + 0 ];
-				ib = indices[ 3 * i + 1 ];
-				ic = indices[ 3 * i + 2 ];
-				geometry.faces.push( new THREE.Face3( ia, ib, ic ) );
+				throw new Error( 'Cannot parse xml string!' );
 
 			}
 
-			if ( colors.length == numTriangles * 3 ) {
+			// Get the doc
+			var doc = dom.documentElement;
+			// Convert to json
+			var json = xmlToJson( doc );
+			var points = [];
+			var normals = [];
+			var indices = [];
 
-				for ( var i = 0; i < numTriangles; ++ i ) {
+			if ( json.PolyData ) {
+
+				var piece = json.PolyData.Piece;
+				var compressed = json.attributes.hasOwnProperty( 'compressor' );
+
+				// Can be optimized
+				// Loop through the sections
+				var sections = [ 'PointData', 'Points', 'Strips', 'Polys' ];// +['CellData', 'Verts', 'Lines'];
+				var sectionIndex = 0, numberOfSections = sections.length;
+
+				while ( sectionIndex < numberOfSections ) {
+
+					var section = piece[ sections[ sectionIndex ] ];
+
+					// If it has a DataArray in it
+
+					if ( section.DataArray ) {
+
+						// Depending on the number of DataArrays
+
+						if ( Object.prototype.toString.call( section.DataArray ) === '[object Array]' ) {
+
+							var arr = section.DataArray;
+
+						} else {
+
+							var arr = [ section.DataArray ];
 
-					face = geometry.faces[ i ];
-					r = colors[ 3 * i + 0 ];
-					g = colors[ 3 * i + 1 ];
-					b = colors[ 3 * i + 2 ];
-					face.color = new THREE.Color().setRGB( r, g, b );
+						}
+
+						var dataArrayIndex = 0, numberOfDataArrays = arr.length;
+
+						while ( dataArrayIndex < numberOfDataArrays ) {
+
+							// Parse the DataArray
+							arr[ dataArrayIndex ].text = parseDataArray( arr[ dataArrayIndex ], compressed );
+							dataArrayIndex ++;
+
+						}
+
+						switch ( sections[ sectionIndex ] ) {
+
+							// if iti is point data
+							case 'PointData':
+
+								var numberOfPoints = parseInt( piece.attributes.NumberOfPoints );
+								var normalsName = section.attributes.Normals;
+
+								if ( numberOfPoints > 0 ) {
+
+									for ( var i = 0, len = arr.length; i < len; i ++ ) {
+
+										if ( normalsName == arr[ i ].attributes.Name ) {
+
+											var components = arr[ i ].attributes.NumberOfComponents;
+											normals = new Float32Array( numberOfPoints * components );
+											normals.set( arr[ i ].text, 0 );
+
+										}
+
+									}
+
+								}
+
+								// console.log('Normals', normals);
+
+								break;
+
+							// if it is points
+							case 'Points':
+
+								var numberOfPoints = parseInt( piece.attributes.NumberOfPoints );
+
+								if ( numberOfPoints > 0 ) {
+
+									var components = section.DataArray.attributes.NumberOfComponents;
+									points = new Float32Array( numberOfPoints * components );
+									points.set( section.DataArray.text, 0 );
+
+								}
+
+								// console.log('Points', points);
+
+								break;
+
+							// if it is strips
+							case 'Strips':
+
+								var numberOfStrips = parseInt( piece.attributes.NumberOfStrips );
+
+								if ( numberOfStrips > 0 ) {
+
+									var connectivity = new Int32Array( section.DataArray[ 0 ].text.length );
+									var offset = new Int32Array( section.DataArray[ 1 ].text.length );
+									connectivity.set( section.DataArray[ 0 ].text, 0 );
+									offset.set( section.DataArray[ 1 ].text, 0 );
+
+									var size = numberOfStrips + connectivity.length;
+									indices = new Uint32Array( 3 * size - 9 * numberOfStrips );
+
+									var indicesIndex = 0;
+
+									for ( var i = 0,len = numberOfStrips; i < len; i ++ ) {
+
+										var strip = [];
+
+										for ( var s = 0, len1 = offset[ i ], len0 = 0; s < len1 - len0; s ++ ) {
+
+											strip.push ( connectivity[ s ] );
+
+											if ( i > 0 ) len0 = offset[ i - 1 ];
+
+										}
+
+										for ( var j = 0, len1 = offset[ i ], len0 = 0; j < len1 - len0 - 2; j ++ ) {
+
+											if ( j % 2 ) {
+
+												indices[ indicesIndex ++ ] = strip[ j ];
+												indices[ indicesIndex ++ ] = strip[ j + 2 ];
+												indices[ indicesIndex ++ ] = strip[ j + 1 ];
+
+											} else {
+
+												indices[ indicesIndex ++ ] = strip[ j ];
+												indices[ indicesIndex ++ ] = strip[ j + 1 ];
+												indices[ indicesIndex ++ ] = strip[ j + 2 ];
+
+											}
+
+											if ( i > 0 ) len0 = offset[ i - 1 ];
+
+										}
+
+									}
+
+								}
+
+								//console.log('Strips', indices);
+
+								break;
+
+							// if it is polys
+							case 'Polys':
+
+								var numberOfPolys = parseInt( piece.attributes.NumberOfPolys );
+
+								if ( numberOfPolys > 0 ) {
+
+									var connectivity = new Int32Array( section.DataArray[ 0 ].text.length );
+									var offset = new Int32Array( section.DataArray[ 1 ].text.length );
+									connectivity.set( section.DataArray[ 0 ].text, 0 );
+									offset.set( section.DataArray[ 1 ].text, 0 );
+
+									var size = numberOfPolys + connectivity.length;
+									indices = new Uint32Array( 3 * size - 9 * numberOfPolys );
+									var indicesIndex = 0, connectivityIndex = 0;
+									var i = 0,len = numberOfPolys, len0 = 0;
+
+									while ( i < len ) {
+
+										var poly = [];
+										var s = 0, len1 = offset[ i ];
+
+										while ( s < len1 - len0 ) {
+
+											poly.push( connectivity[ connectivityIndex ++ ] );
+											s ++;
+
+										}
+
+										var j = 1;
+
+										while ( j < len1 - len0 - 1 ) {
+
+											indices[ indicesIndex ++ ] = poly[ 0 ];
+											indices[ indicesIndex ++ ] = poly[ j ];
+											indices[ indicesIndex ++ ] = poly[ j + 1 ];
+											j ++;
+
+										}
+
+										i ++;
+										len0 = offset[ i - 1 ];
+
+									}
+
+								}
+								//console.log('Polys', indices);
+								break;
+
+							default:
+								break;
+
+						}
+
+					}
+
+					sectionIndex ++;
+
+				}
+
+				var geometry = new THREE.BufferGeometry();
+				geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
+				geometry.addAttribute( 'position', new THREE.BufferAttribute( points, 3 ) );
+
+				if ( normals.length == points.length ) {
+
+					geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
 
 				}
 
-			 }
+				// console.log( json );
+
+				return geometry;
+
+			} else {
+
+				// TODO for vtu,vti,and other xml formats
+
+			}
 
 		}
 
-		return geometry;
+		function getStringFile( data ) {
+
+			var stringFile = '';
+			var charArray = new Uint8Array( data );
+			var i = 0;
+			var len = charArray.length;
+
+			while ( len -- ) {
+
+				stringFile += String.fromCharCode( charArray[ i ++ ] );
+
+			}
+
+			return stringFile;
+
+		}
+
+		// get the 5 first lines of the files to check if there is the key word binary
+		var meta = String.fromCharCode.apply( null, new Uint8Array( data, 0, 250 ) ).split( '\n' );
+
+		if ( meta[ 0 ].indexOf( 'xml' ) !== - 1 ) {
+
+			return parseXML( getStringFile( data ) );
+
+		} else if ( meta[ 2 ].includes( 'ASCII' ) ) {
+
+			return parseASCII( getStringFile( data ) );
+
+		} else {
+
+			return parseBinary( data );
+
+		}
 
 	}
 

+ 317 - 307
examples/js/loaders/gltf/glTF-parser.js

@@ -22,364 +22,374 @@
 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /*
-    The Abstract Loader has two modes:
-        #1: [static] load all the JSON at once [as of now]
-        #2: [stream] stream and parse JSON progressively [not yet supported]
+	The Abstract Loader has two modes:
+		#1: [static] load all the JSON at once [as of now]
+		#2: [stream] stream and parse JSON progressively [not yet supported]
 
-    Whatever is the mechanism used to parse the JSON (#1 or #2),
-    The loader starts by resolving the paths to binaries and referenced json files (by replace the value of the path property with an absolute path if it was relative).
+	Whatever is the mechanism used to parse the JSON (#1 or #2),
+	The loader starts by resolving the paths to binaries and referenced json files (by replace the value of the path property with an absolute path if it was relative).
 
-    In case #1: it is guaranteed to call the concrete loader implementation methods in a order that solves the dependencies between the entries.
-    only the nodes requires an extra pass to set up the hirerarchy.
-    In case #2: the concrete implementation will have to solve the dependencies. no order is guaranteed.
+	In case #1: it is guaranteed to call the concrete loader implementation methods in a order that solves the dependencies between the entries.
+	only the nodes requires an extra pass to set up the hirerarchy.
+	In case #2: the concrete implementation will have to solve the dependencies. no order is guaranteed.
 
-    When case #1 is used the followed dependency order is:
+	When case #1 is used the followed dependency order is:
 
-    scenes -> nodes -> meshes -> materials -> techniques -> shaders
-                    -> buffers
-                    -> cameras
-                    -> lights
+	scenes -> nodes -> meshes -> materials -> techniques -> shaders
+					-> buffers
+					-> cameras
+					-> lights
 
-    The readers starts with the leafs, i.e:
-        shaders, techniques, materials, meshes, buffers, cameras, lights, nodes, scenes
+	The readers starts with the leafs, i.e:
+		shaders, techniques, materials, meshes, buffers, cameras, lights, nodes, scenes
 
-    For each called handle method called the client should return true if the next handle can be call right after returning,
-    or false if a callback on client side will notify the loader that the next handle method can be called.
+	For each called handle method called the client should return true if the next handle can be call right after returning,
+	or false if a callback on client side will notify the loader that the next handle method can be called.
 
 */
 var global = window;
 (function (root, factory) {
 	if (typeof exports === 'object') {
-        // Node. Does not work with strict CommonJS, but
-        // only CommonJS-like enviroments that support module.exports,
-        // like Node.
+		// Node. Does not work with strict CommonJS, but
+		// only CommonJS-like enviroments that support module.exports,
+		// like Node.
 		factory(module.exports);
 	} else if (typeof define === 'function' && define.amd) {
-        // AMD. Register as an anonymous module.
+		// AMD. Register as an anonymous module.
 		define([], function () {
 			return factory(root);
 		});
 	} else {
-        // Browser globals
+		// Browser globals
 		factory(root);
 	}
 }(this, function (root) {
 	"use strict";
 
-	var categoriesDepsOrder = [ "buffers", "bufferViews", "images",  "videos", "samplers", "textures", "shaders", "programs", "techniques", "materials", "accessors", "meshes", "cameras", "lights", "skins", "nodes", "scenes", "animations" ];
+	var categoriesDepsOrder = ["extensions", "buffers", "bufferViews", "images",  "videos", "samplers", "textures", "shaders", "programs", "techniques", "materials", "accessors", "meshes", "cameras", "lights", "skins", "nodes", "animations", "scenes"];
 
 	var glTFParser = Object.create(Object.prototype, {
 
-        _rootDescription: { value: null, writable: true },
+		_rootDescription: { value: null, writable: true },
 
-        rootDescription: {
-            set: function(value) {
-	this._rootDescription = value;
-            },
-            get: function() {
-	return this._rootDescription;
-            }
-        },
-
-        baseURL: { value: null, writable: true },
+		rootDescription: {
+			set: function(value) {
+				this._rootDescription = value;
+			},
+			get: function() {
+				return this._rootDescription;
+			}
+		},
 
-        //detect absolute path following the same protocol than window.location
-        _isAbsolutePath: {
-            value: function(path) {
-	var isAbsolutePathRegExp = new RegExp("^" + window.location.protocol, "i");
+		baseURL: { value: null, writable: true },
 
-	return path.match(isAbsolutePathRegExp) ? true : false;
-            }
-        },
+		//detect absolute path following the same protocol than window.location
+		_isAbsolutePath: {
+			value: function(path) {
+				var isAbsolutePathRegExp = new RegExp("^"+window.location.protocol, "i");
 
-        resolvePathIfNeeded: {
-            value: function(path) {
-	if (this._isAbsolutePath(path)) {
-		return path;
-	}
+				return path.match(isAbsolutePathRegExp) ? true : false;
+			}
+		},
 
-	return this.baseURL + path;
-            }
-        },
-
-        _resolvePathsForCategories: {
-            value: function(categories) {
-	categories.forEach( function(category) {
-		var descriptions = this.json[category];
-		if (descriptions) {
-			var descriptionKeys = Object.keys(descriptions);
-			descriptionKeys.forEach( function(descriptionKey) {
-				var description = descriptions[descriptionKey];
-				description.path = this.resolvePathIfNeeded(description.path);
-			}, this);
-		}
-	}, this);
-            }
-        },
-
-        _json: {
-            value: null,
-            writable: true
-        },
-
-        json: {
-            enumerable: true,
-            get: function() {
-	return this._json;
-            },
-            set: function(value) {
-	if (this._json !== value) {
-		this._json = value;
-		this._resolvePathsForCategories([ "buffers", "shaders", "images", "videos" ]);
-	}
-            }
-        },
-
-        _path: {
-            value: null,
-            writable: true
-        },
-
-        getEntryDescription: {
-            value: function (entryID, entryType) {
-	var entries = null;
-
-	var category = entryType;
-	entries = this.rootDescription[category];
-	if (!entries) {
-		console.log("ERROR:CANNOT find expected category named:" + category);
-		return null;
-	}
+		resolvePathIfNeeded: {
+			value: function(path) {
+				if (this._isAbsolutePath(path)) {
+					return path;
+				}
 
-	return entries ? entries[entryID] : null;
-            }
-        },
+				var isDataUriRegex = /^data:/;
+				if (isDataUriRegex.test(path)) {
+					return path;
+				}
+				
+				return this.baseURL + path;
+			}
+		},
+
+		_resolvePathsForCategories: {
+			value: function(categories) {
+				categories.forEach( function(category) {
+					var descriptions = this.json[category];
+					if (descriptions) {
+						var descriptionKeys = Object.keys(descriptions);
+						descriptionKeys.forEach( function(descriptionKey) {
+							var description = descriptions[descriptionKey];
+							description.uri = this.resolvePathIfNeeded(description.uri);
+						}, this);
+					}
+				}, this);
+			}
+		},
+
+		_json: {
+			value: null,
+			writable: true
+		},
+
+		json: {
+			enumerable: true,
+			get: function() {
+				return this._json;
+			},
+			set: function(value) {
+				if (this._json !== value) {
+					this._json = value;
+					this._resolvePathsForCategories(["buffers", "shaders", "images", "videos"]);
+				}
+			}
+		},
+
+		_path: {
+			value: null,
+			writable: true
+		},
+
+		getEntryDescription: {
+			value: function (entryID, entryType) {
+				var entries = null;
+
+				var category = entryType;
+				entries = this.rootDescription[category];
+				if (!entries) {
+					console.log("ERROR:CANNOT find expected category named:"+category);
+					return null;
+				}
 
-        _stepToNextCategory: {
-            value: function() {
-	this._state.categoryIndex = this.getNextCategoryIndex(this._state.categoryIndex + 1);
-	if (this._state.categoryIndex !== -1) {
-		this._state.categoryState.index = 0;
-		return true;
-	}
+				return entries ? entries[entryID] : null;
+			}
+		},
+
+		_stepToNextCategory: {
+			value: function() {
+				this._state.categoryIndex = this.getNextCategoryIndex(this._state.categoryIndex + 1);
+				if (this._state.categoryIndex !== -1) {
+					this._state.categoryState.index = 0;
+					return true;
+				}
 
-	return false;
-            }
-        },
-
-        _stepToNextDescription: {
-            enumerable: false,
-            value: function() {
-	var categoryState = this._state.categoryState;
-	var keys = categoryState.keys;
-	if (!keys) {
-		console.log("INCONSISTENCY ERROR");
-		return false;
-	}
+				return false;
+			}
+		},
+
+		_stepToNextDescription: {
+			enumerable: false,
+			value: function() {
+				var categoryState = this._state.categoryState;
+				var keys = categoryState.keys;
+				if (!keys) {
+					console.log("INCONSISTENCY ERROR");
+					return false;
+				}
 
-	categoryState.index ++;
-	categoryState.keys = null;
-	if (categoryState.index >= keys.length) {
-		return this._stepToNextCategory();
-	}
-	return false;
-            }
-        },
-
-        hasCategory: {
-            value: function(category) {
-	return this.rootDescription[category] ? true : false;
-            }
-        },
-
-        _handleState: {
-            value: function() {
-
-	var methodForType = {
-                    "buffers" : this.handleBuffer,
-                    "bufferViews" : this.handleBufferView,
-                    "shaders" : this.handleShader,
-                    "programs" : this.handleProgram,
-                    "techniques" : this.handleTechnique,
-                    "materials" : this.handleMaterial,
-                    "meshes" : this.handleMesh,
-                    "cameras" : this.handleCamera,
-                    "lights" : this.handleLight,
-                    "nodes" : this.handleNode,
-                    "scenes" : this.handleScene,
-                    "images" : this.handleImage,
-                    "animations" : this.handleAnimation,
-                    "accessors" : this.handleAccessor,
-                    "skins" : this.handleSkin,
-                    "samplers" : this.handleSampler,
-                    "textures" : this.handleTexture,
-                    "videos" : this.handleVideo
-
-                };
-
-	var success = true;
-	while (this._state.categoryIndex !== -1) {
-		var category = categoriesDepsOrder[this._state.categoryIndex];
-		var categoryState = this._state.categoryState;
-		var keys = categoryState.keys;
-		if (!keys) {
-			categoryState.keys = keys = Object.keys(this.rootDescription[category]);
-			if (keys) {
-				if (keys.length == 0) {
-					this._stepToNextDescription();
-					continue;
+				categoryState.index++;
+				categoryState.keys = null;
+				if (categoryState.index >= keys.length) {
+					return this._stepToNextCategory();
 				}
+				return false;
 			}
-		}
+		},
 
-		var type = category;
-		var entryID = keys[categoryState.index];
-		var description = this.getEntryDescription(entryID, type);
-		if (!description) {
-			if (this.handleError) {
-				this.handleError("INCONSISTENCY ERROR: no description found for entry " + entryID);
-				success = false;
-				break;
+		hasCategory: {
+			value: function(category) {
+				return this.rootDescription[category] ? true : false;
 			}
-		} else {
+		},
+
+		_handleState: {
+			value: function() {
+
+				var methodForType = {
+					"buffers" : this.handleBuffer,
+					"bufferViews" : this.handleBufferView,
+					"shaders" : this.handleShader,
+					"programs" : this.handleProgram,
+					"techniques" : this.handleTechnique,
+					"materials" : this.handleMaterial,
+					"meshes" : this.handleMesh,
+					"cameras" : this.handleCamera,
+					"lights" : this.handleLight,
+					"nodes" : this.handleNode,
+					"scenes" : this.handleScene,
+					"images" : this.handleImage,
+					"animations" : this.handleAnimation,
+					"accessors" : this.handleAccessor,
+					"skins" : this.handleSkin,
+					"samplers" : this.handleSampler,
+					"textures" : this.handleTexture,
+					"videos" : this.handleVideo,
+					"extensions" : this.handleExtension,
+
+				};
+
+				var success = true;
+				while (this._state.categoryIndex !== -1) {
+					var category = categoriesDepsOrder[this._state.categoryIndex];
+					var categoryState = this._state.categoryState;
+					var keys = categoryState.keys;
+					if (!keys) {
+						categoryState.keys = keys = Object.keys(this.rootDescription[category]);
+						if (keys) {
+							if (keys.length == 0) {
+								this._stepToNextDescription();
+								continue;
+							}
+						}
+					}
+
+					var type = category;
+					var entryID = keys[categoryState.index];
+					var description = this.getEntryDescription(entryID, type);
+					if (!description) {
+						if (this.handleError) {
+							this.handleError("INCONSISTENCY ERROR: no description found for entry "+entryID);
+							success = false;
+							break;
+						}
+					} else {
+
+						if (methodForType[type]) {
+							if (methodForType[type].call(this, entryID, description, this._state.userInfo) === false) {
+								success = false;
+								break;
+							}
+						}
+
+						this._stepToNextDescription();
+					}
+				}
 
-			if (methodForType[type]) {
-				if (methodForType[type].call(this, entryID, description, this._state.userInfo) === false) {
-					success = false;
-					break;
+				if (this.handleLoadCompleted) {
+					this.handleLoadCompleted(success);
 				}
-			}
 
-			this._stepToNextDescription();
-		}
-	}
+			}
+		},
+
+		_loadJSONIfNeeded: {
+			enumerable: true,
+			value: function(callback) {
+				var self = this;
+				//FIXME: handle error
+				if (!this._json)  {
+					var jsonPath = this._path;
+					var i = jsonPath.lastIndexOf("/");
+					this.baseURL = (i !== 0) ? jsonPath.substring(0, i + 1) : '';
+					var jsonfile = new XMLHttpRequest();
+					jsonfile.open("GET", jsonPath, true);
+					jsonfile.onreadystatechange = function() {
+						if (jsonfile.readyState == 4) {
+							if (jsonfile.status == 200) {
+								self.json = JSON.parse(jsonfile.responseText);
+								if (callback) {
+									callback(self.json);
+								}
+							}
+						}
+					};
+					jsonfile.send(null);
+			   } else {
+					if (callback) {
+						callback(this.json);
+					}
+				}
+			}
+		},
+
+		/* load JSON and assign it as description to the reader */
+		_buildLoader: {
+			value: function(callback) {
+				var self = this;
+				function JSONReady(json) {
+					self.rootDescription = json;
+					if (callback)
+						callback(this);
+				}
 
-	if (this.handleLoadCompleted) {
-		this.handleLoadCompleted(success);
-	}
+				this._loadJSONIfNeeded(JSONReady);
+			}
+		},
+
+		_state: { value: null, writable: true },
+
+		_getEntryType: {
+			value: function(entryID) {
+				var rootKeys = categoriesDepsOrder;
+				for (var i = 0 ;  i < rootKeys.length ; i++) {
+					var rootValues = this.rootDescription[rootKeys[i]];
+					if (rootValues) {
+						return rootKeys[i];
+					}
+				}
+				return null;
+			}
+		},
+
+		getNextCategoryIndex: {
+			value: function(currentIndex) {
+				for (var i = currentIndex ; i < categoriesDepsOrder.length ; i++) {
+					if (this.hasCategory(categoriesDepsOrder[i])) {
+						return i;
+					}
+				}
 
-            }
-        },
-
-        _loadJSONIfNeeded: {
-            enumerable: true,
-            value: function(callback) {
-	var self = this;
-                //FIXME: handle error
-	if (!this._json) {
-		var jsonPath = this._path;
-		var i = jsonPath.lastIndexOf("/");
-		this.baseURL = (i !== 0) ? jsonPath.substring(0, i + 1) : '';
-		var jsonfile = new XMLHttpRequest();
-		jsonfile.open("GET", jsonPath, true);
-		jsonfile.addEventListener( 'load', function ( event ) {
-			self.json = JSON.parse(jsonfile.responseText);
-			if (callback) {
-				callback(self.json);
+				return -1;
 			}
-		}, false );
-		jsonfile.send(null);
-	} else {
-		if (callback) {
-			callback(this.json);
-		}
-	}
-            }
-        },
-
-        /* load JSON and assign it as description to the reader */
-        _buildLoader: {
-            value: function(callback) {
-	var self = this;
-	function JSONReady(json) {
-		self.rootDescription = json;
-		if (callback)
-                        callback(this);
-	}
+		},
+
+		load: {
+			enumerable: true,
+			value: function(userInfo, options) {
+				var self = this;
+				this._buildLoader(function loaderReady(reader) {
+					var startCategory = self.getNextCategoryIndex.call(self,0);
+					if (startCategory !== -1) {
+						self._state = { "userInfo" : userInfo,
+										"options" : options,
+										"categoryIndex" : startCategory,
+										"categoryState" : { "index" : "0" } };
+						self._handleState();
+					}
+				});
+			}
+		},
 
-	this._loadJSONIfNeeded(JSONReady);
-            }
-        },
+		initWithPath: {
+			value: function(path) {
+				this._path = path;
+				this._json = null;
+				return this;
+			}
+		},
 
-        _state: { value: null, writable: true },
+		//this is meant to be global and common for all instances
+		_knownURLs: { writable: true, value: {} },
 
-        _getEntryType: {
-            value: function(entryID) {
-	var rootKeys = categoriesDepsOrder;
-	for (var i = 0 ; i < rootKeys.length ; i ++) {
-		var rootValues = this.rootDescription[rootKeys[i]];
-		if (rootValues) {
-			return rootKeys[i];
-		}
-	}
-	return null;
-            }
-        },
-
-        getNextCategoryIndex: {
-            value: function(currentIndex) {
-	for (var i = currentIndex ; i < categoriesDepsOrder.length ; i ++) {
-		if (this.hasCategory(categoriesDepsOrder[i])) {
-			return i;
+		//to be invoked by subclass, so that ids can be ensured to not overlap
+		loaderContext: {
+			value: function() {
+				if (typeof this._knownURLs[this._path] === "undefined") {
+					this._knownURLs[this._path] = Object.keys(this._knownURLs).length;
+				}
+				return "__" + this._knownURLs[this._path];
+			}
+		},
+
+		initWithJSON: {
+			value: function(json, baseURL) {
+				this.json = json;
+				this.baseURL = baseURL;
+				if (!baseURL) {
+					console.log("WARNING: no base URL passed to Reader:initWithJSON");
+				}
+				return this;
+			}
 		}
-	}
 
-	return -1;
-            }
-        },
-
-        load: {
-            enumerable: true,
-            value: function(userInfo, options) {
-	var self = this;
-	this._buildLoader(function loaderReady(reader) {
-		var startCategory = self.getNextCategoryIndex.call(self, 0);
-		if (startCategory !== -1) {
-			self._state = { "userInfo" : userInfo,
-                                        "options" : options,
-                                        "categoryIndex" : startCategory,
-                                        "categoryState" : { "index" : "0" } };
-			self._handleState();
-		}
 	});
-            }
-        },
-
-        initWithPath: {
-            value: function(path) {
-	this._path = path;
-	this._json = null;
-	return this;
-            }
-        },
-
-        //this is meant to be global and common for all instances
-        _knownURLs: { writable: true, value: {} },
-
-        //to be invoked by subclass, so that ids can be ensured to not overlap
-        loaderContext: {
-            value: function() {
-	if (typeof this._knownURLs[this._path] === "undefined") {
-		this._knownURLs[this._path] = Object.keys(this._knownURLs).length;
-	}
-	return "__" + this._knownURLs[this._path];
-            }
-        },
-
-        initWithJSON: {
-            value: function(json, baseURL) {
-	this.json = json;
-	this.baseURL = baseURL;
-	if (!baseURL) {
-		console.log("WARNING: no base URL passed to Reader:initWithJSON");
-	}
-	return this;
-            }
-        }
-
-    });
 
-	if (root) {
+	if(root) {
 		root.glTFParser = glTFParser;
 	}
 

+ 13 - 13
examples/js/loaders/gltf/glTFAnimation.js

@@ -24,7 +24,7 @@ THREE.glTFAnimator = ( function () {
 
 		update : function()
 		{
-			for (i = 0; i < animators.length; i ++)
+			for (i = 0; i < animators.length; i++)
 			{
 				animators[i].update();
 			}
@@ -45,18 +45,18 @@ THREE.glTFAnimation = function(interps)
 	{
 		this.createInterpolators(interps);
 	}
-};
+}
 
 THREE.glTFAnimation.prototype.createInterpolators = function(interps)
 {
 	var i, len = interps.length;
-	for (i = 0; i < len; i ++)
+	for (i = 0; i < len; i++)
 	{
 		var interp = new THREE.glTFInterpolator(interps[i]);
 		this.interps.push(interp);
 		this.duration = Math.max(this.duration, interp.duration);
 	}
-};
+}
 
 // Start/stop
 THREE.glTFAnimation.prototype.play = function()
@@ -67,13 +67,13 @@ THREE.glTFAnimation.prototype.play = function()
 	this.startTime = Date.now();
 	this.running = true;
 	THREE.glTFAnimator.add(this);
-};
+}
 
 THREE.glTFAnimation.prototype.stop = function()
 {
 	this.running = false;
 	THREE.glTFAnimator.remove(this);
-};
+}
 
 // Update - drive key frame evaluation
 THREE.glTFAnimation.prototype.update = function()
@@ -90,7 +90,7 @@ THREE.glTFAnimation.prototype.update = function()
 	{
 		this.running = false;
 		var i, len = this.interps.length;
-		for (i = 0; i < len; i ++)
+		for (i = 0; i < len; i++)
 		{
 			this.interps[i].interp(this.duration);
 		}
@@ -100,12 +100,12 @@ THREE.glTFAnimation.prototype.update = function()
 	else
 	{
 		var i, len = this.interps.length;
-		for (i = 0; i < len; i ++)
+		for (i = 0; i < len; i++)
 		{
 			this.interps[i].interp(t);
 		}
 	}
-};
+}
 
 //Interpolator class
 //Construction/initialization
@@ -147,7 +147,7 @@ THREE.glTFInterpolator = function(param)
 	this.quat1 = new THREE.Quaternion;
 	this.quat2 = new THREE.Quaternion;
 	this.quat3 = new THREE.Quaternion;
-};
+}
 
 //Interpolation and tweening methods
 THREE.glTFInterpolator.prototype.interp = function(t)
@@ -202,7 +202,7 @@ THREE.glTFInterpolator.prototype.interp = function(t)
 	}
 	else
 	{
-		for (i = 0; i < this.count - 1; i ++)
+		for (i = 0; i < this.count - 1; i++)
 		{
 			var key1 = this.keys[i];
 			var key2 = this.keys[i + 1];
@@ -238,7 +238,7 @@ THREE.glTFInterpolator.prototype.interp = function(t)
 	{
 		this.copyValue(this.target);
 	}
-};
+}
 
 THREE.glTFInterpolator.prototype.copyValue = function(target) {
 	
@@ -248,4 +248,4 @@ THREE.glTFInterpolator.prototype.copyValue = function(target) {
 	else {
 		target.copy(this.vec3);
 	}		
-};
+}

File diff suppressed because it is too large
+ 1466 - 1103
examples/js/loaders/gltf/glTFLoader.js


+ 185 - 106
examples/js/loaders/gltf/glTFLoaderUtils.js

@@ -26,8 +26,8 @@ THREE.GLTFLoaderUtils = Object.create(Object, {
         value: function() {
 	        this._streams = {};
 	        this._streamsStatus = {};
-	this._resources = {};
-	this._resourcesStatus = {};
+            this._resources = {};
+            this._resourcesStatus = {};
         }
     },
 
@@ -35,60 +35,119 @@ THREE.GLTFLoaderUtils = Object.create(Object, {
     _containsResource: {
         enumerable: false,
         value: function(resourceID) {
-	return this._resources[resourceID] ? true : false;
+            return this._resources[resourceID] ? true : false;
         }
     },
 
     _storeResource: {
         enumerable: false,
         value: function(resourceID, resource) {
-	if (!resourceID) {
-		console.log("ERROR: entry does not contain id, cannot store");
-		return;
-	}
+            if (!resourceID) {
+                console.log("ERROR: entry does not contain id, cannot store");
+                return;
+            }
 
-	if (this._containsResource[resourceID]) {
-		console.log("WARNING: resource:" + resourceID + " is already stored, overriding");
-	}
+            if (this._containsResource[resourceID]) {
+                console.log("WARNING: resource:"+resourceID+" is already stored, overriding");
+            }
 
-	this._resources[resourceID] = resource;
+           this._resources[resourceID] = resource;
         }
     },
 
     _getResource: {
         enumerable: false,
         value: function(resourceID) {
-	return this._resources[resourceID];
+            return this._resources[resourceID];
         }
     },
 
     _loadStream: {
         value: function(path, type, delegate) {
-	var self = this;
 
-	if (!type) {
-		delegate.handleError(THREE.GLTFLoaderUtils.INVALID_TYPE, null);
-		return;
-	}
 
-	if (!path) {
-		delegate.handleError(THREE.GLTFLoaderUtils.INVALID_PATH);
-		return;
-	}
 
-	var xhr = new XMLHttpRequest();
-	xhr.open('GET', path, true);
-	xhr.responseType = (type === this.ARRAY_BUFFER) ? "arraybuffer" : "text";
+            var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
+
+            function decodeDataUriText(isBase64, data) {
+                var result = decodeURIComponent(data);
+                if (isBase64) {
+                    return atob(result);
+                }
+                return result;
+            }
+
+            function decodeDataUriArrayBuffer(isBase64, data) {
+                var byteString = decodeDataUriText(isBase64, data);
+                var buffer = new ArrayBuffer(byteString.length);
+                var view = new Uint8Array(buffer);
+                for (var i = 0; i < byteString.length; i++) {
+                    view[i] = byteString.charCodeAt(i);
+                }
+                return buffer;
+            }
+
+            function decodeDataUri(dataUriRegexResult, responseType) {
+                responseType = typeof responseType !== 'undefined' ? responseType : '';
+                var mimeType = dataUriRegexResult[1];
+                var isBase64 = !!dataUriRegexResult[2];
+                var data = dataUriRegexResult[3];
+
+                switch (responseType) {
+                case '':
+                case 'text':
+                    return decodeDataUriText(isBase64, data);
+                case 'ArrayBuffer':
+                    return decodeDataUriArrayBuffer(isBase64, data);
+                case 'blob':
+                    var buffer = decodeDataUriArrayBuffer(isBase64, data);
+                    return new Blob([buffer], {
+                        type : mimeType
+                    });
+                case 'document':
+                    var parser = new DOMParser();
+                    return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType);
+                case 'json':
+                    return JSON.parse(decodeDataUriText(isBase64, data));
+                default:
+                    throw 'Unhandled responseType: ' + responseType;
+                }
+            }
+
+            var dataUriRegexResult = dataUriRegex.exec(path);
+            if (dataUriRegexResult !== null) {
+                delegate.streamAvailable(path, decodeDataUri(dataUriRegexResult, type));
+                return;
+            }
+
+            var self = this;
+
+            if (!type) {
+                delegate.handleError(THREE.GLTFLoaderUtils.INVALID_TYPE, null);
+                return;
+            }
+
+            if (!path) {
+                delegate.handleError(THREE.GLTFLoaderUtils.INVALID_PATH);
+                return;
+            }
+
+            var xhr = new XMLHttpRequest();
+            xhr.open('GET', path, true);
+            xhr.responseType = (type === this.ARRAY_BUFFER) ? "arraybuffer" : "text";
 
             //if this is not specified, 1 "big blob" scenes fails to load.
-	xhr.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 1970 00:00:00 GMT");
-	xhr.addEventListener( 'load', function ( event ) {
-		delegate.streamAvailable(path, xhr.response);
-	}, false );
-	xhr.addEventListener( 'error', function ( event ) {
-		delegate.handleError(THREE.GLTFLoaderUtils.XMLHTTPREQUEST_STATUS_ERROR, xhr.status);
-	}, false );
-	xhr.send(null);
+            xhr.setRequestHeader("If-Modified-Since", "Sat, 01 Jan 1970 00:00:00 GMT");
+            xhr.onload = function(e) {
+                if ((xhr.status == 200) || (xhr.status == 206)) {
+
+                    delegate.streamAvailable(path, xhr.response);
+
+                } else {
+                    delegate.handleError(THREE.GLTFLoaderUtils.XMLHTTPREQUEST_STATUS_ERROR, this.status);
+                }
+            };
+            xhr.send(null);
         }
     },
 
@@ -97,89 +156,109 @@ THREE.GLTFLoaderUtils = Object.create(Object, {
 
     _handleRequest: {
         value: function(request) {
-	var resourceStatus = this._resourcesStatus[request.id];
-	if (resourceStatus)
+            var resourceStatus = this._resourcesStatus[request.id];
+            if (resourceStatus)
             {
-		this._resourcesStatus[request.id] ++;
-	}
+            	this._resourcesStatus[request.id]++;
+            }
             else
-	{
-		this._resourcesStatus[request.id] = 1;
-	}
+            {
+            	this._resourcesStatus[request.id] = 1;
+            }
             
-	var streamStatus = this._streamsStatus[request.path];
-	if (streamStatus && streamStatus.status === "loading" )
+            var streamStatus = this._streamsStatus[request.uri];
+            if (streamStatus && streamStatus.status === "loading" )
             {
-		streamStatus.requests.push(request);
-		return;
-	}
+            	streamStatus.requests.push(request);
+                return;
+            }
             
-	this._streamsStatus[request.path] = { status : "loading", requests : [ request ] };
+            this._streamsStatus[request.uri] = { status : "loading", requests : [request] };
     		
-	var self = this;
-	var processResourceDelegate = {};
-
-	processResourceDelegate.streamAvailable = function(path, res_) {
-		var streamStatus = self._streamsStatus[path];
-		var requests = streamStatus.requests;
-		requests.forEach( function(req_) {
-			var subArray = res_.slice(req_.range[0], req_.range[1]);
-			var convertedResource = req_.delegate.convert(subArray, req_.ctx);
-			self._storeResource(req_.id, convertedResource);
-			req_.delegate.resourceAvailable(convertedResource, req_.ctx);
-			-- self._resourcesStatus[req_.id];
-
-		}, this);
+            var self = this;
+            var processResourceDelegate = {};
+
+            processResourceDelegate.streamAvailable = function(path, res_) {
+            	var streamStatus = self._streamsStatus[path];
+            	var requests = streamStatus.requests;
+                requests.forEach( function(req_) {
+                    var subArray = res_.slice(req_.range[0], req_.range[1]);
+                    var convertedResource = req_.delegate.convert(subArray, req_.ctx);
+                    self._storeResource(req_.id, convertedResource);
+                    req_.delegate.resourceAvailable(convertedResource, req_.ctx);
+                    --self._resourcesStatus[req_.id];
+
+                }, this);
             	
-		delete self._streamsStatus[path];
+                delete self._streamsStatus[path];
 
-	};
+            };
 
-	processResourceDelegate.handleError = function(errorCode, info) {
-		request.delegate.handleError(errorCode, info);
-	};
+            processResourceDelegate.handleError = function(errorCode, info) {
+                request.delegate.handleError(errorCode, info);
+            }
 
-	this._loadStream(request.path, request.type, processResourceDelegate);
+            this._loadStream(request.uri, request.type, processResourceDelegate);
         }
     },
 
 
     _elementSizeForGLType: {
-        value: function(glType) {
-	switch (glType) {
-		case WebGLRenderingContext.FLOAT :
-			return Float32Array.BYTES_PER_ELEMENT;
-		case WebGLRenderingContext.UNSIGNED_BYTE :
-			return Uint8Array.BYTES_PER_ELEMENT;
-		case WebGLRenderingContext.UNSIGNED_SHORT :
-			return Uint16Array.BYTES_PER_ELEMENT;
-		case WebGLRenderingContext.FLOAT_VEC2 :
-			return Float32Array.BYTES_PER_ELEMENT * 2;
-		case WebGLRenderingContext.FLOAT_VEC3 :
-			return Float32Array.BYTES_PER_ELEMENT * 3;
-		case WebGLRenderingContext.FLOAT_VEC4 :
-			return Float32Array.BYTES_PER_ELEMENT * 4;
-		case WebGLRenderingContext.FLOAT_MAT3 :
-			return Float32Array.BYTES_PER_ELEMENT * 9;
-		case WebGLRenderingContext.FLOAT_MAT4 :
-			return Float32Array.BYTES_PER_ELEMENT * 16;
-		default:
-			return null;
-	}
+        value: function(componentType, type) {
+    	
+    		var nElements = 0;
+    		switch(type) {    		
+	            case "SCALAR" :
+	                nElements = 1;
+	                break;
+	            case "VEC2" :
+	                nElements = 2;
+	                break;
+	            case "VEC3" :
+	                nElements = 3;
+	                break;
+	            case "VEC4" :
+	                nElements = 4;
+	                break;
+	            case "MAT2" :
+	                nElements = 4;
+	                break;
+	            case "MAT3" :
+	                nElements = 9;
+	                break;
+	            case "MAT4" :
+	                nElements = 16;
+	                break;
+	            default :
+	            	debugger;
+	            	break;
+    		}
+    		
+            switch (componentType) {
+                case WebGLRenderingContext.FLOAT :
+                    return Float32Array.BYTES_PER_ELEMENT * nElements;
+                case WebGLRenderingContext.UNSIGNED_BYTE :
+                    return Uint8Array.BYTES_PER_ELEMENT * nElements;
+                case WebGLRenderingContext.UNSIGNED_SHORT :
+                    return Uint16Array.BYTES_PER_ELEMENT * nElements;
+                default :
+                	debugger;
+                    return null;
+            }
         }
     },
 
     _handleWrappedBufferViewResourceLoading: {
         value: function(wrappedBufferView, delegate, ctx) {
-	var bufferView = wrappedBufferView.bufferView;
-	var buffer = bufferView.buffer;
-	var byteOffset = wrappedBufferView.byteOffset + bufferView.description.byteOffset;
-	var range = [ byteOffset, (this._elementSizeForGLType(wrappedBufferView.type) * wrappedBufferView.count) + byteOffset ];
+            var bufferView = wrappedBufferView.bufferView;
+            var buffer = bufferView.buffer;
+            var byteOffset = wrappedBufferView.byteOffset + bufferView.description.byteOffset;
+            var range = [byteOffset , (this._elementSizeForGLType(wrappedBufferView.componentType, wrappedBufferView.type) * wrappedBufferView.count) + byteOffset];
 
-	this._handleRequest({ "id" : wrappedBufferView.id,
+            this._handleRequest({   "id" : wrappedBufferView.id,
                                     "range" : range,
                                     "type" : buffer.description.type,
-                                    "path" : buffer.description.path,
+                                    "uri" : buffer.description.uri,
                                     "delegate" : delegate,
                                     "ctx" : ctx }, null);
         }
@@ -189,14 +268,14 @@ THREE.GLTFLoaderUtils = Object.create(Object, {
     	
             value: function(wrappedBufferView, delegate, ctx) {
 
-	var savedBuffer = this._getResource(wrappedBufferView.id);
-	if (savedBuffer) {
-		return savedBuffer;
-	} else {
-		this._handleWrappedBufferViewResourceLoading(wrappedBufferView, delegate, ctx);
-	}
+            var savedBuffer = this._getResource(wrappedBufferView.id);
+            if (false) { // savedBuffer) {
+                return savedBuffer;
+            } else {
+                this._handleWrappedBufferViewResourceLoading(wrappedBufferView, delegate, ctx);
+            }
 
-	return null;
+            return null;
         }
     },
 
@@ -204,17 +283,17 @@ THREE.GLTFLoaderUtils = Object.create(Object, {
     	
         value: function(request, delegate, ctx) {
 
-	request.delegate = delegate;
-	request.ctx = ctx;
+    		request.delegate = delegate;
+    		request.ctx = ctx;
 
-	this._handleRequest({ "id" : request.id,
-                "path" : request.path,
-                "range" : [ 0 ],
+            this._handleRequest({   "id" : request.id,
+                "uri" : request.uri,
+                "range" : [0],
                 "type" : "text",
                 "delegate" : delegate,
                 "ctx" : ctx }, null);
     	
-	return null;
-}
+            return null;
+	    }
 	},    
 });

+ 145 - 0
examples/js/loaders/gltf/glTFShaders.js

@@ -0,0 +1,145 @@
+/**
+ * @author Tony Parisi / http://www.tonyparisi.com/
+ */
+
+THREE.glTFShaders = ( function () {
+
+	var shaders = [];
+
+	return	{
+		add : function(shader) {
+			shaders.push(shader);
+		},
+
+		remove: function(shader) {
+
+			var i = shaders.indexOf(shader);
+
+			if ( i !== -1 ) {
+				shaders.splice( i, 1 );
+			}
+		},
+
+		removeAll: function(shader) {
+
+			// probably want to clean up the shaders, too, but not for now
+			shaders = [];
+		},
+
+		bindShaderParameters: function(scene) {
+			for (i = 0; i < shaders.length; i++)
+			{
+				shaders[i].bindParameters(scene);
+			}
+		},
+
+		update : function(scene, camera) {
+			for (i = 0; i < shaders.length; i++)
+			{
+				shaders[i].update(scene, camera);
+			}
+		},
+	};
+})();
+
+// Construction/initialization
+THREE.glTFShader = function(material, params, object, scene) {
+	this.material = material;
+	this.parameters = params.technique.parameters;
+	this.uniforms = params.technique.uniforms;
+	this.joints = params.joints;
+	this.object = object;
+	this.semantics = {};
+	this.m4 = new THREE.Matrix4;
+}
+
+
+// bindParameters - connect the uniform values to their source parameters
+THREE.glTFShader.prototype.bindParameters = function(scene) {
+
+	function findObject(o, p) { 
+		if (o.glTFID == param.node) {
+			p.sourceObject = o;
+		}
+	}
+
+	for (var uniform in this.uniforms) {
+		var pname = this.uniforms[uniform];
+		var param = this.parameters[pname];
+		if (param.semantic) {
+
+			var p = { 
+				semantic : param.semantic,
+				uniform: this.material.uniforms[uniform] 
+			};
+
+			if (param.node) {
+				scene.traverse(function(o) { findObject(o, p)});
+			}
+			else {
+				p.sourceObject = this.object;
+			}			
+
+			this.semantics[pname] = p;
+
+		}
+	}
+
+}
+
+// Update - update all the uniform values
+THREE.glTFShader.prototype.update = function(scene, camera) {
+
+	// update scene graph
+
+	scene.updateMatrixWorld();
+
+	// update camera matrices and frustum
+	camera.updateMatrixWorld();
+	camera.matrixWorldInverse.getInverse( camera.matrixWorld );
+
+	for (var sname in this.semantics) {
+		var semantic = this.semantics[sname];
+        if (semantic) {
+	        switch (semantic.semantic) {
+	            case "MODELVIEW" :
+	            	var m4 = semantic.uniform.value;
+	            	m4.multiplyMatrices(camera.matrixWorldInverse, 
+	            		semantic.sourceObject.matrixWorld);
+	                break;
+
+	            case "MODELVIEWINVERSETRANSPOSE" :
+	            	var m3 = semantic.uniform.value;
+	            	this.m4.multiplyMatrices(camera.matrixWorldInverse, 
+	            		semantic.sourceObject.matrixWorld);
+					m3.getNormalMatrix(this.m4);
+	                break;
+
+	            case "PROJECTION" :
+	            	var m4 = semantic.uniform.value;
+	            	m4.copy(camera.projectionMatrix);            		
+	                break;
+
+	            case "JOINTMATRIX" :
+	            
+	            	var m4v = semantic.uniform.value;
+					for (var mi = 0; mi < m4v.length; mi++) {
+						// So it goes like this:
+						// SkinnedMesh world matrix is already baked into MODELVIEW;
+						// ransform joints to local space,
+						// then transform using joint's inverse
+						m4v[mi].getInverse(semantic.sourceObject.matrixWorld).
+							multiply(this.joints[mi].matrixWorld).
+							multiply(this.object.skeleton.boneInverses[mi]);
+					}
+	            
+	                //console.log("Joint:", semantic)
+	                break;
+
+	            default :
+	                throw new Error("Unhandled shader semantic" + semantic);
+	                break;
+	        }
+        }
+	}
+}

+ 204 - 0
examples/js/loaders/gltf/gltfUtilities.js

@@ -0,0 +1,204 @@
+/**
+gltfUtilities
+@license
+The MIT License (MIT)
+Copyright (c) 2014 Analytical Graphics, Inc.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+(function(root, factory) {
+    "use strict";
+    /*global define*/
+    if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define([], factory);
+    } else {
+        // Browser globals
+        root.gltfUtilities = factory();
+    }
+}(this, function() {
+    "use strict";
+
+    /**
+     * Given a URL, determine whether that URL is considered cross-origin to the current page.
+     */
+    var isCrossOriginUrl = function(url) {
+        var location = window.location;
+        var a = document.createElement('a');
+
+        a.href = url;
+
+        // host includes both hostname and port if the port is not standard
+        return location.protocol !== a.protocol || location.host !== a.host;
+    };
+
+    var isDataUriRegex = /^data:/;
+
+    /**
+     * Asynchronously loads the given image URL.  Attempts to load cross-origin images using CORS.
+     *
+     * @param {String} url The source of the image.
+     * @param {Function} success A function that will be called with an Image object
+     *                           once the image has loaded successfully.
+     * @param {Function} [error] A function that will be called if the request fails.
+     *
+     * @see <a href='http://www.w3.org/TR/cors/'>Cross-Origin Resource Sharing</a>
+     */
+    var loadImage = function(url, success, error) {
+        var image = new Image();
+
+        image.onload = function() {
+            success(image);
+        };
+
+        if (typeof error !== 'undefined') {
+            image.onerror = error;
+        }
+
+        var crossOrigin;
+        if (isDataUriRegex.test(url)) {
+            crossOrigin = false;
+        } else {
+            crossOrigin = isCrossOriginUrl(url);
+        }
+
+        if (crossOrigin) {
+            image.crossOrigin = '';
+        }
+
+        image.src = url;
+    };
+
+    var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
+
+    function decodeDataUriText(isBase64, data) {
+        var result = decodeURIComponent(data);
+        if (isBase64) {
+            return atob(result);
+        }
+        return result;
+    }
+
+    function decodeDataUriArrayBuffer(isBase64, data) {
+        var byteString = decodeDataUriText(isBase64, data);
+        var buffer = new ArrayBuffer(byteString.length);
+        var view = new Uint8Array(buffer);
+        for (var i = 0; i < byteString.length; i++) {
+            view[i] = byteString.charCodeAt(i);
+        }
+        return buffer;
+    }
+
+    function decodeDataUri(dataUriRegexResult, responseType) {
+        responseType = typeof responseType !== 'undefined' ? responseType : '';
+        var mimeType = dataUriRegexResult[1];
+        var isBase64 = !!dataUriRegexResult[2];
+        var data = dataUriRegexResult[3];
+
+        switch (responseType) {
+        case '':
+        case 'text':
+            return decodeDataUriText(isBase64, data);
+        case 'arraybuffer':
+            return decodeDataUriArrayBuffer(isBase64, data);
+        case 'blob':
+            var buffer = decodeDataUriArrayBuffer(isBase64, data);
+            return new Blob([buffer], {
+                type : mimeType
+            });
+        case 'document':
+            var parser = new DOMParser();
+            return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType);
+        case 'json':
+            return JSON.parse(decodeDataUriText(isBase64, data));
+        default:
+            throw 'Unhandled responseType: ' + responseType;
+        }
+    }
+
+    var loadWithXhr = function(url, responseType, success, error) {
+        var dataUriRegexResult = dataUriRegex.exec(url);
+        if (dataUriRegexResult !== null) {
+            success(decodeDataUri(dataUriRegexResult, responseType));
+            return;
+        }
+
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+
+        if (typeof responseType !== 'undefined') {
+            xhr.responseType = responseType;
+        }
+
+        xhr.onload = function(e) {
+            if (xhr.status === 200) {
+                success(xhr.response);
+            } else {
+                error(xhr);
+            }
+        };
+
+        xhr.onerror = function(e) {
+            error(xhr);
+        };
+
+        xhr.send();
+    };
+
+    /**
+     * Asynchronously loads the given URL as raw binary data.  The data is loaded
+     * using XMLHttpRequest, which means that in order to make requests to another origin,
+     * the server must have Cross-Origin Resource Sharing (CORS) headers enabled.
+     *
+     * @param {String} url The URL of the binary data.
+     * @param {Function} success A function that will be called with an ArrayBuffer object
+     *                           once the data has loaded successfully.
+     * @param {Function} [error] A function that will be called with the XMLHttpRequest object
+     *                           if the request fails.
+     *
+     * @see <a href="http://en.wikipedia.org/wiki/XMLHttpRequest">XMLHttpRequest</a>
+     * @see <a href='http://www.w3.org/TR/cors/'>Cross-Origin Resource Sharing</a>
+     */
+    var loadArrayBuffer = function(url, success, error) {
+        loadWithXhr(url, 'arraybuffer', success, error);
+    };
+
+    /**
+     * Asynchronously loads the given URL as text.  The data is loaded
+     * using XMLHttpRequest, which means that in order to make requests to another origin,
+     * the server must have Cross-Origin Resource Sharing (CORS) headers enabled.
+     *
+     * @param {String} url The URL to request.
+     * @param {Function} success A function that will be called with a String
+     *                           once the data has loaded successfully.
+     * @param {Function} [error] A function that will be called with the XMLHttpRequest object
+     *                           if the request fails.
+     *
+     * @see <a href="http://en.wikipedia.org/wiki/XMLHttpRequest">XMLHttpRequest</a>
+     * @see <a href='http://www.w3.org/TR/cors/'>Cross-Origin Resource Sharing</a>
+     */
+    var loadText = function(url, success, error) {
+        return loadWithXhr(url, undefined, success, error);
+    };
+
+    return {
+        loadImage : loadImage,
+        loadArrayBuffer : loadArrayBuffer,
+        loadText : loadText
+    };
+}));
+
+

+ 1 - 2
examples/js/materials/ShadowMaterial.js

@@ -6,7 +6,6 @@ THREE.ShadowMaterial = function () {
 
 	THREE.ShaderMaterial.call( this, {
 		uniforms: THREE.UniformsUtils.merge( [
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
 			{
 				opacity:  { type: 'f', value: 1.0 }
@@ -29,7 +28,7 @@ THREE.ShadowMaterial = function () {
 			THREE.ShaderChunk[ "shadowmask_pars_fragment" ],
 			"uniform float opacity;",
 			"void main() {",
-			"	gl_FragColor = vec4( 0.0, 0.0, 0.0, opacity - getShadowMask() );",
+			"	gl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0  - getShadowMask() ) );",
 			"}"
 		].join( '\n' )
 	} );

+ 0 - 1
examples/js/modifiers/ExplodeModifier.js

@@ -38,6 +38,5 @@ THREE.ExplodeModifier.prototype.modify = function ( geometry ) {
 	}
 
 	geometry.vertices = vertices;
-	delete geometry.__tmpVertices;
 
 };

+ 387 - 350
examples/js/modifiers/SubdivisionModifier.js

@@ -1,350 +1,387 @@
-/*
- *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog 
- *
- *	Subdivision Geometry Modifier 
- *		using Loop Subdivision Scheme
- *
- *	References:
- *		http://graphics.stanford.edu/~mdfisher/subdivision.html
- *		http://www.holmes3d.net/graphics/subdivision/
- *		http://www.cs.rutgers.edu/~decarlo/readings/subdiv-sg00c.pdf
- *
- *	Known Issues:
- *		- currently doesn't handle UVs
- *		- currently doesn't handle "Sharp Edges"
- *
- */
-
-THREE.SubdivisionModifier = function ( subdivisions ) {
-
-	this.subdivisions = ( subdivisions === undefined ) ? 1 : subdivisions;
-
-};
-
-// Applies the "modify" pattern
-THREE.SubdivisionModifier.prototype.modify = function ( geometry ) {
-
-	var repeats = this.subdivisions;
-
-	while ( repeats -- > 0 ) {
-
-		this.smooth( geometry );
-
-	}
-
-	delete geometry.__tmpVertices;
-
-	geometry.computeFaceNormals();
-	geometry.computeVertexNormals();
-
-};
-
-( function() {
-
-	// Some constants
-	var WARNINGS = ! true; // Set to true for development
-	var ABC = [ 'a', 'b', 'c' ];
-	
-
-	function getEdge( a, b, map ) {
-
-		var vertexIndexA = Math.min( a, b );
-		var vertexIndexB = Math.max( a, b );
-
-		var key = vertexIndexA + "_" + vertexIndexB;
-
-		return map[ key ];
-
-	}
-
-
-	function processEdge( a, b, vertices, map, face, metaVertices ) {
-
-		var vertexIndexA = Math.min( a, b );
-		var vertexIndexB = Math.max( a, b );
-
-		var key = vertexIndexA + "_" + vertexIndexB;
-
-		var edge;
-
-		if ( key in map ) {
-
-			edge = map[ key ];
-
-		} else {
-			
-			var vertexA = vertices[ vertexIndexA ];
-			var vertexB = vertices[ vertexIndexB ];
-
-			edge = {
-
-				a: vertexA, // pointer reference
-				b: vertexB,
-				newEdge: null,
-				// aIndex: a, // numbered reference
-				// bIndex: b,
-				faces: [] // pointers to face
-
-			};
-
-			map[ key ] = edge;
-
-		}
-
-		edge.faces.push( face );
-
-		metaVertices[ a ].edges.push( edge );
-		metaVertices[ b ].edges.push( edge );
-		
-
-	}
-
-	function generateLookups( vertices, faces, metaVertices, edges ) {
-
-		var i, il, face, edge;
-
-		for ( i = 0, il = vertices.length; i < il; i ++ ) {
-
-			metaVertices[ i ] = { edges: [] };
-
-		}
-		
-		for ( i = 0, il = faces.length; i < il; i ++ ) {
-
-			face = faces[ i ];
-
-			processEdge( face.a, face.b, vertices, edges, face, metaVertices );
-			processEdge( face.b, face.c, vertices, edges, face, metaVertices );
-			processEdge( face.c, face.a, vertices, edges, face, metaVertices );
-
-		}
-
-	}
-
-	function newFace( newFaces, a, b, c ) {
-
-		newFaces.push( new THREE.Face3( a, b, c ) );
-
-	}
-
-
-	/////////////////////////////
-
-	// Performs one iteration of Subdivision
-	THREE.SubdivisionModifier.prototype.smooth = function ( geometry ) {
-
-		var tmp = new THREE.Vector3();
-
-		var oldVertices, oldFaces;
-		var newVertices, newFaces; // newUVs = [];
-
-		var n, l, i, il, j, k;
-		var metaVertices, sourceEdges;
-
-		// new stuff.
-		var sourceEdges, newEdgeVertices, newSourceVertices;
-
-		oldVertices = geometry.vertices; // { x, y, z}
-		oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 }
-
-		/******************************************************
-		 *
-		 * Step 0: Preprocess Geometry to Generate edges Lookup
-		 *
-		 *******************************************************/
-
-		metaVertices = new Array( oldVertices.length );
-		sourceEdges = {}; // Edge => { oldVertex1, oldVertex2, faces[]  }
-
-		generateLookups( oldVertices, oldFaces, metaVertices, sourceEdges );
-
-
-		/******************************************************
-		 *
-		 *	Step 1. 
-		 *	For each edge, create a new Edge Vertex,
-		 *	then position it.
-		 *
-		 *******************************************************/
-
-		newEdgeVertices = [];
-		var other, currentEdge, newEdge, face;
-		var edgeVertexWeight, adjacentVertexWeight, connectedFaces;
-
-		for ( i in sourceEdges ) {
-
-			currentEdge = sourceEdges[ i ];
-			newEdge = new THREE.Vector3();
-
-			edgeVertexWeight = 3 / 8;
-			adjacentVertexWeight = 1 / 8;
-
-			connectedFaces = currentEdge.faces.length;
-
-			// check how many linked faces. 2 should be correct.
-			if ( connectedFaces != 2 ) {
-
-				// if length is not 2, handle condition
-				edgeVertexWeight = 0.5;
-				adjacentVertexWeight = 0;
-
-				if ( connectedFaces != 1 ) {
-					
-					if ( WARNINGS ) console.warn( 'Subdivision Modifier: Number of connected faces != 2, is: ', connectedFaces, currentEdge );
-			
-				}
-
-			}
-
-			newEdge.addVectors( currentEdge.a, currentEdge.b ).multiplyScalar( edgeVertexWeight );
-
-			tmp.set( 0, 0, 0 );
-
-			for ( j = 0; j < connectedFaces; j ++ ) {
-
-				face = currentEdge.faces[ j ];
-				
-				for ( k = 0; k < 3; k ++ ) {
-
-					other = oldVertices[ face[ ABC[ k ] ] ];
-					if ( other !== currentEdge.a && other !== currentEdge.b ) break;
-
-				}
-
-				tmp.add( other );
-
-			}
-
-			tmp.multiplyScalar( adjacentVertexWeight );
-			newEdge.add( tmp );
-
-			currentEdge.newEdge = newEdgeVertices.length;
-			newEdgeVertices.push( newEdge );
-
-			// console.log(currentEdge, newEdge);
-
-		}
-
-		/******************************************************
-		 *
-		 *	Step 2. 
-		 *	Reposition each source vertices.
-		 *
-		 *******************************************************/
-
-		var beta, sourceVertexWeight, connectingVertexWeight;
-		var connectingEdge, connectingEdges, oldVertex, newSourceVertex;
-		newSourceVertices = [];
-
-		for ( i = 0, il = oldVertices.length; i < il; i ++ ) {
-
-			oldVertex = oldVertices[ i ];
-
-			// find all connecting edges (using lookupTable)
-			connectingEdges = metaVertices[ i ].edges;
-			n = connectingEdges.length;
-			beta;
-
-			if ( n == 3 ) {
-
-				beta = 3 / 16;
-
-			} else if ( n > 3 ) {
-
-				beta = 3 / ( 8 * n ); // Warren's modified formula
-
-			}
-
-			// Loop's original beta formula
-			// beta = 1 / n * ( 5/8 - Math.pow( 3/8 + 1/4 * Math.cos( 2 * Math. PI / n ), 2) );
-
-			sourceVertexWeight = 1 - n * beta;
-			connectingVertexWeight = beta;
-
-			if ( n <= 2 ) {
-				
-				// crease and boundary rules
-				// console.warn('crease and boundary rules');
-
-				if ( n == 2 ) {
-
-					if ( WARNINGS ) console.warn( '2 connecting edges', connectingEdges );
-					sourceVertexWeight = 3 / 4;
-					connectingVertexWeight = 1 / 8;
-
-					// sourceVertexWeight = 1;
-					// connectingVertexWeight = 0;
-
-				} else if ( n == 1 ) {
-
-					if ( WARNINGS ) console.warn( 'only 1 connecting edge' );
-
-				} else if ( n == 0 ) {
-
-					if ( WARNINGS ) console.warn( '0 connecting edges' );
-			
-				}
-			
-			}
-
-			newSourceVertex = oldVertex.clone().multiplyScalar( sourceVertexWeight );
-
-			tmp.set( 0, 0, 0 );
-
-			for ( j = 0; j < n; j ++ ) {
-
-				connectingEdge = connectingEdges[ j ];
-				other = connectingEdge.a !== oldVertex ? connectingEdge.a : connectingEdge.b;
-				tmp.add( other );
-
-			}
-
-			tmp.multiplyScalar( connectingVertexWeight );
-			newSourceVertex.add( tmp );
-			
-			newSourceVertices.push( newSourceVertex );
-
-		}
-
-							   
-		/******************************************************
-		 *
-		 *	Step 3. 
-		 *	Generate Faces between source vertecies
-		 *	and edge vertices.
-		 *
-		 *******************************************************/
-
-		newVertices = newSourceVertices.concat( newEdgeVertices );
-		var sl = newSourceVertices.length, edge1, edge2, edge3;
-		newFaces = [];
-
-		for ( i = 0, il = oldFaces.length; i < il; i ++ ) {
-
-			face = oldFaces[ i ];
-
-			// find the 3 new edges vertex of each old face
-
-			edge1 = getEdge( face.a, face.b, sourceEdges ).newEdge + sl;
-			edge2 = getEdge( face.b, face.c, sourceEdges ).newEdge + sl;
-			edge3 = getEdge( face.c, face.a, sourceEdges ).newEdge + sl;
-
-			// create 4 faces.
-
-			newFace( newFaces, edge1, edge2, edge3 );
-			newFace( newFaces, face.a, edge1, edge3 );
-			newFace( newFaces, face.b, edge2, edge1 );
-			newFace( newFaces, face.c, edge3, edge2 );
-
-		}
-
-		// Overwrite old arrays
-		geometry.vertices = newVertices;
-		geometry.faces = newFaces;
-
-		// console.log('done');
-
-	};
-
-
-} )();
+/*
+ *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
+ *	@author centerionware / http://www.centerionware.com
+ *
+ *	Subdivision Geometry Modifier
+ *		using Loop Subdivision Scheme
+ *
+ *	References:
+ *		http://graphics.stanford.edu/~mdfisher/subdivision.html
+ *		http://www.holmes3d.net/graphics/subdivision/
+ *		http://www.cs.rutgers.edu/~decarlo/readings/subdiv-sg00c.pdf
+ *
+ *	Known Issues:
+ *		- currently doesn't handle "Sharp Edges"
+ */
+
+THREE.SubdivisionModifier = function ( subdivisions ) {
+
+	this.subdivisions = ( subdivisions === undefined ) ? 1 : subdivisions;
+
+};
+
+// Applies the "modify" pattern
+THREE.SubdivisionModifier.prototype.modify = function ( geometry ) {
+
+	var repeats = this.subdivisions;
+
+	while ( repeats -- > 0 ) {
+
+		this.smooth( geometry );
+
+	}
+
+	geometry.computeFaceNormals();
+	geometry.computeVertexNormals();
+
+};
+
+( function() {
+
+	// Some constants
+	var WARNINGS = ! true; // Set to true for development
+	var ABC = [ 'a', 'b', 'c' ];
+
+
+	function getEdge( a, b, map ) {
+
+		var vertexIndexA = Math.min( a, b );
+		var vertexIndexB = Math.max( a, b );
+
+		var key = vertexIndexA + "_" + vertexIndexB;
+
+		return map[ key ];
+
+	}
+
+
+	function processEdge( a, b, vertices, map, face, metaVertices ) {
+
+		var vertexIndexA = Math.min( a, b );
+		var vertexIndexB = Math.max( a, b );
+
+		var key = vertexIndexA + "_" + vertexIndexB;
+
+		var edge;
+
+		if ( key in map ) {
+
+			edge = map[ key ];
+
+		} else {
+
+			var vertexA = vertices[ vertexIndexA ];
+			var vertexB = vertices[ vertexIndexB ];
+
+			edge = {
+
+				a: vertexA, // pointer reference
+				b: vertexB,
+				newEdge: null,
+				// aIndex: a, // numbered reference
+				// bIndex: b,
+				faces: [] // pointers to face
+
+			};
+
+			map[ key ] = edge;
+
+		}
+
+		edge.faces.push( face );
+
+		metaVertices[ a ].edges.push( edge );
+		metaVertices[ b ].edges.push( edge );
+
+
+	}
+
+	function generateLookups( vertices, faces, metaVertices, edges ) {
+
+		var i, il, face, edge;
+
+		for ( i = 0, il = vertices.length; i < il; i ++ ) {
+
+			metaVertices[ i ] = { edges: [] };
+
+		}
+
+		for ( i = 0, il = faces.length; i < il; i ++ ) {
+
+			face = faces[ i ];
+
+			processEdge( face.a, face.b, vertices, edges, face, metaVertices );
+			processEdge( face.b, face.c, vertices, edges, face, metaVertices );
+			processEdge( face.c, face.a, vertices, edges, face, metaVertices );
+
+		}
+
+	}
+
+	function newFace( newFaces, a, b, c ) {
+
+		newFaces.push( new THREE.Face3( a, b, c ) );
+
+	}
+
+	function midpoint( a, b ) {
+
+		return ( Math.abs( b - a ) / 2 ) + Math.min( a, b );
+
+	}
+
+	function newUv( newUvs, a, b, c ) {
+
+		newUvs.push( [ a.clone(), b.clone(), c.clone() ] );
+
+	}
+
+	/////////////////////////////
+
+	// Performs one iteration of Subdivision
+	THREE.SubdivisionModifier.prototype.smooth = function ( geometry ) {
+
+		var tmp = new THREE.Vector3();
+
+		var oldVertices, oldFaces, oldUvs;
+		var newVertices, newFaces, newUVs = [];
+
+		var n, l, i, il, j, k;
+		var metaVertices, sourceEdges;
+
+		// new stuff.
+		var sourceEdges, newEdgeVertices, newSourceVertices;
+
+		oldVertices = geometry.vertices; // { x, y, z}
+		oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 }
+		oldUvs = geometry.faceVertexUvs[ 0 ];
+
+		var hasUvs = oldUvs !== undefined && oldUvs.length > 0;
+
+		/******************************************************
+		 *
+		 * Step 0: Preprocess Geometry to Generate edges Lookup
+		 *
+		 *******************************************************/
+
+		metaVertices = new Array( oldVertices.length );
+		sourceEdges = {}; // Edge => { oldVertex1, oldVertex2, faces[]  }
+
+		generateLookups( oldVertices, oldFaces, metaVertices, sourceEdges );
+
+
+		/******************************************************
+		 *
+		 *	Step 1.
+		 *	For each edge, create a new Edge Vertex,
+		 *	then position it.
+		 *
+		 *******************************************************/
+
+		newEdgeVertices = [];
+		var other, currentEdge, newEdge, face;
+		var edgeVertexWeight, adjacentVertexWeight, connectedFaces;
+
+		for ( i in sourceEdges ) {
+
+			currentEdge = sourceEdges[ i ];
+			newEdge = new THREE.Vector3();
+
+			edgeVertexWeight = 3 / 8;
+			adjacentVertexWeight = 1 / 8;
+
+			connectedFaces = currentEdge.faces.length;
+
+			// check how many linked faces. 2 should be correct.
+			if ( connectedFaces != 2 ) {
+
+				// if length is not 2, handle condition
+				edgeVertexWeight = 0.5;
+				adjacentVertexWeight = 0;
+
+				if ( connectedFaces != 1 ) {
+
+					if ( WARNINGS ) console.warn( 'Subdivision Modifier: Number of connected faces != 2, is: ', connectedFaces, currentEdge );
+
+				}
+
+			}
+
+			newEdge.addVectors( currentEdge.a, currentEdge.b ).multiplyScalar( edgeVertexWeight );
+
+			tmp.set( 0, 0, 0 );
+
+			for ( j = 0; j < connectedFaces; j ++ ) {
+
+				face = currentEdge.faces[ j ];
+
+				for ( k = 0; k < 3; k ++ ) {
+
+					other = oldVertices[ face[ ABC[ k ] ] ];
+					if ( other !== currentEdge.a && other !== currentEdge.b ) break;
+
+				}
+
+				tmp.add( other );
+
+			}
+
+			tmp.multiplyScalar( adjacentVertexWeight );
+			newEdge.add( tmp );
+
+			currentEdge.newEdge = newEdgeVertices.length;
+			newEdgeVertices.push( newEdge );
+
+			// console.log(currentEdge, newEdge);
+
+		}
+
+		/******************************************************
+		 *
+		 *	Step 2.
+		 *	Reposition each source vertices.
+		 *
+		 *******************************************************/
+
+		var beta, sourceVertexWeight, connectingVertexWeight;
+		var connectingEdge, connectingEdges, oldVertex, newSourceVertex;
+		newSourceVertices = [];
+
+		for ( i = 0, il = oldVertices.length; i < il; i ++ ) {
+
+			oldVertex = oldVertices[ i ];
+
+			// find all connecting edges (using lookupTable)
+			connectingEdges = metaVertices[ i ].edges;
+			n = connectingEdges.length;
+
+			if ( n == 3 ) {
+
+				beta = 3 / 16;
+
+			} else if ( n > 3 ) {
+
+				beta = 3 / ( 8 * n ); // Warren's modified formula
+
+			}
+
+			// Loop's original beta formula
+			// beta = 1 / n * ( 5/8 - Math.pow( 3/8 + 1/4 * Math.cos( 2 * Math. PI / n ), 2) );
+
+			sourceVertexWeight = 1 - n * beta;
+			connectingVertexWeight = beta;
+
+			if ( n <= 2 ) {
+
+				// crease and boundary rules
+				// console.warn('crease and boundary rules');
+
+				if ( n == 2 ) {
+
+					if ( WARNINGS ) console.warn( '2 connecting edges', connectingEdges );
+					sourceVertexWeight = 3 / 4;
+					connectingVertexWeight = 1 / 8;
+
+					// sourceVertexWeight = 1;
+					// connectingVertexWeight = 0;
+
+				} else if ( n == 1 ) {
+
+					if ( WARNINGS ) console.warn( 'only 1 connecting edge' );
+
+				} else if ( n == 0 ) {
+
+					if ( WARNINGS ) console.warn( '0 connecting edges' );
+
+				}
+
+			}
+
+			newSourceVertex = oldVertex.clone().multiplyScalar( sourceVertexWeight );
+
+			tmp.set( 0, 0, 0 );
+
+			for ( j = 0; j < n; j ++ ) {
+
+				connectingEdge = connectingEdges[ j ];
+				other = connectingEdge.a !== oldVertex ? connectingEdge.a : connectingEdge.b;
+				tmp.add( other );
+
+			}
+
+			tmp.multiplyScalar( connectingVertexWeight );
+			newSourceVertex.add( tmp );
+
+			newSourceVertices.push( newSourceVertex );
+
+		}
+
+
+		/******************************************************
+		 *
+		 *	Step 3.
+		 *	Generate Faces between source vertices
+		 *	and edge vertices.
+		 *
+		 *******************************************************/
+
+		newVertices = newSourceVertices.concat( newEdgeVertices );
+		var sl = newSourceVertices.length, edge1, edge2, edge3;
+		newFaces = [];
+
+		var uv, x0, x1, x2;
+		var x3 = new THREE.Vector2();
+		var x4 = new THREE.Vector2();
+		var x5 = new THREE.Vector2();
+
+		for ( i = 0, il = oldFaces.length; i < il; i ++ ) {
+
+			face = oldFaces[ i ];
+
+			// find the 3 new edges vertex of each old face
+
+			edge1 = getEdge( face.a, face.b, sourceEdges ).newEdge + sl;
+			edge2 = getEdge( face.b, face.c, sourceEdges ).newEdge + sl;
+			edge3 = getEdge( face.c, face.a, sourceEdges ).newEdge + sl;
+
+			// create 4 faces.
+
+			newFace( newFaces, edge1, edge2, edge3 );
+			newFace( newFaces, face.a, edge1, edge3 );
+			newFace( newFaces, face.b, edge2, edge1 );
+			newFace( newFaces, face.c, edge3, edge2 );
+
+			// create 4 new uv's
+
+			if ( hasUvs ) {
+
+				uv = oldUvs[ i ];
+
+				x0 = uv[ 0 ];
+				x1 = uv[ 1 ];
+				x2 = uv[ 2 ];
+
+				x3.set( midpoint( x0.x, x1.x ), midpoint( x0.y, x1.y ) );
+				x4.set( midpoint( x1.x, x2.x ), midpoint( x1.y, x2.y ) );
+				x5.set( midpoint( x0.x, x2.x ), midpoint( x0.y, x2.y ) );
+
+				newUv( newUVs, x3, x4, x5 );
+				newUv( newUVs, x0, x3, x5 );
+
+				newUv( newUVs, x1, x4, x3 );
+				newUv( newUVs, x2, x5, x4 );
+
+			}
+
+		}
+
+		// Overwrite old arrays
+		geometry.vertices = newVertices;
+		geometry.faces = newFaces;
+		if ( hasUvs ) geometry.faceVertexUvs[ 0 ] = newUVs;
+
+		// console.log('done');
+
+	};
+
+} )();

+ 0 - 2
examples/js/nodes/materials/PhongNode.js

@@ -32,7 +32,6 @@ THREE.PhongNode.prototype.build = function( builder ) {
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ]
 
 		] ) );
@@ -146,7 +145,6 @@ THREE.PhongNode.prototype.build = function( builder ) {
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],

+ 0 - 2
examples/js/nodes/materials/StandardNode.js

@@ -32,7 +32,6 @@ THREE.StandardNode.prototype.build = function( builder ) {
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ]
 
 		] ) );
@@ -159,7 +158,6 @@ THREE.StandardNode.prototype.build = function( builder ) {
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "ambient_pars" ],
 			THREE.ShaderChunk[ "lights_pars" ],
 			THREE.ShaderChunk[ "lights_standard_pars_fragment" ],
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],

+ 177 - 0
examples/js/pmrem/PMREMCubeUVPacker.js

@@ -0,0 +1,177 @@
+/**
+ * @author Prashant Sharma / spidersharma03
+ * @author Ben Houston / bhouston, https://clara.io
+ *
+ * This class takes the cube lods(corresponding to different roughness values), and creates a single cubeUV
+ * Texture. The format for a given roughness set of faces is simply::
+ * +X+Y+Z
+ * -X-Y-Z
+ * For every roughness a mip map chain is also saved, which is essential to remove the texture artifacts due to
+ * minification.
+ * Right now for every face a PlaneMesh is drawn, which leads to a lot of geometry draw calls, but can be replaced
+ * later by drawing a single buffer and by sending the appropriate faceIndex via vertex attributes.
+ * The arrangement of the faces is fixed, as assuming this arrangement, the sampling function has been written.
+ */
+
+
+THREE.PMREMCubeUVPacker = function( cubeTextureLods, numLods ) {
+
+	this.cubeLods = cubeTextureLods;
+	this.numLods = numLods;
+	var size = cubeTextureLods[ 0 ].width * 4;
+
+	this.CubeUVRenderTarget = new THREE.WebGLRenderTarget( size, size,
+	{ format: THREE.RGBAFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter, type: cubeTextureLods[ 0 ].texture.type } );
+	this.CubeUVRenderTarget.texture.generateMipmaps = false;
+  this.CubeUVRenderTarget.mapping = THREE.CubeUVReflectionMapping;
+	this.camera = new THREE.OrthographicCamera( - size * 0.5, size * 0.5, - size * 0.5, size * 0.5, 0.0, 1000 );
+
+	this.scene = new THREE.Scene();
+	this.scene.add( this.camera );
+
+	this.objects = [];
+	var xOffset = 0;
+	var faceOffsets = [];
+	faceOffsets.push( new THREE.Vector2( 0, 0 ) );
+	faceOffsets.push( new THREE.Vector2( 1, 0 ) );
+	faceOffsets.push( new THREE.Vector2( 2, 0 ) );
+	faceOffsets.push( new THREE.Vector2( 0, 1 ) );
+	faceOffsets.push( new THREE.Vector2( 1, 1 ) );
+	faceOffsets.push( new THREE.Vector2( 2, 1 ) );
+	var yOffset = 0;
+	var textureResolution = size;
+	size = cubeTextureLods[ 0 ].width;
+
+	var offset2 = 0;
+	var c = 4.0;
+	this.numLods = Math.log2( cubeTextureLods[ 0 ].width ) - 2;
+	for ( var i = 0; i < this.numLods; i ++ ) {
+
+		var offset1 = ( textureResolution - textureResolution / c ) * 0.5;
+		if ( size > 16 )
+		c *= 2;
+		var nMips = size > 16 ? 6 : 1;
+		var mipOffsetX = 0;
+		var mipOffsetY = 0;
+		var mipSize = size;
+
+		for ( var j = 0; j < nMips; j ++ ) {
+
+			// Mip Maps
+			for ( var k = 0; k < 6; k ++ ) {
+
+				// 6 Cube Faces
+				var material = this.getShader();
+				material.uniforms[ "envMap" ].value = this.cubeLods[ i ];
+				material.envMap = this.cubeLods[ i ]
+				material.uniforms[ "faceIndex" ].value = k;
+				material.uniforms[ "mapSize" ].value = mipSize;
+				var color = material.uniforms[ "testColor" ].value;
+				//color.copy(testColor[j]);
+				var planeMesh = new THREE.Mesh(
+				new THREE.PlaneGeometry( mipSize, mipSize, 0 ),
+				material );
+				planeMesh.position.x = faceOffsets[ k ].x * mipSize - offset1 + mipOffsetX;
+				planeMesh.position.y = faceOffsets[ k ].y * mipSize - offset1 + offset2 + mipOffsetY;
+				planeMesh.material.side = THREE.DoubleSide;
+				this.scene.add( planeMesh );
+				this.objects.push( planeMesh );
+
+			}
+			mipOffsetY += 1.75 * mipSize;
+			mipOffsetX += 1.25 * mipSize;
+			mipSize /= 2;
+
+		}
+		offset2 += 2 * size;
+		if ( size > 16 )
+		size /= 2;
+
+	}
+
+};
+
+THREE.PMREMCubeUVPacker.prototype = {
+
+	constructor : THREE.PMREMCubeUVPacker,
+
+	update: function( renderer ) {
+
+		var gammaInput = renderer.gammaInput;
+    var gammaOutput = renderer.gammaOutput;
+    renderer.gammaInput = false;
+    renderer.gammaOutput = false;
+
+		renderer.render( this.scene, this.camera, this.CubeUVRenderTarget, true );
+
+    renderer.gammaInput = renderer.gammaInput;
+    renderer.gammaOutput = renderer.gammaOutput;
+	},
+
+  getShader: function() {
+
+    var shaderMaterial = new THREE.ShaderMaterial( {
+
+      uniforms: {
+       	"faceIndex": { type: 'i', value: 0 },
+       	"mapSize": { type: 'f', value: 0 },
+       	"envMap": { type: 't', value: null },
+       	"testColor": { type: 'v3', value: new THREE.Vector3( 1, 1, 1 ) }
+      },
+
+      vertexShader:
+        "precision highp float;\
+         varying vec2 vUv;\
+         void main() {\
+            vUv = uv;\
+            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\
+         }",
+
+      fragmentShader:
+       "precision highp float;\
+        varying vec2 vUv;\
+        uniform samplerCube envMap;\
+        uniform float mapSize;\
+        uniform vec3 testColor;\
+        uniform int faceIndex;\
+        \
+        void main() {\
+          vec3 sampleDirection;\
+          vec2 uv = vUv;\
+          uv = uv * 2.0 - 1.0;\
+          uv.y *= -1.0;\
+          if(faceIndex == 0) {\
+              sampleDirection = normalize(vec3(1.0, uv.y, -uv.x));\
+          }\
+          else if(faceIndex == 1) {\
+              sampleDirection = normalize(vec3(uv.x, 1.0, uv.y));\
+          }\
+          else if(faceIndex == 2) {\
+              sampleDirection = normalize(vec3(uv.x, uv.y, 1.0));\
+          }\
+          else if(faceIndex == 3) {\
+              sampleDirection = normalize(vec3(-1.0, uv.y, uv.x));\
+          }\
+          else if(faceIndex == 4) {\
+              sampleDirection = normalize(vec3(uv.x, -1.0, -uv.y));\
+          }\
+          else {\
+              sampleDirection = normalize(vec3(-uv.x, uv.y, -1.0));\
+          }\
+          vec4 color = envMapTexelToLinear( textureCube( envMap, sampleDirection ) );\
+          gl_FragColor = linearToOutputTexel( color * vec4(testColor, 1.0) );\
+        }",
+
+			blending: THREE.CustomBlending,
+			blendSrc: THREE.OneFactor,
+			blendDst: THREE.ZeroFactor,
+			blendSrcAlpha: THREE.OneFactor,
+			blendDstAlpha: THREE.ZeroFactor,
+			blendEquation: THREE.AddEquation
+    });
+
+		return shaderMaterial;
+
+  }
+
+};

+ 244 - 0
examples/js/pmrem/PMREMGenerator.js

@@ -0,0 +1,244 @@
+/**
+ * @author Prashant Sharma / spidersharma03
+ * @author Ben Houston / bhouston, https://clara.io
+ *
+ * To avoid cube map seams, I create an extra pixel around each face. This way when the cube map is
+ * sampled by an application later(with a little care by sampling the centre of the texel), the extra 1 border
+ *  of pixels makes sure that there is no seams artifacts present. This works perfectly for cubeUV format as
+ *  well where the 6 faces can be arranged in any manner whatsoever.
+ * Code in the beginning of fragment shader's main function does this job for a given resolution.
+ *  Run Scene_PMREM_Test.html in the examples directory to see the sampling from the cube lods generated
+ *  by this class.
+ */
+
+THREE.PMREMGenerator = function( sourceTexture ) {
+
+	this.sourceTexture = sourceTexture;
+  this.resolution = 256; // NODE: 256 is currently hard coded in the glsl code for performance reasons
+
+  var monotonicEncoding = ( sourceTexture.encoding === THREE.LinearEncoding ) ||
+    ( sourceTexture.encoding === THREE.GammaEncoding ) || ( sourceTexture.encoding === THREE.sRGBEncoding );
+
+  this.sourceTexture.minFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter;
+  this.sourceTexture.magFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter;
+  this.sourceTexture.generateMipmaps = this.sourceTexture.generateMipmaps && monotonicEncoding;
+
+	this.cubeLods = [];
+
+	var size = this.resolution;
+  var params = { format: this.sourceTexture.format, magFilter: this.sourceTexture.magFilter, minFilter: this.sourceTexture.minFilter, type: this.sourceTexture.type };
+
+  // how many LODs fit in the given CubeUV Texture.
+	this.numLods = Math.log2( size ) - 2;
+  for ( var i = 0; i < this.numLods; i ++ ) {
+		var renderTarget = new THREE.WebGLRenderTargetCube( size, size, params );
+		renderTarget.texture.generateMipmaps = this.sourceTexture.generateMipmaps;
+    renderTarget.texture.anisotropy = this.sourceTexture.anisotropy;
+    renderTarget.texture.encoding = this.sourceTexture.encoding;
+    renderTarget.texture.minFilter = this.sourceTexture.minFilter;
+    renderTarget.texture.magFilter = this.sourceTexture.magFilter;
+		this.cubeLods.push( renderTarget );
+		size = Math.max( 16, size / 2 );
+	}
+
+	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0.0, 1000 );
+
+  this.shader = this.getShader();
+	this.planeMesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2, 0 ), this.shader );
+	this.planeMesh.material.side = THREE.DoubleSide;
+	this.scene = new THREE.Scene();
+	this.scene.add( this.planeMesh );
+	this.scene.add( this.camera );
+
+	this.shader.uniforms[ "envMap" ].value = this.sourceTexture;
+  this.shader.envMap = this.sourceTexture;
+};
+
+THREE.PMREMGenerator.prototype = {
+
+	constructor : THREE.PMREMGenerator,
+
+  /*
+   * Prashant Sharma / spidersharma03: More thought and work is needed here.
+   * Right now it's a kind of a hack to use the previously convolved map to convolve the current one.
+   * I tried to use the original map to convolve all the lods, but for many textures(specially the high frequency)
+   * even a high number of samples(1024) dosen't lead to satisfactory results.
+   * By using the previous convolved maps, a lower number of samples are generally sufficient(right now 32, which
+   * gives okay results unless we see the reflection very carefully, or zoom in too much), however the math
+   * goes wrong as the distribution function tries to sample a larger area than what it should be. So I simply scaled
+   * the roughness by 0.9(totally empirical) to try to visually match the original result.
+   * The condition "if(i <5)" is also an attemt to make the result match the original result.
+   * This method requires the most amount of thinking I guess. Here is a paper which we could try to implement in future::
+   * http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
+   */
+	update: function( renderer ) {
+
+		this.shader.uniforms[ "envMap" ].value = this.sourceTexture;
+    this.shader.envMap = this.sourceTexture;
+
+    var gammaInput = renderer.gammaInput;
+    var gammaOutput = renderer.gammaOutput;
+    renderer.gammaInput = false;
+    renderer.gammaOutput = false;
+		for ( var i = 0; i < this.numLods; i ++ ) {
+
+			var r = i / ( this.numLods - 1 );
+			this.shader.uniforms[ "roughness" ].value = r * 0.9; // see comment above, pragmatic choice
+			var size = this.cubeLods[ i ].width;
+			this.shader.uniforms[ "mapSize" ].value = size;
+			this.renderToCubeMapTarget( renderer, this.cubeLods[ i ] );
+			if ( i < 5 )
+			this.shader.uniforms[ "envMap" ].value = this.cubeLods[ i ];
+
+		}
+
+    renderer.gammaInput = renderer.gammaInput;
+    renderer.gammaOutput = renderer.gammaOutput;
+
+	},
+
+	renderToCubeMapTarget: function( renderer, renderTarget ) {
+
+		for ( var i = 0; i < 6; i ++ ) {
+		  this.renderToCubeMapTargetFace( renderer, renderTarget, i )
+    }
+
+	},
+
+	renderToCubeMapTargetFace: function( renderer, renderTarget, faceIndex ) {
+		renderTarget.activeCubeFace = faceIndex;
+		this.shader.uniforms[ "faceIndex" ].value = faceIndex;
+		renderer.render( this.scene, this.camera, renderTarget, true );
+
+	},
+
+  getShader: function() {
+
+    return new THREE.ShaderMaterial( {
+
+      uniforms: {
+        "faceIndex": { type: 'i', value: 0 },
+        "roughness": { type: 'f', value: 0.5 },
+        "mapSize": { type: 'f', value: 0.5 },
+        "envMap": { type: 't', value: null },
+        "testColor": { type: 'v3', value: new THREE.Vector3( 1, 1, 1 ) }
+      },
+
+      vertexShader:
+        "varying vec2 vUv;\n\
+        void main() {\n\
+           vUv = uv;\n\
+           gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
+        }",
+
+      fragmentShader:
+        "varying vec2 vUv;\n\
+        uniform int faceIndex;\n\
+        uniform float roughness;\n\
+        uniform samplerCube envMap;\n\
+        uniform float mapSize;\n\
+        uniform vec3 testColor;\n\
+        \n\
+        float rnd(vec2 uv) {\n\
+           return fract(sin(dot(uv, vec2(12.9898, 78.233) * 2.0)) * 43758.5453);\n\
+        }\n\
+        float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\
+           float a = ggxRoughness + 0.0001;\n\
+           a *= a;\n\
+           return ( 2.0 / a - 2.0 );\n\
+        }\n\
+        const float PI = 3.14159265358979;\n\
+        vec3 ImportanceSamplePhong(vec2 uv, mat3 vecSpace, float specPow) {\n\
+           float phi = uv.y * 2.0 * PI;\n\
+           float cosTheta = pow(1.0 - uv.x, 1.0 / (specPow + 1.0));\n\
+           float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n\
+           vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);\n\
+           return vecSpace * sampleDir;\n\
+        }\n\
+        vec3 ImportanceSampleGGX( vec2 uv, mat3 vecSpace, float Roughness )\n\
+        {\n\
+               float a = Roughness * Roughness;\n\
+               float Phi = 2.0 * PI * uv.x;\n\
+               float CosTheta = sqrt( (1.0 - uv.y) / ( 1.0 + (a*a - 1.0) * uv.y ) );\n\
+               float SinTheta = sqrt( 1.0 - CosTheta * CosTheta );\n\
+               return vecSpace * vec3(SinTheta * cos( Phi ), SinTheta * sin( Phi ), CosTheta);\n\
+        }\n\
+        mat3 matrixFromVector(vec3 n) {\n\
+           float a = 1.0 / (1.0 + n.z);\n\
+           float b = -n.x * n.y * a;\n\
+           vec3 b1 = vec3(1.0 - n.x * n.x * a, b, -n.x);\n\
+           vec3 b2 = vec3(b, 1.0 - n.y * n.y * a, -n.y);\n\
+           return mat3(b1, b2, n);\n\
+        }\n\
+        \n\
+        vec4 testColorMap(float Roughness) {\n\
+           vec4 color;\n\
+           if(faceIndex == 0)\n\
+               color = vec4(1.0,0.0,0.0,1.0);\n\
+           else if(faceIndex == 1)\n\
+               color = vec4(0.0,1.0,0.0,1.0);\n\
+           else if(faceIndex == 2)\n\
+               color = vec4(0.0,0.0,1.0,1.0);\n\
+           else if(faceIndex == 3)\n\
+               color = vec4(1.0,1.0,0.0,1.0);\n\
+           else if(faceIndex == 4)\n\
+               color = vec4(0.0,1.0,1.0,1.0);\n\
+           else\n\
+               color = vec4(1.0,0.0,1.0,1.0);\n\
+           color *= ( 1.0 - Roughness );\n\
+           return color;\n\
+        }\n\
+        void main() {\n\
+           vec3 sampleDirection;\n\
+           vec2 uv = vUv*2.0 - 1.0;\n\
+           float offset = -1.0/mapSize;\n\
+           const float a = -1.0;\n\
+           const float b = 1.0;\n\
+           float c = -1.0 + offset;\n\
+           float d = 1.0 - offset;\n\
+           float bminusa = b - a;\n\
+           uv.x = (uv.x - a)/bminusa * d - (uv.x - b)/bminusa * c;\n\
+           uv.y = (uv.y - a)/bminusa * d - (uv.y - b)/bminusa * c;\n\
+           if (faceIndex==0) {\n\
+               sampleDirection = vec3(1.0, -uv.y, -uv.x);\n\
+           }\n\
+           else if (faceIndex==1) {\n\
+               sampleDirection = vec3(-1.0, -uv.y, uv.x);\n\
+           } else if (faceIndex==2) {\n\
+               sampleDirection = vec3(uv.x, 1.0, uv.y);\n\
+           } else if (faceIndex==3) {\n\
+               sampleDirection = vec3(uv.x, -1.0, -uv.y);\n\
+           } else if (faceIndex==4) {\n\
+               sampleDirection = vec3(uv.x, -uv.y, 1.0);\n\
+           } else {\n\
+               sampleDirection = vec3(-uv.x, -uv.y, -1.0);\n\
+           }\n\
+           mat3 vecSpace = matrixFromVector(normalize(sampleDirection));\n\
+           vec3 rgbColor = vec3(0.0);\n\
+           const int NumSamples = 1024;\n\
+           vec3 vect;\n\
+           float weight = 0.0;\n\
+           for(int i=0; i<NumSamples; i++) {\n\
+               float sini = sin(float(i));\n\
+               float cosi = cos(float(i));\n\
+               float rand = rnd(vec2(sini, cosi));\n\
+               vect = ImportanceSampleGGX(vec2(float(i) / float(NumSamples), rand), vecSpace, roughness);\n\
+               float dotProd = dot(vect, normalize(sampleDirection));\n\
+               weight += dotProd;\n\
+               vec3 color = envMapTexelToLinear(textureCube(envMap,vect)).rgb;\n\
+               rgbColor.rgb += color;\n\
+           }\n\
+           rgbColor /= float(NumSamples);\n\
+           //rgbColor = testColorMap( roughness ).rgb;\n\
+           gl_FragColor = linearToOutputTexel( vec4( rgbColor, 1.0 ) );\n\
+        }",
+        blending: THREE.CustomBlending,
+        blendSrc: THREE.OneFactor,
+        blendDst: THREE.ZeroFactor,
+        blendSrcAlpha: THREE.OneFactor,
+        blendDstAlpha: THREE.ZeroFactor,
+        blendEquation: THREE.AddEquation
+      }
+    );
+  }
+};

+ 12 - 15
examples/js/postprocessing/EffectComposer.js

@@ -8,13 +8,14 @@ THREE.EffectComposer = function ( renderer, renderTarget ) {
 
 	if ( renderTarget === undefined ) {
 
-		var pixelRatio = renderer.getPixelRatio();
-
-		var width  = Math.floor( renderer.context.canvas.width  / pixelRatio ) || 1;
-		var height = Math.floor( renderer.context.canvas.height / pixelRatio ) || 1;
-		var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };
-
-		renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
+		var parameters = {
+			minFilter: THREE.LinearFilter,
+			magFilter: THREE.LinearFilter,
+			format: THREE.RGBAFormat,
+			stencilBuffer: false
+		};
+		var size = renderer.getSize();
+		renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters );
 
 	}
 
@@ -108,20 +109,16 @@ THREE.EffectComposer.prototype = {
 
 		if ( renderTarget === undefined ) {
 
-			renderTarget = this.renderTarget1.clone();
-
-			var pixelRatio = this.renderer.getPixelRatio();
+			var size = this.renderer.getSize();
 
-			renderTarget.setSize(
-				Math.floor( this.renderer.context.canvas.width  / pixelRatio ),
-				Math.floor( this.renderer.context.canvas.height / pixelRatio )
-			);
+			renderTarget = this.renderTarget1.clone();
+			renderTarget.setSize( size.width, size.height );
 
 		}
 
 		this.renderTarget1.dispose();
-		this.renderTarget1 = renderTarget;
 		this.renderTarget2.dispose();
+		this.renderTarget1 = renderTarget;
 		this.renderTarget2 = renderTarget.clone();
 
 		this.writeBuffer = this.renderTarget1;

+ 166 - 0
examples/js/postprocessing/ManualMSAARenderPass.js

@@ -0,0 +1,166 @@
+/**
+*
+* Manual Multi-Sample Anti-Aliasing Render Pass
+*
+* @author bhouston / http://clara.io/
+*
+* This manual approach to MSAA re-renders the scene ones for each sample with camera jitter and accumulates the results.
+*
+* References: https://en.wikipedia.org/wiki/Multisample_anti-aliasing
+*
+*/
+
+THREE.ManualMSAARenderPass = function ( scene, camera, params ) {
+
+	this.scene = scene;
+	this.camera = camera;
+
+	this.sampleLevel = 4; // specified as n, where the number of samples is 2^n, so sampleLevel = 4, is 2^4 samples, 16.
+
+	this.params = params || { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
+	this.params.minFilter = THREE.NearestFilter;
+	this.params.maxFilter = THREE.NearestFilter;
+	this.enabled = true;
+
+	this.needsSwap = true;
+
+	if ( THREE.CompositeShader === undefined ) {
+
+		console.error( "THREE.ManualMSAARenderPass relies on THREE.CompositeShader" );
+
+	}
+
+	var compositeShader = THREE.CompositeShader;
+	this.compositeUniforms = THREE.UniformsUtils.clone( compositeShader.uniforms );
+
+	this.materialComposite = new THREE.ShaderMaterial(	{
+
+		uniforms: this.compositeUniforms,
+		vertexShader: compositeShader.vertexShader,
+		fragmentShader: compositeShader.fragmentShader,
+		transparent: true,
+		blending: THREE.CustomBlending,
+		blendSrc: THREE.OneFactor,
+		blendDst: THREE.OneFactor,
+		blendSrcAlpha: THREE.OneFactor,
+		blendDstAlpha: THREE.OneFactor,
+		blendEquation: THREE.AddEquation,
+		depthTest: false,
+		depthWrite: false
+
+	} );
+
+	this.camera2 = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
+	this.scene2	= new THREE.Scene();
+	this.quad2 = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), this.materialComposite );
+	this.scene2.add( this.quad2 );
+
+};
+
+THREE.ManualMSAARenderPass.prototype = {
+
+	constructor: THREE.ManualMSAARenderPass,
+
+	dispose: function() {
+
+		if ( this.sampleRenderTarget ) {
+
+			this.sampleRenderTarget.dispose();
+			this.sampleRenderTarget = null;
+
+		}
+
+	},
+
+
+	setSize: function ( width, height ) {
+
+		this.sampleRenderTarget.setSize( width, height );
+
+	},
+
+	render: function ( renderer, writeBuffer, readBuffer, delta ) {
+
+		var camera = ( this.camera || this.scene.camera );
+		var jitterOffsets = THREE.ManualMSAARenderPass.JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 5 ) ) ];
+
+		if( jitterOffsets.length === 1 ) {
+
+			renderer.render( this.scene, camera, writeBuffer, true );
+			return;
+
+		}
+
+		if ( ! this.sampleRenderTarget ) {
+
+			this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
+
+		}
+
+		var autoClear = renderer.autoClear;
+		renderer.autoClear = false;
+
+		this.compositeUniforms[ "scale" ].value = 1.0 / ( jitterOffsets.length );
+		this.compositeUniforms[ "tForeground" ].value = this.sampleRenderTarget;
+
+		// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
+		for ( var i = 0; i < jitterOffsets.length; i ++ ) {
+
+			// only jitters perspective cameras.	TODO: add support for jittering orthogonal cameras
+			var jitterOffset = jitterOffsets[i];
+			if ( camera.setViewOffset ) {
+				camera.setViewOffset( readBuffer.width, readBuffer.height,
+					jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625,   // 0.0625 = 1 / 16
+					readBuffer.width, readBuffer.height );
+			}
+
+			renderer.render( this.scene, this.camera, this.sampleRenderTarget, true );
+			renderer.render( this.scene2, this.camera2, writeBuffer, ( i === 0 ) );
+
+		}
+
+		// reset jitter to nothing.	TODO: add support for orthogonal cameras
+		if ( camera.setViewOffset ) camera.setViewOffset( undefined, undefined, undefined, undefined, undefined, undefined );
+
+		renderer.autoClear = true;
+
+	}
+
+};
+
+// These jitter vectors are specified in integers because it is easier.
+// I am assuming a [-8,8) integer grid, but it needs to be mapped onto [-0.5,0.5)
+// before being used, thus these integers need to be scaled by 1/16.
+//
+// Sample patterns reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
+THREE.ManualMSAARenderPass.JitterVectors = [
+	[
+		[ 0, 0 ]
+	],
+	[
+		[ 4, 4 ], [ - 4, - 4 ]
+	],
+	[
+		[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]
+	],
+	[
+		[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ],
+		[ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]
+	],
+	[
+		[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ],
+		[ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ],
+		[ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ],
+		[ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]
+	],
+	[
+		[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ],
+		[ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ],
+		[ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ],
+		[ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ],
+		[ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ],
+		[ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ],
+		[ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ],
+		[ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
+	]
+];

+ 121 - 0
examples/js/postprocessing/TAARenderPass.js

@@ -0,0 +1,121 @@
+/**
+ *
+ * Temporal Anti-Aliasing Render Pass
+ *
+ * @author bhouston / http://clara.io/
+ *
+ * When there is no motion in the scene, the TAA render pass accumulates jittered camera samples across frames to create a high quality anti-aliased result.
+ *
+ * References:
+ *
+ * TODO: Add support for motion vector pas so that accumulation of samples across frames can occur on dynamics scenes.
+ *
+ */
+
+THREE.TAARenderPass = function ( scene, camera, params ) {
+
+	if ( THREE.ManualMSAARenderPass === undefined ) {
+
+		console.error( "THREE.TAARenderPass relies on THREE.ManualMSAARenderPass" );
+
+	}
+	THREE.ManualMSAARenderPass.call( this, scene, camera, params );
+
+	this.sampleLevel = 0;
+	this.accumulate = false;
+	
+};
+
+THREE.TAARenderPass.prototype = Object.create( THREE.ManualMSAARenderPass.prototype );
+THREE.TAARenderPass.prototype.constructor = THREE.TAARenderPass;
+THREE.TAARenderPass.JitterVectors = THREE.ManualMSAARenderPass.JitterVectors;
+
+THREE.TAARenderPass.prototype.render = function ( renderer, writeBuffer, readBuffer, delta ) {
+
+	if( ! this.accumulate ) {
+
+			THREE.ManualMSAARenderPass.prototype.render.call( this, renderer, writeBuffer, readBuffer, delta );
+
+			this.accumulateIndex = -1;
+			return;
+
+	}
+
+	var jitterOffsets = THREE.TAARenderPass.JitterVectors[ 5 ];
+
+	var camera = ( this.camera || this.scene.camera );
+
+	if ( ! this.sampleRenderTarget ) {
+
+		this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
+
+	}
+
+	if ( ! this.holdRenderTarget ) {
+
+		this.holdRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
+
+	}
+
+	if( this.accumulate && this.accumulateIndex === -1 ) {
+
+			THREE.ManualMSAARenderPass.prototype.render.call( this, renderer, this.holdRenderTarget, readBuffer, delta );
+
+			this.accumulateIndex = 0;
+
+	}
+
+	var autoClear = renderer.autoClear;
+	renderer.autoClear = false;
+
+	var sampleWeight = 1.0 / ( jitterOffsets.length );
+
+	if( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) {
+
+		this.compositeUniforms[ "scale" ].value = sampleWeight;
+		this.compositeUniforms[ "tForeground" ].value = writeBuffer;
+
+		// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
+		var numSamplesPerFrame = Math.pow( 2, this.sampleLevel );
+		for ( var i = 0; i < numSamplesPerFrame; i ++ ) {
+
+			var j = this.accumulateIndex;
+			// only jitters perspective cameras.	TODO: add support for jittering orthogonal cameras
+			var jitterOffset = jitterOffsets[j];
+			if ( camera.setViewOffset ) {
+				camera.setViewOffset( readBuffer.width, readBuffer.height,
+					jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625,   // 0.0625 = 1 / 16
+					readBuffer.width, readBuffer.height );
+			}
+
+			renderer.render( this.scene, this.camera, writeBuffer, true );
+
+			renderer.render( this.scene2, this.camera2, this.sampleRenderTarget, ( this.accumulateIndex == 0 ) );
+
+			this.accumulateIndex ++;
+			if( this.accumulateIndex >= jitterOffsets.length ) break;
+		}
+
+		// reset jitter to nothing.	TODO: add support for orthogonal cameras
+		if ( camera.setViewOffset ) camera.setViewOffset( undefined, undefined, undefined, undefined, undefined, undefined );
+
+	}
+
+	var accumulationWeight = this.accumulateIndex * sampleWeight;
+
+	if( accumulationWeight > 0 ) {
+		this.compositeUniforms[ "scale" ].value = 1.0;
+		this.compositeUniforms[ "tForeground" ].value = this.sampleRenderTarget;
+		renderer.render( this.scene2, this.camera2, writeBuffer, true );
+	}
+
+	if( accumulationWeight < 1.0 ) {
+		this.compositeUniforms[ "scale" ].value = 1.0 - accumulationWeight;
+		this.compositeUniforms[ "tForeground" ].value = this.holdRenderTarget;
+		renderer.render( this.scene2, this.camera2, writeBuffer, ( accumulationWeight === 0 ) );
+	}
+
+	renderer.autoClear = autoClear;
+
+
+}

+ 48 - 0
examples/js/shaders/CompositeShader.js

@@ -0,0 +1,48 @@
+/**
+ * @author bhouston / http://clara.io/
+ *
+ * Multi-Sample Anti-aliasing shader - for blending together sample buffers
+ */
+
+THREE.CompositeShader = {
+
+	shaderID: "composite",
+
+	uniforms: {
+
+		"tForeground": { type: "t", value: null },
+		"scale": { type: "f", value: 1.0 }
+
+	},
+
+	vertexShader: [
+
+		"varying vec2 vUv;",
+
+		"void main() {",
+
+			"vUv = uv;",
+			"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
+		"}"
+
+	].join( '\n' ),
+
+	fragmentShader: [
+
+		"varying vec2 vUv;",
+
+		"uniform sampler2D tForeground;",
+		"uniform float scale;",
+
+		"void main() {",
+
+			"vec4 foreground = texture2D( tForeground, vUv );",
+
+			"gl_FragColor = foreground * scale;",
+
+		"}"
+
+	].join( '\n' )
+
+};

+ 0 - 1
examples/js/shaders/GammaCorrectionShader.js

@@ -28,7 +28,6 @@ THREE.GammaCorrectionShader = {
 
 	fragmentShader: [
 
-		"#define GAMMA_OUTPUT",
 		"#define GAMMA_FACTOR 2",
 
 		"uniform sampler2D tDiffuse;",

+ 1 - 0
examples/models/gltf/CesiumMan/README.txt

@@ -0,0 +1 @@
+Donated by Cesium for glTF testing.  Please follow the Cesium Trademark Terms and Conditions: https://github.com/AnalyticalGraphicsInc/cesium/wiki/CesiumTrademark.pdf

BIN
examples/models/gltf/CesiumMan/glTF-MaterialsCommon/Cesium_Man.bin


+ 2111 - 0
examples/models/gltf/CesiumMan/glTF-MaterialsCommon/Cesium_Man.gltf

@@ -0,0 +1,2111 @@
+{
+    "accessors": {
+        "IBM_Armature_Cesium_Man-skin": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 0,
+            "componentType": 5126,
+            "count": 19,
+            "type": "MAT4"
+        },
+        "accessor_112": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 448512,
+            "byteStride": 16,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                1,
+                0.98992,
+                0.951076,
+                0.874108
+            ],
+            "min": [
+                0.0100802,
+                0,
+                0,
+                0
+            ],
+            "type": "VEC4"
+        },
+        "accessor_115": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 672768,
+            "byteStride": 16,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                18,
+                18,
+                18,
+                18
+            ],
+            "min": [
+                0,
+                0,
+                0,
+                0
+            ],
+            "type": "VEC4"
+        },
+        "accessor_21": {
+            "bufferView": "bufferView_119",
+            "byteOffset": 0,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 14016,
+            "type": "SCALAR"
+        },
+        "accessor_23": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 0,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                0.180954,
+                0.569137,
+                1.50655
+            ],
+            "min": [
+                -0.131,
+                -0.569137,
+                0
+            ],
+            "type": "VEC3"
+        },
+        "accessor_25": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 168192,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                1,
+                0.999981,
+                0.994445
+            ],
+            "min": [
+                -1,
+                -0.999981,
+                -1
+            ],
+            "type": "VEC3"
+        },
+        "accessor_27": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 336384,
+            "byteStride": 8,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                0.990806,
+                0.98803
+            ],
+            "min": [
+                0.0140794,
+                0.00844598
+            ],
+            "type": "VEC2"
+        },
+        "animAccessor_0": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 1216,
+            "componentType": 5126,
+            "count": 49,
+            "type": "SCALAR"
+        },
+        "animAccessor_1": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 1412,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_10": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 7292,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_11": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 7880,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_12": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 8468,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_13": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 9252,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_14": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 9840,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_15": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 10428,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_16": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 11212,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_17": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 11800,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_18": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 12388,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_19": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 13172,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_2": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 2000,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_20": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 13760,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_21": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 14348,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_22": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 15132,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_23": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 15720,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_24": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 16308,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_25": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 17092,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_26": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 17680,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_27": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 18268,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_28": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 19052,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_29": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 19640,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_3": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 2588,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_30": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 20228,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_31": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 21012,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_32": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 21600,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_33": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 22188,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_34": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 22972,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_35": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 23560,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_36": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 24148,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_37": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 24932,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_38": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 25520,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_39": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 26108,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_4": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 3372,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_40": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 26892,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_41": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 27480,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_42": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 28068,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_43": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 28852,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_44": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 29440,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_45": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 30028,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_46": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 30812,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_47": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 31400,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_48": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 31988,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_49": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 32772,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_5": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 3960,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_50": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 33360,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_51": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 33948,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_52": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 34732,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_53": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 35320,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_54": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 35908,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_55": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 36692,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_56": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 37280,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_57": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 37868,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_6": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 4548,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_7": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 5332,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_8": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 5920,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_9": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 6508,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        }
+    },
+    "animations": {
+        "animation_0": {
+            "channels": [
+                {
+                    "sampler": "animation_0_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_0_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_0_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_3",
+                "scale": "animAccessor_1",
+                "translation": "animAccessor_2"
+            },
+            "samplers": {
+                "animation_0_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_0_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_0_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_1": {
+            "channels": [
+                {
+                    "sampler": "animation_1_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_1_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_1_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_6",
+                "scale": "animAccessor_4",
+                "translation": "animAccessor_5"
+            },
+            "samplers": {
+                "animation_1_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_1_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_1_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_10": {
+            "channels": [
+                {
+                    "sampler": "animation_10_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__3_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_10_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__3_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_10_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__3_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_9",
+                "scale": "animAccessor_7",
+                "translation": "animAccessor_8"
+            },
+            "samplers": {
+                "animation_10_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_10_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_10_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_11": {
+            "channels": [
+                {
+                    "sampler": "animation_11_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_11_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_11_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_12",
+                "scale": "animAccessor_10",
+                "translation": "animAccessor_11"
+            },
+            "samplers": {
+                "animation_11_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_11_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_11_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_12": {
+            "channels": [
+                {
+                    "sampler": "animation_12_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_12_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_12_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_15",
+                "scale": "animAccessor_13",
+                "translation": "animAccessor_14"
+            },
+            "samplers": {
+                "animation_12_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_12_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_12_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_13": {
+            "channels": [
+                {
+                    "sampler": "animation_13_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_3",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_13_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_3",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_13_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_3",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_18",
+                "scale": "animAccessor_16",
+                "translation": "animAccessor_17"
+            },
+            "samplers": {
+                "animation_13_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_13_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_13_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_14": {
+            "channels": [
+                {
+                    "sampler": "animation_14_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_5",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_14_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_5",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_14_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_5",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_21",
+                "scale": "animAccessor_19",
+                "translation": "animAccessor_20"
+            },
+            "samplers": {
+                "animation_14_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_14_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_14_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_15": {
+            "channels": [
+                {
+                    "sampler": "animation_15_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_15_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_15_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_24",
+                "scale": "animAccessor_22",
+                "translation": "animAccessor_23"
+            },
+            "samplers": {
+                "animation_15_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_15_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_15_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_16": {
+            "channels": [
+                {
+                    "sampler": "animation_16_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_16_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_16_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_27",
+                "scale": "animAccessor_25",
+                "translation": "animAccessor_26"
+            },
+            "samplers": {
+                "animation_16_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_16_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_16_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_17": {
+            "channels": [
+                {
+                    "sampler": "animation_17_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_3",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_17_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_3",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_17_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_3",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_30",
+                "scale": "animAccessor_28",
+                "translation": "animAccessor_29"
+            },
+            "samplers": {
+                "animation_17_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_17_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_17_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_18": {
+            "channels": [
+                {
+                    "sampler": "animation_18_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_5",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_18_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_5",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_18_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_5",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_33",
+                "scale": "animAccessor_31",
+                "translation": "animAccessor_32"
+            },
+            "samplers": {
+                "animation_18_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_18_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_18_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_2": {
+            "channels": [
+                {
+                    "sampler": "animation_2_scale_sampler",
+                    "target": {
+                        "id": "torso_joint_3",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_2_translation_sampler",
+                    "target": {
+                        "id": "torso_joint_3",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_2_rotation_sampler",
+                    "target": {
+                        "id": "torso_joint_3",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_36",
+                "scale": "animAccessor_34",
+                "translation": "animAccessor_35"
+            },
+            "samplers": {
+                "animation_2_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_2_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_2_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_3": {
+            "channels": [
+                {
+                    "sampler": "animation_3_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_3_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_3_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_39",
+                "scale": "animAccessor_37",
+                "translation": "animAccessor_38"
+            },
+            "samplers": {
+                "animation_3_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_3_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_3_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_4": {
+            "channels": [
+                {
+                    "sampler": "animation_4_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_4_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_4_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_42",
+                "scale": "animAccessor_40",
+                "translation": "animAccessor_41"
+            },
+            "samplers": {
+                "animation_4_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_4_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_4_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_5": {
+            "channels": [
+                {
+                    "sampler": "animation_5_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__4_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_5_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__4_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_5_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__4_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_45",
+                "scale": "animAccessor_43",
+                "translation": "animAccessor_44"
+            },
+            "samplers": {
+                "animation_5_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_5_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_5_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_6": {
+            "channels": [
+                {
+                    "sampler": "animation_6_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__3_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_6_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__3_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_6_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__3_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_48",
+                "scale": "animAccessor_46",
+                "translation": "animAccessor_47"
+            },
+            "samplers": {
+                "animation_6_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_6_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_6_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_7": {
+            "channels": [
+                {
+                    "sampler": "animation_7_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__2_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_7_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__2_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_7_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__2_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_51",
+                "scale": "animAccessor_49",
+                "translation": "animAccessor_50"
+            },
+            "samplers": {
+                "animation_7_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_7_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_7_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_8": {
+            "channels": [
+                {
+                    "sampler": "animation_8_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_8_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_8_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_54",
+                "scale": "animAccessor_52",
+                "translation": "animAccessor_53"
+            },
+            "samplers": {
+                "animation_8_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_8_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_8_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_9": {
+            "channels": [
+                {
+                    "sampler": "animation_9_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__2_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_9_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__2_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_9_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__2_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_57",
+                "scale": "animAccessor_55",
+                "translation": "animAccessor_56"
+            },
+            "samplers": {
+                "animation_9_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_9_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_9_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        }
+    },
+    "asset": {
+        "generator": "collada2gltf@cf6371beb0bdc18ba603378d5e40c966da53d385",
+        "premultipliedAlpha": true,
+        "profile": {
+            "api": "WebGL",
+            "version": "1.0.2"
+        },
+        "version": "1.0"
+    },
+    "bufferViews": {
+        "bufferView_118": {
+            "buffer": "Cesium_Man",
+            "byteLength": 38652,
+            "byteOffset": 0
+        },
+        "bufferView_119": {
+            "buffer": "Cesium_Man",
+            "byteLength": 28032,
+            "byteOffset": 38652,
+            "target": 34963
+        },
+        "bufferView_120": {
+            "buffer": "Cesium_Man",
+            "byteLength": 897024,
+            "byteOffset": 66684,
+            "target": 34962
+        }
+    },
+    "buffers": {
+        "Cesium_Man": {
+            "byteLength": 963708,
+            "type": "arraybuffer",
+            "uri": "Cesium_Man.bin"
+        }
+    },
+    "extensionsUsed": [
+        "KHR_materials_common"
+    ],
+    "images": {
+        "Cesium_Man_jpg": {
+            "name": "Cesium_Man_jpg",
+            "uri": "Cesium_Man.jpg"
+        }
+    },
+    "materials": {
+        "Cesium_Man-effect": {
+            "extensions": {
+                "KHR_materials_common": {
+                    "doubleSided": false,
+                    "jointCount": 19,
+                    "technique": "PHONG",
+                    "transparent": false,
+                    "values": {
+                        "ambient": [
+                            0,
+                            0,
+                            0,
+                            1
+                        ],
+                        "diffuse": "texture_Cesium_Man_jpg",
+                        "emission": [
+                            0,
+                            0,
+                            0,
+                            1
+                        ],
+                        "shininess": 256,
+                        "specular": [
+                            0.1,
+                            0.1,
+                            0.1,
+                            1
+                        ]
+                    }
+                }
+            },
+            "name": "Cesium_Man"
+        }
+    },
+    "meshes": {
+        "Cesium_Man-mesh": {
+            "name": "Cesium_Man",
+            "primitives": [
+                {
+                    "attributes": {
+                        "JOINT": "accessor_115",
+                        "NORMAL": "accessor_25",
+                        "POSITION": "accessor_23",
+                        "TEXCOORD_0": "accessor_27",
+                        "WEIGHT": "accessor_112"
+                    },
+                    "indices": "accessor_21",
+                    "material": "Cesium_Man-effect",
+                    "mode": 4
+                }
+            ]
+        }
+    },
+    "nodes": {
+        "Armature": {
+            "children": [
+                "Skeleton_torso_joint_1"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Armature"
+        },
+        "Cesium_Man": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "meshes": [
+                "Cesium_Man-mesh"
+            ],
+            "name": "Cesium_Man",
+            "skeletons": [
+                "Skeleton_torso_joint_1"
+            ],
+            "skin": "Armature_Cesium_Man-skin"
+        },
+        "Skeleton_arm_joint_L__2_": {
+            "children": [],
+            "jointName": "Skeleton_arm_joint_L__2_",
+            "name": "Skeleton_arm_joint_L__2_",
+            "rotation": [
+                -0.00611917,
+                0.0423255,
+                0.0787759,
+                0.995975
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                1.49012e-008,
+                0.187791,
+                5.96046e-008
+            ]
+        },
+        "Skeleton_arm_joint_L__3_": {
+            "children": [
+                "Skeleton_arm_joint_L__2_"
+            ],
+            "jointName": "Skeleton_arm_joint_L__3_",
+            "name": "Skeleton_arm_joint_L__3_",
+            "rotation": [
+                0.0139609,
+                0.129373,
+                0.252206,
+                0.958885
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                1.16415e-010,
+                0.242009,
+                0
+            ]
+        },
+        "Skeleton_arm_joint_L__4_": {
+            "children": [
+                "Skeleton_arm_joint_L__3_"
+            ],
+            "jointName": "Skeleton_arm_joint_L__4_",
+            "name": "Skeleton_arm_joint_L__4_",
+            "rotation": [
+                0.679733,
+                0.689686,
+                -0.226972,
+                -0.103832
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0.0910136,
+                1.41859e-005,
+                -5.80549e-005
+            ]
+        },
+        "Skeleton_arm_joint_R": {
+            "children": [
+                "Skeleton_arm_joint_R__2_"
+            ],
+            "jointName": "Skeleton_arm_joint_R",
+            "name": "Skeleton_arm_joint_R",
+            "rotation": [
+                -0.296443,
+                -0.0315103,
+                0.652255,
+                0.696916
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -0.0909878,
+                6.25998e-005,
+                -6.53267e-005
+            ]
+        },
+        "Skeleton_arm_joint_R__2_": {
+            "children": [
+                "Skeleton_arm_joint_R__3_"
+            ],
+            "jointName": "Skeleton_arm_joint_R__2_",
+            "name": "Skeleton_arm_joint_R__2_",
+            "rotation": [
+                -0.188793,
+                0.915707,
+                -0.167809,
+                -0.312534
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0,
+                0.242008,
+                -5.96046e-008
+            ]
+        },
+        "Skeleton_arm_joint_R__3_": {
+            "children": [],
+            "jointName": "Skeleton_arm_joint_R__3_",
+            "name": "Skeleton_arm_joint_R__3_",
+            "rotation": [
+                0.0586139,
+                -0.263777,
+                -0.0522685,
+                0.961381
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0,
+                0.187792,
+                0
+            ]
+        },
+        "Skeleton_neck_joint_1": {
+            "children": [
+                "Skeleton_neck_joint_2"
+            ],
+            "jointName": "Skeleton_neck_joint_1",
+            "name": "Skeleton_neck_joint_1",
+            "rotation": [
+                0.66063,
+                -8.34443e-005,
+                -7.10926e-005,
+                0.750712
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -8.84756e-009,
+                5.96046e-008,
+                0.0648366
+            ]
+        },
+        "Skeleton_neck_joint_2": {
+            "children": [],
+            "jointName": "Skeleton_neck_joint_2",
+            "name": "Skeleton_neck_joint_2",
+            "rotation": [
+                2.55261e-006,
+                0.99969,
+                -0.0248797,
+                -4.32993e-007
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0,
+                0.0520397,
+                0
+            ]
+        },
+        "Skeleton_torso_joint_1": {
+            "children": [
+                "Skeleton_torso_joint_2",
+                "leg_joint_L_1",
+                "leg_joint_R_1"
+            ],
+            "jointName": "Skeleton_torso_joint_1",
+            "name": "Skeleton_torso_joint_1",
+            "rotation": [
+                0.0267947,
+                0.0267326,
+                0.706561,
+                0.706639
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -3.35276e-008,
+                0.00499989,
+                0.679
+            ]
+        },
+        "Skeleton_torso_joint_2": {
+            "children": [
+                "torso_joint_3"
+            ],
+            "jointName": "Skeleton_torso_joint_2",
+            "name": "Skeleton_torso_joint_2",
+            "rotation": [
+                0.657252,
+                0.000179693,
+                0.00010428,
+                0.753671
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -1.02445e-008,
+                1.49012e-008,
+                0.145417
+            ]
+        },
+        "leg_joint_L_1": {
+            "children": [
+                "leg_joint_L_2"
+            ],
+            "jointName": "leg_joint_L_1",
+            "name": "leg_joint_L_1",
+            "rotation": [
+                0.24757,
+                -0.577568,
+                0.747914,
+                -0.213889
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0.0680367,
+                -0.0285187,
+                -0.0629628
+            ]
+        },
+        "leg_joint_L_2": {
+            "children": [
+                "leg_joint_L_3"
+            ],
+            "jointName": "leg_joint_L_2",
+            "name": "leg_joint_L_2",
+            "rotation": [
+                -0.209028,
+                0.32989,
+                0.0555992,
+                0.918906
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                3.72529e-009,
+                0.266113,
+                1.49012e-008
+            ]
+        },
+        "leg_joint_L_3": {
+            "children": [
+                "leg_joint_L_5"
+            ],
+            "jointName": "leg_joint_L_3",
+            "name": "leg_joint_L_3",
+            "rotation": [
+                -0.84774,
+                0.00425408,
+                0.00949198,
+                0.530311
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -7.45058e-009,
+                0.275824,
+                5.58794e-009
+            ]
+        },
+        "leg_joint_L_5": {
+            "children": [],
+            "jointName": "leg_joint_L_5",
+            "name": "leg_joint_L_5",
+            "rotation": [
+                0.0265735,
+                -0.320144,
+                0.944545,
+                0.0680896
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -0.00234652,
+                -0.0661733,
+                0.0278568
+            ]
+        },
+        "leg_joint_R_1": {
+            "children": [
+                "leg_joint_R_2"
+            ],
+            "jointName": "leg_joint_R_1",
+            "name": "leg_joint_R_1",
+            "rotation": [
+                -0.066427,
+                -0.611501,
+                0.785027,
+                0.0733875
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -0.068042,
+                -0.0285702,
+                -0.0629496
+            ]
+        },
+        "leg_joint_R_2": {
+            "children": [
+                "leg_joint_R_3"
+            ],
+            "jointName": "leg_joint_R_2",
+            "name": "leg_joint_R_2",
+            "rotation": [
+                -0.216291,
+                -0.124306,
+                -0.00157521,
+                0.968382
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0,
+                0.266111,
+                0
+            ]
+        },
+        "leg_joint_R_3": {
+            "children": [
+                "leg_joint_R_5"
+            ],
+            "jointName": "leg_joint_R_3",
+            "name": "leg_joint_R_3",
+            "rotation": [
+                -0.847274,
+                0.029564,
+                0.020868,
+                0.529922
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0,
+                0.275825,
+                -1.11759e-008
+            ]
+        },
+        "leg_joint_R_5": {
+            "children": [],
+            "jointName": "leg_joint_R_5",
+            "name": "leg_joint_R_5",
+            "rotation": [
+                -0.0372644,
+                -0.319313,
+                0.946053,
+                -0.040415
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -0.00145848,
+                -0.0661988,
+                0.0278567
+            ]
+        },
+        "node_21": {
+            "children": [
+                "Armature",
+                "Cesium_Man"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                0,
+                -1,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Y_UP_Transform"
+        },
+        "torso_joint_3": {
+            "children": [
+                "Skeleton_neck_joint_1",
+                "Skeleton_arm_joint_L__4_",
+                "Skeleton_arm_joint_R"
+            ],
+            "jointName": "torso_joint_3",
+            "name": "torso_joint_3",
+            "rotation": [
+                -0.622604,
+                -1.67835e-005,
+                3.1824e-006,
+                0.782537
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                4.65661e-010,
+                0.250517,
+                3.72529e-009
+            ]
+        }
+    },
+    "samplers": {
+        "sampler_0": {
+            "magFilter": 9729,
+            "minFilter": 9729,
+            "wrapS": 10497,
+            "wrapT": 10497
+        }
+    },
+    "scene": "defaultScene",
+    "scenes": {
+        "defaultScene": {
+            "nodes": [
+                "node_21"
+            ]
+        }
+    },
+    "skins": {
+        "Armature_Cesium_Man-skin": {
+            "bindShapeMatrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "inverseBindMatrices": "IBM_Armature_Cesium_Man-skin",
+            "jointNames": [
+                "Skeleton_torso_joint_1",
+                "Skeleton_torso_joint_2",
+                "torso_joint_3",
+                "Skeleton_neck_joint_1",
+                "Skeleton_neck_joint_2",
+                "Skeleton_arm_joint_L__4_",
+                "Skeleton_arm_joint_R",
+                "Skeleton_arm_joint_L__3_",
+                "Skeleton_arm_joint_R__2_",
+                "Skeleton_arm_joint_L__2_",
+                "Skeleton_arm_joint_R__3_",
+                "leg_joint_L_1",
+                "leg_joint_R_1",
+                "leg_joint_L_2",
+                "leg_joint_R_2",
+                "leg_joint_L_3",
+                "leg_joint_R_3",
+                "leg_joint_L_5",
+                "leg_joint_R_5"
+            ],
+            "name": "Armature"
+        }
+    },
+    "textures": {
+        "texture_Cesium_Man_jpg": {
+            "format": 6408,
+            "internalFormat": 6408,
+            "sampler": "sampler_0",
+            "source": "Cesium_Man_jpg",
+            "target": 3553,
+            "type": 5121
+        }
+    }
+}

BIN
examples/models/gltf/CesiumMan/glTF-MaterialsCommon/Cesium_Man.jpg


BIN
examples/models/gltf/CesiumMan/glTF/Cesium_Man.bin


+ 2207 - 0
examples/models/gltf/CesiumMan/glTF/Cesium_Man.gltf

@@ -0,0 +1,2207 @@
+{
+    "accessors": {
+        "IBM_Armature_Cesium_Man-skin": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 0,
+            "componentType": 5126,
+            "count": 19,
+            "type": "MAT4"
+        },
+        "accessor_112": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 448512,
+            "byteStride": 16,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                1,
+                0.9899199604988098,
+                0.9510759711265564,
+                0.8741080164909363
+            ],
+            "min": [
+                0.01008019968867302,
+                0,
+                0,
+                0
+            ],
+            "type": "VEC4"
+        },
+        "accessor_115": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 672768,
+            "byteStride": 16,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                18,
+                18,
+                18,
+                18
+            ],
+            "min": [
+                0,
+                0,
+                0,
+                0
+            ],
+            "type": "VEC4"
+        },
+        "accessor_21": {
+            "bufferView": "bufferView_119",
+            "byteOffset": 0,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 14016,
+            "type": "SCALAR"
+        },
+        "accessor_23": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 0,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                0.1809539943933487,
+                0.5691369771957397,
+                1.5065499544143677
+            ],
+            "min": [
+                -0.13100001215934753,
+                -0.5691369771957397,
+                0
+            ],
+            "type": "VEC3"
+        },
+        "accessor_25": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 168192,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                1,
+                0.9999809861183167,
+                0.9944450259208679
+            ],
+            "min": [
+                -1,
+                -0.9999809861183167,
+                -1
+            ],
+            "type": "VEC3"
+        },
+        "accessor_27": {
+            "bufferView": "bufferView_120",
+            "byteOffset": 336384,
+            "byteStride": 8,
+            "componentType": 5126,
+            "count": 14016,
+            "max": [
+                0.990805983543396,
+                0.9880298972129822
+            ],
+            "min": [
+                0.014079400338232517,
+                0.008445978164672852
+            ],
+            "type": "VEC2"
+        },
+        "animAccessor_0": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 1216,
+            "componentType": 5126,
+            "count": 49,
+            "type": "SCALAR"
+        },
+        "animAccessor_1": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 1412,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_10": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 7292,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_11": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 7880,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_12": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 8468,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_13": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 9252,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_14": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 9840,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_15": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 10428,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_16": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 11212,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_17": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 11800,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_18": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 12388,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_19": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 13172,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_2": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 2000,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_20": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 13760,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_21": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 14348,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_22": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 15132,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_23": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 15720,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_24": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 16308,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_25": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 17092,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_26": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 17680,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_27": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 18268,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_28": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 19052,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_29": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 19640,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_3": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 2588,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_30": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 20228,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_31": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 21012,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_32": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 21600,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_33": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 22188,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_34": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 22972,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_35": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 23560,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_36": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 24148,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_37": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 24932,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_38": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 25520,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_39": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 26108,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_4": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 3372,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_40": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 26892,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_41": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 27480,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_42": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 28068,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_43": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 28852,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_44": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 29440,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_45": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 30028,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_46": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 30812,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_47": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 31400,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_48": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 31988,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_49": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 32772,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_5": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 3960,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_50": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 33360,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_51": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 33948,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_52": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 34732,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_53": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 35320,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_54": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 35908,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_55": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 36692,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_56": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 37280,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_57": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 37868,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_6": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 4548,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        },
+        "animAccessor_7": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 5332,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_8": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 5920,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC3"
+        },
+        "animAccessor_9": {
+            "bufferView": "bufferView_118",
+            "byteOffset": 6508,
+            "componentType": 5126,
+            "count": 49,
+            "type": "VEC4"
+        }
+    },
+    "animations": {
+        "animation_0": {
+            "channels": [
+                {
+                    "sampler": "animation_0_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_0_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_0_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_3",
+                "scale": "animAccessor_1",
+                "translation": "animAccessor_2"
+            },
+            "samplers": {
+                "animation_0_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_0_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_0_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_1": {
+            "channels": [
+                {
+                    "sampler": "animation_1_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_1_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_1_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_torso_joint_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_6",
+                "scale": "animAccessor_4",
+                "translation": "animAccessor_5"
+            },
+            "samplers": {
+                "animation_1_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_1_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_1_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_10": {
+            "channels": [
+                {
+                    "sampler": "animation_10_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__3_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_10_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__3_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_10_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__3_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_9",
+                "scale": "animAccessor_7",
+                "translation": "animAccessor_8"
+            },
+            "samplers": {
+                "animation_10_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_10_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_10_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_11": {
+            "channels": [
+                {
+                    "sampler": "animation_11_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_11_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_11_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_12",
+                "scale": "animAccessor_10",
+                "translation": "animAccessor_11"
+            },
+            "samplers": {
+                "animation_11_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_11_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_11_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_12": {
+            "channels": [
+                {
+                    "sampler": "animation_12_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_12_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_12_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_15",
+                "scale": "animAccessor_13",
+                "translation": "animAccessor_14"
+            },
+            "samplers": {
+                "animation_12_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_12_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_12_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_13": {
+            "channels": [
+                {
+                    "sampler": "animation_13_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_3",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_13_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_3",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_13_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_3",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_18",
+                "scale": "animAccessor_16",
+                "translation": "animAccessor_17"
+            },
+            "samplers": {
+                "animation_13_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_13_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_13_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_14": {
+            "channels": [
+                {
+                    "sampler": "animation_14_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_L_5",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_14_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_5",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_14_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_L_5",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_21",
+                "scale": "animAccessor_19",
+                "translation": "animAccessor_20"
+            },
+            "samplers": {
+                "animation_14_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_14_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_14_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_15": {
+            "channels": [
+                {
+                    "sampler": "animation_15_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_15_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_15_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_24",
+                "scale": "animAccessor_22",
+                "translation": "animAccessor_23"
+            },
+            "samplers": {
+                "animation_15_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_15_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_15_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_16": {
+            "channels": [
+                {
+                    "sampler": "animation_16_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_16_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_16_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_27",
+                "scale": "animAccessor_25",
+                "translation": "animAccessor_26"
+            },
+            "samplers": {
+                "animation_16_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_16_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_16_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_17": {
+            "channels": [
+                {
+                    "sampler": "animation_17_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_3",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_17_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_3",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_17_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_3",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_30",
+                "scale": "animAccessor_28",
+                "translation": "animAccessor_29"
+            },
+            "samplers": {
+                "animation_17_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_17_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_17_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_18": {
+            "channels": [
+                {
+                    "sampler": "animation_18_scale_sampler",
+                    "target": {
+                        "id": "leg_joint_R_5",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_18_translation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_5",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_18_rotation_sampler",
+                    "target": {
+                        "id": "leg_joint_R_5",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_33",
+                "scale": "animAccessor_31",
+                "translation": "animAccessor_32"
+            },
+            "samplers": {
+                "animation_18_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_18_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_18_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_2": {
+            "channels": [
+                {
+                    "sampler": "animation_2_scale_sampler",
+                    "target": {
+                        "id": "torso_joint_3",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_2_translation_sampler",
+                    "target": {
+                        "id": "torso_joint_3",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_2_rotation_sampler",
+                    "target": {
+                        "id": "torso_joint_3",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_36",
+                "scale": "animAccessor_34",
+                "translation": "animAccessor_35"
+            },
+            "samplers": {
+                "animation_2_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_2_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_2_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_3": {
+            "channels": [
+                {
+                    "sampler": "animation_3_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_1",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_3_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_1",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_3_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_1",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_39",
+                "scale": "animAccessor_37",
+                "translation": "animAccessor_38"
+            },
+            "samplers": {
+                "animation_3_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_3_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_3_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_4": {
+            "channels": [
+                {
+                    "sampler": "animation_4_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_2",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_4_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_2",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_4_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_neck_joint_2",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_42",
+                "scale": "animAccessor_40",
+                "translation": "animAccessor_41"
+            },
+            "samplers": {
+                "animation_4_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_4_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_4_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_5": {
+            "channels": [
+                {
+                    "sampler": "animation_5_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__4_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_5_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__4_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_5_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__4_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_45",
+                "scale": "animAccessor_43",
+                "translation": "animAccessor_44"
+            },
+            "samplers": {
+                "animation_5_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_5_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_5_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_6": {
+            "channels": [
+                {
+                    "sampler": "animation_6_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__3_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_6_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__3_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_6_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__3_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_48",
+                "scale": "animAccessor_46",
+                "translation": "animAccessor_47"
+            },
+            "samplers": {
+                "animation_6_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_6_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_6_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_7": {
+            "channels": [
+                {
+                    "sampler": "animation_7_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__2_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_7_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__2_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_7_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_L__2_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_51",
+                "scale": "animAccessor_49",
+                "translation": "animAccessor_50"
+            },
+            "samplers": {
+                "animation_7_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_7_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_7_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_8": {
+            "channels": [
+                {
+                    "sampler": "animation_8_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_8_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_8_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_54",
+                "scale": "animAccessor_52",
+                "translation": "animAccessor_53"
+            },
+            "samplers": {
+                "animation_8_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_8_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_8_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        },
+        "animation_9": {
+            "channels": [
+                {
+                    "sampler": "animation_9_scale_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__2_",
+                        "path": "scale"
+                    }
+                },
+                {
+                    "sampler": "animation_9_translation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__2_",
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": "animation_9_rotation_sampler",
+                    "target": {
+                        "id": "Skeleton_arm_joint_R__2_",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_57",
+                "scale": "animAccessor_55",
+                "translation": "animAccessor_56"
+            },
+            "samplers": {
+                "animation_9_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                },
+                "animation_9_scale_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "scale"
+                },
+                "animation_9_translation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "translation"
+                }
+            }
+        }
+    },
+    "asset": {
+        "generator": "collada2gltf@",
+        "premultipliedAlpha": true,
+        "profile": {
+            "api": "WebGL",
+            "version": "1.0.2"
+        },
+        "version": "1.0"
+    },
+    "bufferViews": {
+        "bufferView_118": {
+            "buffer": "Cesium_Man",
+            "byteLength": 38652,
+            "byteOffset": 0
+        },
+        "bufferView_119": {
+            "buffer": "Cesium_Man",
+            "byteLength": 28032,
+            "byteOffset": 38652,
+            "target": 34963
+        },
+        "bufferView_120": {
+            "buffer": "Cesium_Man",
+            "byteLength": 897024,
+            "byteOffset": 66684,
+            "target": 34962
+        }
+    },
+    "buffers": {
+        "Cesium_Man": {
+            "byteLength": 963708,
+            "type": "arraybuffer",
+            "uri": "Cesium_Man.bin"
+        }
+    },
+    "images": {
+        "Cesium_Man_jpg": {
+            "name": "Cesium_Man_jpg",
+            "uri": "Cesium_Man.jpg"
+        }
+    },
+    "materials": {
+        "Cesium_Man-effect": {
+            "name": "Cesium_Man",
+            "technique": "technique0",
+            "values": {
+                "ambient": [
+                    0,
+                    0,
+                    0,
+                    1
+                ],
+                "diffuse": "texture_Cesium_Man_jpg",
+                "emission": [
+                    0,
+                    0,
+                    0,
+                    1
+                ],
+                "shininess": 256,
+                "specular": [
+                    0.10000000149011612,
+                    0.10000000149011612,
+                    0.10000000149011612,
+                    1
+                ]
+            }
+        }
+    },
+    "meshes": {
+        "Cesium_Man-mesh": {
+            "name": "Cesium_Man",
+            "primitives": [
+                {
+                    "attributes": {
+                        "JOINT": "accessor_115",
+                        "NORMAL": "accessor_25",
+                        "POSITION": "accessor_23",
+                        "TEXCOORD_0": "accessor_27",
+                        "WEIGHT": "accessor_112"
+                    },
+                    "indices": "accessor_21",
+                    "material": "Cesium_Man-effect",
+                    "mode": 4
+                }
+            ]
+        }
+    },
+    "nodes": {
+        "Armature": {
+            "children": [
+                "Skeleton_torso_joint_1"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Armature"
+        },
+        "Cesium_Man": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "meshes": [
+                "Cesium_Man-mesh"
+            ],
+            "name": "Cesium_Man",
+            "skeletons": [
+                "Skeleton_torso_joint_1"
+            ],
+            "skin": "Armature_Cesium_Man-skin"
+        },
+        "Skeleton_arm_joint_L__2_": {
+            "children": [],
+            "jointName": "Skeleton_arm_joint_L__2_",
+            "name": "Skeleton_arm_joint_L__2_",
+            "rotation": [
+                -0.006119159981608391,
+                0.04232554882764816,
+                0.07877608388662338,
+                0.995974600315094
+            ],
+            "scale": [
+                1.000000238418579,
+                1.000000238418579,
+                0.9999998211860657
+            ],
+            "translation": [
+                0.000000014901200273698123,
+                0.18779200315475464,
+                0.0000000596045985901128
+            ]
+        },
+        "Skeleton_arm_joint_L__3_": {
+            "children": [
+                "Skeleton_arm_joint_L__2_"
+            ],
+            "jointName": "Skeleton_arm_joint_L__3_",
+            "name": "Skeleton_arm_joint_L__3_",
+            "rotation": [
+                0.013960931450128555,
+                0.12937265634536743,
+                0.2522056996822357,
+                0.9588848352432251
+            ],
+            "scale": [
+                1.0000001192092896,
+                1.0000001192092896,
+                1.0000003576278687
+            ],
+            "translation": [
+                0.00000000011641500263781523,
+                0.2420089989900589,
+                0
+            ]
+        },
+        "Skeleton_arm_joint_L__4_": {
+            "children": [
+                "Skeleton_arm_joint_L__3_"
+            ],
+            "jointName": "Skeleton_arm_joint_L__4_",
+            "name": "Skeleton_arm_joint_L__4_",
+            "rotation": [
+                0.6797326803207397,
+                0.6896856427192688,
+                -0.22697189450263977,
+                -0.10383138060569763
+            ],
+            "scale": [
+                1.0000005960464478,
+                1,
+                1.0000001192092896
+            ],
+            "translation": [
+                0.091013602912426,
+                0.000014185899999574758,
+                -0.000058054902183357626
+            ]
+        },
+        "Skeleton_arm_joint_R": {
+            "children": [
+                "Skeleton_arm_joint_R__2_"
+            ],
+            "jointName": "Skeleton_arm_joint_R",
+            "name": "Skeleton_arm_joint_R",
+            "rotation": [
+                -0.2964428663253784,
+                -0.03151031211018562,
+                0.652255117893219,
+                0.6969161033630371
+            ],
+            "scale": [
+                1,
+                0.9999998807907104,
+                0.9999996423721313
+            ],
+            "translation": [
+                -0.09098780155181885,
+                0.00006259980000322685,
+                -0.00006532669794978574
+            ]
+        },
+        "Skeleton_arm_joint_R__2_": {
+            "children": [
+                "Skeleton_arm_joint_R__3_"
+            ],
+            "jointName": "Skeleton_arm_joint_R__2_",
+            "name": "Skeleton_arm_joint_R__2_",
+            "rotation": [
+                -0.18879348039627075,
+                0.9157071113586426,
+                -0.1678091138601303,
+                -0.3125341236591339
+            ],
+            "scale": [
+                1.0000001192092896,
+                0.9999996423721313,
+                1.0000001192092896
+            ],
+            "translation": [
+                0,
+                0.2420080006122589,
+                -0.0000000596045985901128
+            ]
+        },
+        "Skeleton_arm_joint_R__3_": {
+            "children": [],
+            "jointName": "Skeleton_arm_joint_R__3_",
+            "name": "Skeleton_arm_joint_R__3_",
+            "rotation": [
+                0.05861387029290199,
+                -0.263776570558548,
+                -0.05226854607462883,
+                0.9613814949989319
+            ],
+            "scale": [
+                1.0000003576278687,
+                1.0000001192092896,
+                1.0000001192092896
+            ],
+            "translation": [
+                0,
+                0.18779200315475464,
+                0
+            ]
+        },
+        "Skeleton_neck_joint_1": {
+            "children": [
+                "Skeleton_neck_joint_2"
+            ],
+            "jointName": "Skeleton_neck_joint_1",
+            "name": "Skeleton_neck_joint_1",
+            "rotation": [
+                0.6606296300888062,
+                -0.00008344435627805069,
+                -0.0000710925814928487,
+                0.750711977481842
+            ],
+            "scale": [
+                1,
+                0.9999998211860657,
+                0.9999998807907104
+            ],
+            "translation": [
+                -0.000000008847560017954947,
+                0.0000000596045985901128,
+                0.06483659893274307
+            ]
+        },
+        "Skeleton_neck_joint_2": {
+            "children": [],
+            "jointName": "Skeleton_neck_joint_2",
+            "name": "Skeleton_neck_joint_2",
+            "rotation": [
+                0.000002552607611505664,
+                0.9996904730796814,
+                -0.02487965300679207,
+                -0.00000043299277763253485
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                0,
+                0.052039701491594315,
+                0
+            ]
+        },
+        "Skeleton_torso_joint_1": {
+            "children": [
+                "Skeleton_torso_joint_2",
+                "leg_joint_L_1",
+                "leg_joint_R_1"
+            ],
+            "jointName": "Skeleton_torso_joint_1",
+            "name": "Skeleton_torso_joint_1",
+            "rotation": [
+                0.026794692501425743,
+                0.026732537895441055,
+                0.7065614461898804,
+                0.706638753414154
+            ],
+            "scale": [
+                1,
+                1.0000001192092896,
+                1.0000001192092896
+            ],
+            "translation": [
+                -0.00000003352759847530251,
+                0.004999889992177486,
+                0.6790000200271606
+            ]
+        },
+        "Skeleton_torso_joint_2": {
+            "children": [
+                "torso_joint_3"
+            ],
+            "jointName": "Skeleton_torso_joint_2",
+            "name": "Skeleton_torso_joint_2",
+            "rotation": [
+                0.6572521924972534,
+                0.00017969278269447386,
+                0.00010428006498841569,
+                0.7536706924438477
+            ],
+            "scale": [
+                1.0000001192092896,
+                0.9999995231628418,
+                1.0000005960464478
+            ],
+            "translation": [
+                -0.00000001024449947095718,
+                0.000000014901200273698123,
+                0.1454170048236847
+            ]
+        },
+        "leg_joint_L_1": {
+            "children": [
+                "leg_joint_L_2"
+            ],
+            "jointName": "leg_joint_L_1",
+            "name": "leg_joint_L_1",
+            "rotation": [
+                0.247569739818573,
+                -0.5775678753852844,
+                0.7479144334793091,
+                -0.21388916671276093
+            ],
+            "scale": [
+                0.9999995827674866,
+                1.0000003576278687,
+                1.000000238418579
+            ],
+            "translation": [
+                0.06803669780492783,
+                -0.02851870097219944,
+                -0.06296280026435852
+            ]
+        },
+        "leg_joint_L_2": {
+            "children": [
+                "leg_joint_L_3"
+            ],
+            "jointName": "leg_joint_L_2",
+            "name": "leg_joint_L_2",
+            "rotation": [
+                -0.20902787148952484,
+                0.32988977432250977,
+                0.05559920147061348,
+                0.9189063310623169
+            ],
+            "scale": [
+                0.9999999403953552,
+                0.9999998211860657,
+                0.9999997615814209
+            ],
+            "translation": [
+                0.0000000037252898543727042,
+                0.2661130130290985,
+                0.000000014901200273698123
+            ]
+        },
+        "leg_joint_L_3": {
+            "children": [
+                "leg_joint_L_5"
+            ],
+            "jointName": "leg_joint_L_3",
+            "name": "leg_joint_L_3",
+            "rotation": [
+                -0.847739577293396,
+                0.004254061728715897,
+                0.009491981007158756,
+                0.5303107500076294
+            ],
+            "scale": [
+                1.0000003576278687,
+                1.0000001192092896,
+                1.0000004768371582
+            ],
+            "translation": [
+                -0.0000000074505797087454084,
+                0.27582401037216187,
+                0.00000000558793988858497
+            ]
+        },
+        "leg_joint_L_5": {
+            "children": [],
+            "jointName": "leg_joint_L_5",
+            "name": "leg_joint_L_5",
+            "rotation": [
+                0.0265735425055027,
+                -0.32014429569244385,
+                0.9445450305938721,
+                0.06808965653181076
+            ],
+            "scale": [
+                0.9999997019767761,
+                1.000000238418579,
+                0.9999999403953552
+            ],
+            "translation": [
+                -0.0023465200792998075,
+                -0.06617330014705658,
+                0.027856800705194473
+            ]
+        },
+        "leg_joint_R_1": {
+            "children": [
+                "leg_joint_R_2"
+            ],
+            "jointName": "leg_joint_R_1",
+            "name": "leg_joint_R_1",
+            "rotation": [
+                -0.06642694771289825,
+                -0.6115013360977173,
+                0.785027265548706,
+                0.07338760793209076
+            ],
+            "scale": [
+                0.9999995827674866,
+                0.9999997615814209,
+                1.000000238418579
+            ],
+            "translation": [
+                -0.06804200261831284,
+                -0.028570201247930527,
+                -0.06294959783554077
+            ]
+        },
+        "leg_joint_R_2": {
+            "children": [
+                "leg_joint_R_3"
+            ],
+            "jointName": "leg_joint_R_2",
+            "name": "leg_joint_R_2",
+            "rotation": [
+                -0.21629124879837036,
+                -0.1243065595626831,
+                -0.001575213740579784,
+                0.9683818817138672
+            ],
+            "scale": [
+                1.000000238418579,
+                0.9999996423721313,
+                1.0000001192092896
+            ],
+            "translation": [
+                0,
+                0.26611199975013733,
+                0
+            ]
+        },
+        "leg_joint_R_3": {
+            "children": [
+                "leg_joint_R_5"
+            ],
+            "jointName": "leg_joint_R_3",
+            "name": "leg_joint_R_3",
+            "rotation": [
+                -0.847274124622345,
+                0.02956405282020569,
+                0.020867986604571342,
+                0.5299217104911804
+            ],
+            "scale": [
+                1,
+                1,
+                1.0000001192092896
+            ],
+            "translation": [
+                0,
+                0.27582499384880066,
+                -0.000000011175900205273592
+            ]
+        },
+        "leg_joint_R_5": {
+            "children": [],
+            "jointName": "leg_joint_R_5",
+            "name": "leg_joint_R_5",
+            "rotation": [
+                -0.03726435825228691,
+                -0.3193131983280182,
+                0.9460533857345581,
+                -0.04041508957743645
+            ],
+            "scale": [
+                1,
+                1.0000007152557373,
+                1.000000238418579
+            ],
+            "translation": [
+                -0.0014584800228476524,
+                -0.06619880348443985,
+                0.027856700122356415
+            ]
+        },
+        "node_21": {
+            "children": [
+                "Armature",
+                "Cesium_Man"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                0,
+                -1,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Y_UP_Transform"
+        },
+        "torso_joint_3": {
+            "children": [
+                "Skeleton_neck_joint_1",
+                "Skeleton_arm_joint_L__4_",
+                "Skeleton_arm_joint_R"
+            ],
+            "jointName": "torso_joint_3",
+            "name": "torso_joint_3",
+            "rotation": [
+                -0.6226037740707397,
+                -0.000016783453247626312,
+                0.0000031824033612792846,
+                0.7825372219085693
+            ],
+            "scale": [
+                1,
+                0.9999997019767761,
+                0.9999997019767761
+            ],
+            "translation": [
+                0.0000000004656610097519831,
+                0.25051701068878174,
+                0.0000000037252898543727042
+            ]
+        }
+    },
+    "programs": {
+        "program_0": {
+            "attributes": [
+                "a_joint",
+                "a_normal",
+                "a_position",
+                "a_texcoord0",
+                "a_weight"
+            ],
+            "fragmentShader": "Cesium_Man0FS",
+            "vertexShader": "Cesium_Man0VS"
+        }
+    },
+    "samplers": {
+        "sampler_0": {
+            "magFilter": 9729,
+            "minFilter": 9729,
+            "wrapS": 10497,
+            "wrapT": 10497
+        }
+    },
+    "scene": "defaultScene",
+    "scenes": {
+        "defaultScene": {
+            "nodes": [
+                "node_21"
+            ]
+        }
+    },
+    "shaders": {
+        "Cesium_Man0FS": {
+            "type": 35632,
+            "uri": "Cesium_Man0FS.glsl"
+        },
+        "Cesium_Man0VS": {
+            "type": 35633,
+            "uri": "Cesium_Man0VS.glsl"
+        }
+    },
+    "skins": {
+        "Armature_Cesium_Man-skin": {
+            "bindShapeMatrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "inverseBindMatrices": "IBM_Armature_Cesium_Man-skin",
+            "jointNames": [
+                "Skeleton_torso_joint_1",
+                "Skeleton_torso_joint_2",
+                "torso_joint_3",
+                "Skeleton_neck_joint_1",
+                "Skeleton_neck_joint_2",
+                "Skeleton_arm_joint_L__4_",
+                "Skeleton_arm_joint_R",
+                "Skeleton_arm_joint_L__3_",
+                "Skeleton_arm_joint_R__2_",
+                "Skeleton_arm_joint_L__2_",
+                "Skeleton_arm_joint_R__3_",
+                "leg_joint_L_1",
+                "leg_joint_R_1",
+                "leg_joint_L_2",
+                "leg_joint_R_2",
+                "leg_joint_L_3",
+                "leg_joint_R_3",
+                "leg_joint_L_5",
+                "leg_joint_R_5"
+            ],
+            "name": "Armature"
+        }
+    },
+    "techniques": {
+        "technique0": {
+            "attributes": {
+                "a_joint": "joint",
+                "a_normal": "normal",
+                "a_position": "position",
+                "a_texcoord0": "texcoord0",
+                "a_weight": "weight"
+            },
+            "parameters": {
+                "ambient": {
+                    "type": 35666
+                },
+                "diffuse": {
+                    "type": 35678
+                },
+                "emission": {
+                    "type": 35666
+                },
+                "joint": {
+                    "semantic": "JOINT",
+                    "type": 35666
+                },
+                "jointMat": {
+                    "count": 19,
+                    "semantic": "JOINTMATRIX",
+                    "type": 35676
+                },
+                "modelViewMatrix": {
+                    "semantic": "MODELVIEW",
+                    "type": 35676
+                },
+                "normal": {
+                    "semantic": "NORMAL",
+                    "type": 35665
+                },
+                "normalMatrix": {
+                    "semantic": "MODELVIEWINVERSETRANSPOSE",
+                    "type": 35675
+                },
+                "position": {
+                    "semantic": "POSITION",
+                    "type": 35665
+                },
+                "projectionMatrix": {
+                    "semantic": "PROJECTION",
+                    "type": 35676
+                },
+                "shininess": {
+                    "type": 5126
+                },
+                "specular": {
+                    "type": 35666
+                },
+                "texcoord0": {
+                    "semantic": "TEXCOORD_0",
+                    "type": 35664
+                },
+                "weight": {
+                    "semantic": "WEIGHT",
+                    "type": 35666
+                }
+            },
+            "program": "program_0",
+            "states": {
+                "enable": [
+                    2929,
+                    2884
+                ]
+            },
+            "uniforms": {
+                "u_ambient": "ambient",
+                "u_diffuse": "diffuse",
+                "u_emission": "emission",
+                "u_jointMat": "jointMat",
+                "u_modelViewMatrix": "modelViewMatrix",
+                "u_normalMatrix": "normalMatrix",
+                "u_projectionMatrix": "projectionMatrix",
+                "u_shininess": "shininess",
+                "u_specular": "specular"
+            }
+        }
+    },
+    "textures": {
+        "texture_Cesium_Man_jpg": {
+            "format": 6408,
+            "internalFormat": 6408,
+            "sampler": "sampler_0",
+            "source": "Cesium_Man_jpg",
+            "target": 3553,
+            "type": 5121
+        }
+    }
+}

BIN
examples/models/gltf/CesiumMan/glTF/Cesium_Man.jpg


+ 25 - 0
examples/models/gltf/CesiumMan/glTF/Cesium_Man0FS.glsl

@@ -0,0 +1,25 @@
+precision highp float;
+varying vec3 v_normal;
+uniform vec4 u_ambient;
+varying vec2 v_texcoord0;
+uniform sampler2D u_diffuse;
+uniform vec4 u_emission;
+uniform vec4 u_specular;
+uniform float u_shininess;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 emission;
+vec4 ambient;
+vec4 specular;
+ambient = u_ambient;
+diffuse = texture2D(u_diffuse, v_texcoord0);
+emission = u_emission;
+specular = u_specular;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color.xyz += emission.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
+}

+ 22 - 0
examples/models/gltf/CesiumMan/glTF/Cesium_Man0VS.glsl

@@ -0,0 +1,22 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+attribute vec4 a_joint;
+attribute vec4 a_weight;
+uniform mat4 u_jointMat[19];
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+attribute vec2 a_texcoord0;
+varying vec2 v_texcoord0;
+void main(void) {
+mat4 skinMat = a_weight.x * u_jointMat[int(a_joint.x)];
+skinMat += a_weight.y * u_jointMat[int(a_joint.y)];
+skinMat += a_weight.z * u_jointMat[int(a_joint.z)];
+skinMat += a_weight.w * u_jointMat[int(a_joint.w)];
+vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);
+v_normal = u_normalMatrix * mat3(skinMat)* a_normal;
+v_texcoord0 = a_texcoord0;
+gl_Position = u_projectionMatrix * pos;
+}

+ 1 - 0
examples/models/gltf/CesiumMilkTruck/README.txt

@@ -0,0 +1 @@
+Donated by Cesium for glTF testing.  Please follow the Cesium Trademark Terms and Conditions: https://github.com/AnalyticalGraphicsInc/cesium/wiki/CesiumTrademark.pdf

BIN
examples/models/gltf/CesiumMilkTruck/glTF-MaterialsCommon/CesiumMilkTruck.bin


+ 610 - 0
examples/models/gltf/CesiumMilkTruck/glTF-MaterialsCommon/CesiumMilkTruck.gltf

@@ -0,0 +1,610 @@
+{
+    "accessors": {
+        "accessor_100": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 7032,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 586,
+            "max": [
+                0.999039,
+                0.999038,
+                1
+            ],
+            "min": [
+                -0.999038,
+                -0.999038,
+                -1
+            ],
+            "type": "VEC3"
+        },
+        "accessor_102": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 14064,
+            "byteStride": 8,
+            "componentType": 5126,
+            "count": 586,
+            "max": [
+                0.993657,
+                0.989576
+            ],
+            "min": [
+                0.605093,
+                0.00905001
+            ],
+            "type": "VEC2"
+        },
+        "accessor_63": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 4608,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 5232,
+            "type": "SCALAR"
+        },
+        "accessor_66": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 15072,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 168,
+            "type": "SCALAR"
+        },
+        "accessor_69": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 15408,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 864,
+            "type": "SCALAR"
+        },
+        "accessor_71": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 18752,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 2392,
+            "max": [
+                2.438,
+                2.58437,
+                1.396
+            ],
+            "min": [
+                -2.43091,
+                0.2668,
+                -1.396
+            ],
+            "type": "VEC3"
+        },
+        "accessor_73": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 47456,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 2392,
+            "max": [
+                1,
+                1,
+                1
+            ],
+            "min": [
+                -1,
+                -1,
+                -1
+            ],
+            "type": "VEC3"
+        },
+        "accessor_75": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 76160,
+            "byteStride": 8,
+            "componentType": 5126,
+            "count": 2392,
+            "max": [
+                0.896458,
+                0.997245
+            ],
+            "min": [
+                0.00295639,
+                0.015672
+            ],
+            "type": "VEC2"
+        },
+        "accessor_96": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 0,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 2304,
+            "type": "SCALAR"
+        },
+        "accessor_98": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 0,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 586,
+            "max": [
+                0.4278,
+                0.4278,
+                1.058
+            ],
+            "min": [
+                -0.4278,
+                -0.4278,
+                -1.058
+            ],
+            "type": "VEC3"
+        },
+        "animAccessor_0": {
+            "bufferView": "bufferView_103",
+            "byteOffset": 0,
+            "componentType": 5126,
+            "count": 31,
+            "type": "SCALAR"
+        },
+        "animAccessor_1": {
+            "bufferView": "bufferView_103",
+            "byteOffset": 124,
+            "componentType": 5126,
+            "count": 31,
+            "type": "VEC4"
+        }
+    },
+    "animations": {
+        "animation_0": {
+            "channels": [
+                {
+                    "sampler": "animation_0_rotation_sampler",
+                    "target": {
+                        "id": "Geometry-mesh001Node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_1"
+            },
+            "samplers": {
+                "animation_0_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                }
+            }
+        },
+        "animation_1": {
+            "channels": [
+                {
+                    "sampler": "animation_1_rotation_sampler",
+                    "target": {
+                        "id": "meshInst962Node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_1"
+            },
+            "samplers": {
+                "animation_1_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                }
+            }
+        }
+    },
+    "asset": {
+        "generator": "collada2gltf@cf6371beb0bdc18ba603378d5e40c966da53d385",
+        "premultipliedAlpha": true,
+        "profile": {
+            "api": "WebGL",
+            "version": "1.0.2"
+        },
+        "version": "1.0"
+    },
+    "bufferViews": {
+        "bufferView_103": {
+            "buffer": "CesiumMilkTruck",
+            "byteLength": 620,
+            "byteOffset": 0
+        },
+        "bufferView_104": {
+            "buffer": "CesiumMilkTruck",
+            "byteLength": 17136,
+            "byteOffset": 620,
+            "target": 34963
+        },
+        "bufferView_105": {
+            "buffer": "CesiumMilkTruck",
+            "byteLength": 95296,
+            "byteOffset": 17756,
+            "target": 34962
+        }
+    },
+    "buffers": {
+        "CesiumMilkTruck": {
+            "byteLength": 113052,
+            "type": "arraybuffer",
+            "uri": "CesiumMilkTruck.bin"
+        }
+    },
+    "extensions": {
+        "KHR_materials_common": {
+            "lights": {
+                "Light-polyRender006": {
+                    "ambient": {
+                        "color": [
+                            0,
+                            0,
+                            0
+                        ]
+                    },
+                    "name": "Render",
+                    "type": "ambient"
+                }
+            }
+        }
+    },
+    "extensionsUsed": [
+        "KHR_materials_common"
+    ],
+    "images": {
+        "Image0001": {
+            "name": "Image0001",
+            "uri": "CesiumMilkTruck.png"
+        }
+    },
+    "materials": {
+        "Effect-glass": {
+            "extensions": {
+                "KHR_materials_common": {
+                    "doubleSided": false,
+                    "jointCount": 0,
+                    "technique": "PHONG",
+                    "transparent": false,
+                    "values": {
+                        "diffuse": [
+                            0,
+                            0.0405063,
+                            0.0212407,
+                            1
+                        ],
+                        "shininess": 256,
+                        "specular": [
+                            0.65,
+                            0.65,
+                            0.65,
+                            1
+                        ]
+                    }
+                }
+            },
+            "name": "glass"
+        },
+        "Effect-truck": {
+            "extensions": {
+                "KHR_materials_common": {
+                    "doubleSided": false,
+                    "jointCount": 0,
+                    "technique": "PHONG",
+                    "transparent": false,
+                    "values": {
+                        "diffuse": "texture_Image0001",
+                        "shininess": 256,
+                        "specular": [
+                            0.04,
+                            0.04,
+                            0.04,
+                            1
+                        ]
+                    }
+                }
+            },
+            "name": "truck"
+        },
+        "Effect-wheels": {
+            "extensions": {
+                "KHR_materials_common": {
+                    "doubleSided": false,
+                    "jointCount": 0,
+                    "technique": "PHONG",
+                    "transparent": false,
+                    "values": {
+                        "diffuse": "texture_Image0001",
+                        "shininess": 256,
+                        "specular": [
+                            0.04,
+                            0.04,
+                            0.04,
+                            1
+                        ]
+                    }
+                }
+            },
+            "name": "wheels"
+        },
+        "Effect-window_trim": {
+            "extensions": {
+                "KHR_materials_common": {
+                    "doubleSided": false,
+                    "jointCount": 0,
+                    "technique": "PHONG",
+                    "transparent": false,
+                    "values": {
+                        "diffuse": [
+                            0.064,
+                            0.064,
+                            0.064,
+                            1
+                        ],
+                        "shininess": 256,
+                        "specular": [
+                            0.04,
+                            0.04,
+                            0.04,
+                            1
+                        ]
+                    }
+                }
+            },
+            "name": "window_trim"
+        }
+    },
+    "meshes": {
+        "Geometry-mesh001": {
+            "name": "Wheels",
+            "primitives": [
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_100",
+                        "POSITION": "accessor_98",
+                        "TEXCOORD_0": "accessor_102"
+                    },
+                    "indices": "accessor_96",
+                    "material": "Effect-wheels",
+                    "mode": 4
+                }
+            ]
+        },
+        "Geometry-mesh002": {
+            "name": "Cesium_Milk_Truck",
+            "primitives": [
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_73",
+                        "POSITION": "accessor_71",
+                        "TEXCOORD_0": "accessor_75"
+                    },
+                    "indices": "accessor_63",
+                    "material": "Effect-truck",
+                    "mode": 4
+                },
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_73",
+                        "POSITION": "accessor_71",
+                        "TEXCOORD_0": "accessor_75"
+                    },
+                    "indices": "accessor_66",
+                    "material": "Effect-glass",
+                    "mode": 4
+                },
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_73",
+                        "POSITION": "accessor_71",
+                        "TEXCOORD_0": "accessor_75"
+                    },
+                    "indices": "accessor_69",
+                    "material": "Effect-window_trim",
+                    "mode": 4
+                }
+            ]
+        }
+    },
+    "nodes": {
+        "Geometry-mesh001Node": {
+            "children": [],
+            "meshes": [
+                "Geometry-mesh001"
+            ],
+            "name": "Wheels",
+            "rotation": [
+                0,
+                0,
+                -0.0884856,
+                0.996077
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                1.43267,
+                0.427722,
+                -2.98023e-008
+            ]
+        },
+        "Geometry-mesh002Node": {
+            "children": [
+                "Geometry-mesh001Node",
+                "meshInst962Node"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "meshes": [
+                "Geometry-mesh002"
+            ],
+            "name": "Cesium_Milk_Truck"
+        },
+        "groupLocator006Node": {
+            "children": [
+                "txtrLocator003Node",
+                "txtrLocator013Node"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Texture_Group"
+        },
+        "meshInst962Node": {
+            "children": [],
+            "meshes": [
+                "Geometry-mesh001"
+            ],
+            "name": "Wheels__2_",
+            "rotation": [
+                0,
+                0,
+                -0.0884856,
+                0.996077
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -1.35233,
+                0.427722,
+                -2.98023e-008
+            ]
+        },
+        "polyRender006": {
+            "children": [],
+            "extensions": {
+                "KHR_materials_common": {
+                    "light": "Light-polyRender006"
+                }
+            },
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Render"
+        },
+        "txtrLocator003Node": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Cesium_Milk_Truck__2___Image___Texture_"
+        },
+        "txtrLocator013Node": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Cesium_Milk_Truck__2___Image___2___Texture_"
+        }
+    },
+    "samplers": {
+        "sampler_0": {
+            "magFilter": 9729,
+            "minFilter": 9987,
+            "wrapS": 10497,
+            "wrapT": 10497
+        }
+    },
+    "scene": "defaultScene",
+    "scenes": {
+        "defaultScene": {
+            "nodes": [
+                "polyRender006",
+                "Geometry-mesh002Node",
+                "groupLocator006Node"
+            ]
+        }
+    },
+    "skins": {},
+    "textures": {
+        "texture_Image0001": {
+            "format": 6408,
+            "internalFormat": 6408,
+            "sampler": "sampler_0",
+            "source": "Image0001",
+            "target": 3553,
+            "type": 5121
+        }
+    }
+}

BIN
examples/models/gltf/CesiumMilkTruck/glTF-MaterialsCommon/CesiumMilkTruck.png


BIN
examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck.bin


+ 705 - 0
examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck.gltf

@@ -0,0 +1,705 @@
+{
+    "accessors": {
+        "accessor_100": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 7032,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 586,
+            "max": [
+                0.999039,
+                0.999038,
+                1
+            ],
+            "min": [
+                -0.999038,
+                -0.999038,
+                -1
+            ],
+            "type": "VEC3"
+        },
+        "accessor_102": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 14064,
+            "byteStride": 8,
+            "componentType": 5126,
+            "count": 586,
+            "max": [
+                0.993657,
+                0.989576
+            ],
+            "min": [
+                0.605093,
+                0.00905001
+            ],
+            "type": "VEC2"
+        },
+        "accessor_63": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 4608,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 5232,
+            "type": "SCALAR"
+        },
+        "accessor_66": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 15072,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 168,
+            "type": "SCALAR"
+        },
+        "accessor_69": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 15408,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 864,
+            "type": "SCALAR"
+        },
+        "accessor_71": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 18752,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 2392,
+            "max": [
+                2.438,
+                2.58437,
+                1.396
+            ],
+            "min": [
+                -2.43091,
+                0.2668,
+                -1.396
+            ],
+            "type": "VEC3"
+        },
+        "accessor_73": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 47456,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 2392,
+            "max": [
+                1,
+                1,
+                1
+            ],
+            "min": [
+                -1,
+                -1,
+                -1
+            ],
+            "type": "VEC3"
+        },
+        "accessor_75": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 76160,
+            "byteStride": 8,
+            "componentType": 5126,
+            "count": 2392,
+            "max": [
+                0.896458,
+                0.997245
+            ],
+            "min": [
+                0.00295639,
+                0.015672
+            ],
+            "type": "VEC2"
+        },
+        "accessor_96": {
+            "bufferView": "bufferView_104",
+            "byteOffset": 0,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 2304,
+            "type": "SCALAR"
+        },
+        "accessor_98": {
+            "bufferView": "bufferView_105",
+            "byteOffset": 0,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 586,
+            "max": [
+                0.4278,
+                0.4278,
+                1.058
+            ],
+            "min": [
+                -0.4278,
+                -0.4278,
+                -1.058
+            ],
+            "type": "VEC3"
+        },
+        "animAccessor_0": {
+            "bufferView": "bufferView_103",
+            "byteOffset": 0,
+            "componentType": 5126,
+            "count": 31,
+            "type": "SCALAR"
+        },
+        "animAccessor_1": {
+            "bufferView": "bufferView_103",
+            "byteOffset": 124,
+            "componentType": 5126,
+            "count": 31,
+            "type": "VEC4"
+        }
+    },
+    "animations": {
+        "animation_0": {
+            "channels": [
+                {
+                    "sampler": "animation_0_rotation_sampler",
+                    "target": {
+                        "id": "Geometry-mesh001Node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_1"
+            },
+            "samplers": {
+                "animation_0_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                }
+            }
+        },
+        "animation_1": {
+            "channels": [
+                {
+                    "sampler": "animation_1_rotation_sampler",
+                    "target": {
+                        "id": "meshInst962Node",
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "parameters": {
+                "TIME": "animAccessor_0",
+                "rotation": "animAccessor_1"
+            },
+            "samplers": {
+                "animation_1_rotation_sampler": {
+                    "input": "TIME",
+                    "interpolation": "LINEAR",
+                    "output": "rotation"
+                }
+            }
+        }
+    },
+    "asset": {
+        "generator": "collada2gltf@ceec062e3d5793f2f249f53cbd843aee382ad40b",
+        "premultipliedAlpha": true,
+        "profile": {
+            "api": "WebGL",
+            "version": "1.0.2"
+        },
+        "version": 1
+    },
+    "bufferViews": {
+        "bufferView_103": {
+            "buffer": "CesiumMilkTruck",
+            "byteLength": 620,
+            "byteOffset": 0
+        },
+        "bufferView_104": {
+            "buffer": "CesiumMilkTruck",
+            "byteLength": 17136,
+            "byteOffset": 620,
+            "target": 34963
+        },
+        "bufferView_105": {
+            "buffer": "CesiumMilkTruck",
+            "byteLength": 95296,
+            "byteOffset": 17756,
+            "target": 34962
+        }
+    },
+    "buffers": {
+        "CesiumMilkTruck": {
+            "byteLength": 113052,
+            "type": "arraybuffer",
+            "uri": "CesiumMilkTruck.bin"
+        }
+    },
+    "images": {
+        "Image0001": {
+            "name": "Image0001",
+            "uri": "CesiumMilkTruck.png"
+        }
+    },
+    "materials": {
+        "Effect-glass": {
+            "name": "glass",
+            "technique": "technique0",
+            "values": {
+                "diffuse": [
+                    0,
+                    0.0405063,
+                    0.0212407,
+                    1
+                ],
+                "shininess": 256,
+                "specular": [
+                    0.65,
+                    0.65,
+                    0.65,
+                    1
+                ]
+            }
+        },
+        "Effect-truck": {
+            "name": "truck",
+            "technique": "technique1",
+            "values": {
+                "diffuse": "texture_Image0001",
+                "shininess": 256,
+                "specular": [
+                    0.04,
+                    0.04,
+                    0.04,
+                    1
+                ]
+            }
+        },
+        "Effect-wheels": {
+            "name": "wheels",
+            "technique": "technique1",
+            "values": {
+                "diffuse": "texture_Image0001",
+                "shininess": 256,
+                "specular": [
+                    0.04,
+                    0.04,
+                    0.04,
+                    1
+                ]
+            }
+        },
+        "Effect-window_trim": {
+            "name": "window_trim",
+            "technique": "technique0",
+            "values": {
+                "diffuse": [
+                    0.064,
+                    0.064,
+                    0.064,
+                    1
+                ],
+                "shininess": 256,
+                "specular": [
+                    0.04,
+                    0.04,
+                    0.04,
+                    1
+                ]
+            }
+        }
+    },
+    "meshes": {
+        "Geometry-mesh001": {
+            "name": "Wheels",
+            "primitives": [
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_100",
+                        "POSITION": "accessor_98",
+                        "TEXCOORD_0": "accessor_102"
+                    },
+                    "indices": "accessor_96",
+                    "material": "Effect-wheels",
+                    "mode": 4
+                }
+            ]
+        },
+        "Geometry-mesh002": {
+            "name": "Cesium_Milk_Truck",
+            "primitives": [
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_73",
+                        "POSITION": "accessor_71",
+                        "TEXCOORD_0": "accessor_75"
+                    },
+                    "indices": "accessor_63",
+                    "material": "Effect-truck",
+                    "mode": 4
+                },
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_73",
+                        "POSITION": "accessor_71",
+                        "TEXCOORD_0": "accessor_75"
+                    },
+                    "indices": "accessor_66",
+                    "material": "Effect-glass",
+                    "mode": 4
+                },
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_73",
+                        "POSITION": "accessor_71",
+                        "TEXCOORD_0": "accessor_75"
+                    },
+                    "indices": "accessor_69",
+                    "material": "Effect-window_trim",
+                    "mode": 4
+                }
+            ]
+        }
+    },
+    "nodes": {
+        "Geometry-mesh001Node": {
+            "children": [],
+            "meshes": [
+                "Geometry-mesh001"
+            ],
+            "name": "Wheels",
+            "rotation": [
+                0,
+                0,
+                -0.0884856,
+                0.996077
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                1.43267,
+                0.427722,
+                -2.98023e-008
+            ]
+        },
+        "Geometry-mesh002Node": {
+            "children": [
+                "Geometry-mesh001Node",
+                "meshInst962Node"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "meshes": [
+                "Geometry-mesh002"
+            ],
+            "name": "Cesium_Milk_Truck"
+        },
+        "groupLocator006Node": {
+            "children": [
+                "txtrLocator003Node",
+                "txtrLocator013Node"
+            ],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Texture_Group"
+        },
+        "meshInst962Node": {
+            "children": [],
+            "meshes": [
+                "Geometry-mesh001"
+            ],
+            "name": "Wheels__2_",
+            "rotation": [
+                0,
+                0,
+                -0.0884856,
+                0.996077
+            ],
+            "scale": [
+                1,
+                1,
+                1
+            ],
+            "translation": [
+                -1.35233,
+                0.427722,
+                -2.98023e-008
+            ]
+        },
+        "polyRender006": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Render"
+        },
+        "txtrLocator003Node": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Cesium_Milk_Truck__2___Image___Texture_"
+        },
+        "txtrLocator013Node": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "name": "Cesium_Milk_Truck__2___Image___2___Texture_"
+        }
+    },
+    "programs": {
+        "program_0": {
+            "attributes": [
+                "a_normal",
+                "a_position"
+            ],
+            "fragmentShader": "CesiumMilkTruck0FS",
+            "vertexShader": "CesiumMilkTruck0VS"
+        },
+        "program_1": {
+            "attributes": [
+                "a_normal",
+                "a_position",
+                "a_texcoord0"
+            ],
+            "fragmentShader": "CesiumMilkTruck1FS",
+            "vertexShader": "CesiumMilkTruck1VS"
+        }
+    },
+    "samplers": {
+        "sampler_0": {
+            "magFilter": 9729,
+            "minFilter": 9987,
+            "wrapS": 10497,
+            "wrapT": 10497
+        }
+    },
+    "scene": "defaultScene",
+    "scenes": {
+        "defaultScene": {
+            "nodes": [
+                "polyRender006",
+                "Geometry-mesh002Node",
+                "groupLocator006Node"
+            ]
+        }
+    },
+    "shaders": {
+        "CesiumMilkTruck0FS": {
+            "type": 35632,
+            "uri": "CesiumMilkTruck0FS.glsl"
+        },
+        "CesiumMilkTruck0VS": {
+            "type": 35633,
+            "uri": "CesiumMilkTruck0VS.glsl"
+        },
+        "CesiumMilkTruck1FS": {
+            "type": 35632,
+            "uri": "CesiumMilkTruck1FS.glsl"
+        },
+        "CesiumMilkTruck1VS": {
+            "type": 35633,
+            "uri": "CesiumMilkTruck1VS.glsl"
+        }
+    },
+    "skins": {},
+    "techniques": {
+        "technique0": {
+            "attributes": {
+                "a_normal": "normal",
+                "a_position": "position"
+            },
+            "parameters": {
+                "diffuse": {
+                    "type": 35666
+                },
+                "modelViewMatrix": {
+                    "semantic": "MODELVIEW",
+                    "type": 35676
+                },
+                "normal": {
+                    "semantic": "NORMAL",
+                    "type": 35665
+                },
+                "normalMatrix": {
+                    "semantic": "MODELVIEWINVERSETRANSPOSE",
+                    "type": 35675
+                },
+                "position": {
+                    "semantic": "POSITION",
+                    "type": 35665
+                },
+                "projectionMatrix": {
+                    "semantic": "PROJECTION",
+                    "type": 35676
+                },
+                "shininess": {
+                    "type": 5126
+                },
+                "specular": {
+                    "type": 35666
+                }
+            },
+            "program": "program_0",
+            "states": {
+                "enable": [
+                    2929,
+                    2884
+                ]
+            },
+            "uniforms": {
+                "u_diffuse": "diffuse",
+                "u_modelViewMatrix": "modelViewMatrix",
+                "u_normalMatrix": "normalMatrix",
+                "u_projectionMatrix": "projectionMatrix",
+                "u_shininess": "shininess",
+                "u_specular": "specular"
+            }
+        },
+        "technique1": {
+            "attributes": {
+                "a_normal": "normal",
+                "a_position": "position",
+                "a_texcoord0": "texcoord0"
+            },
+            "parameters": {
+                "diffuse": {
+                    "type": 35678
+                },
+                "modelViewMatrix": {
+                    "semantic": "MODELVIEW",
+                    "type": 35676
+                },
+                "normal": {
+                    "semantic": "NORMAL",
+                    "type": 35665
+                },
+                "normalMatrix": {
+                    "semantic": "MODELVIEWINVERSETRANSPOSE",
+                    "type": 35675
+                },
+                "position": {
+                    "semantic": "POSITION",
+                    "type": 35665
+                },
+                "projectionMatrix": {
+                    "semantic": "PROJECTION",
+                    "type": 35676
+                },
+                "shininess": {
+                    "type": 5126
+                },
+                "specular": {
+                    "type": 35666
+                },
+                "texcoord0": {
+                    "semantic": "TEXCOORD_0",
+                    "type": 35664
+                }
+            },
+            "program": "program_1",
+            "states": {
+                "enable": [
+                    2929,
+                    2884
+                ]
+            },
+            "uniforms": {
+                "u_diffuse": "diffuse",
+                "u_modelViewMatrix": "modelViewMatrix",
+                "u_normalMatrix": "normalMatrix",
+                "u_projectionMatrix": "projectionMatrix",
+                "u_shininess": "shininess",
+                "u_specular": "specular"
+            }
+        }
+    },
+    "textures": {
+        "texture_Image0001": {
+            "format": 6408,
+            "internalFormat": 6408,
+            "sampler": "sampler_0",
+            "source": "Image0001",
+            "target": 3553,
+            "type": 5121
+        }
+    }
+}

BIN
examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck.png


+ 17 - 0
examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck0FS.glsl

@@ -0,0 +1,17 @@
+precision highp float;
+varying vec3 v_normal;
+uniform vec4 u_diffuse;
+uniform vec4 u_specular;
+uniform float u_shininess;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 specular;
+diffuse = u_diffuse;
+specular = u_specular;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
+}

+ 12 - 0
examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck0VS.glsl

@@ -0,0 +1,12 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+void main(void) {
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+gl_Position = u_projectionMatrix * pos;
+}

+ 18 - 0
examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck1FS.glsl

@@ -0,0 +1,18 @@
+precision highp float;
+varying vec3 v_normal;
+varying vec2 v_texcoord0;
+uniform sampler2D u_diffuse;
+uniform vec4 u_specular;
+uniform float u_shininess;
+void main(void) {
+vec3 normal = normalize(v_normal);
+vec4 color = vec4(0., 0., 0., 0.);
+vec4 diffuse = vec4(0., 0., 0., 1.);
+vec4 specular;
+diffuse = texture2D(u_diffuse, v_texcoord0);
+specular = u_specular;
+diffuse.xyz *= max(dot(normal,vec3(0.,0.,1.)), 0.);
+color.xyz += diffuse.xyz;
+color = vec4(color.rgb * diffuse.a, diffuse.a);
+gl_FragColor = color;
+}

+ 15 - 0
examples/models/gltf/CesiumMilkTruck/glTF/CesiumMilkTruck1VS.glsl

@@ -0,0 +1,15 @@
+precision highp float;
+attribute vec3 a_position;
+attribute vec3 a_normal;
+varying vec3 v_normal;
+uniform mat3 u_normalMatrix;
+uniform mat4 u_modelViewMatrix;
+uniform mat4 u_projectionMatrix;
+attribute vec2 a_texcoord0;
+varying vec2 v_texcoord0;
+void main(void) {
+vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);
+v_normal = u_normalMatrix * a_normal;
+v_texcoord0 = a_texcoord0;
+gl_Position = u_projectionMatrix * pos;
+}

+ 7 - 13
examples/models/gltf/duck/README.txt

@@ -1,13 +1,7 @@
----UPDATED 2/21/2007

-Scaled down the duck to a more reasonable size, removed physics scene, removed extra "dummy" transforms and pivot points, added camera and light.

----

-

-This model is a typical bathtub rubber duck.  It uses a single texture.

-

-One version uses a polylist the other is triangles only.

-

-The model has been stripped of all <extra> tags and should be COLLADA 1.4.1 compliant.

-

-For additional information post messages on www.collada.org or mail [email protected]

-

-These models are Copyright 2006 Sony Computer Entertainment Inc. and are distributed under the terms of the SCEA Shared Source License, available at http://research.scea.com/scea_shared_source_license.html
+Copyright 2006 Sony Computer Entertainment Inc.
+
+Licensed under the SCEA Shared Source License, Version 1.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://research.scea.com/scea_shared_source_license.html
+
+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.

BIN
examples/models/gltf/duck/duck.bin


File diff suppressed because it is too large
+ 0 - 122
examples/models/gltf/duck/duck.dae


BIN
examples/models/gltf/duck/glTF-MaterialsCommon/duck.bin


+ 291 - 0
examples/models/gltf/duck/glTF-MaterialsCommon/duck.gltf

@@ -0,0 +1,291 @@
+{
+    "accessors": {
+        "accessor_21": {
+            "bufferView": "bufferView_29",
+            "byteOffset": 0,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 12636,
+            "type": "SCALAR"
+        },
+        "accessor_23": {
+            "bufferView": "bufferView_30",
+            "byteOffset": 0,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 2399,
+            "max": [
+                0.961799,
+                1.6397,
+                0.539252
+            ],
+            "min": [
+                -0.692985,
+                0.0992937,
+                -0.613282
+            ],
+            "type": "VEC3"
+        },
+        "accessor_25": {
+            "bufferView": "bufferView_30",
+            "byteOffset": 28788,
+            "byteStride": 12,
+            "componentType": 5126,
+            "count": 2399,
+            "max": [
+                0.999599,
+                0.999581,
+                0.998436
+            ],
+            "min": [
+                -0.999084,
+                -1,
+                -0.999832
+            ],
+            "type": "VEC3"
+        },
+        "accessor_27": {
+            "bufferView": "bufferView_30",
+            "byteOffset": 57576,
+            "byteStride": 8,
+            "componentType": 5126,
+            "count": 2399,
+            "max": [
+                0.983346,
+                0.980037
+            ],
+            "min": [
+                0.026409,
+                0.019963
+            ],
+            "type": "VEC2"
+        }
+    },
+    "animations": {},
+    "asset": {
+        "generator": "collada2gltf@cf6371beb0bdc18ba603378d5e40c966da53d385",
+        "premultipliedAlpha": true,
+        "profile": {
+            "api": "WebGL",
+            "version": "1.0.2"
+        },
+        "version": "1.0"
+    },
+    "bufferViews": {
+        "bufferView_29": {
+            "buffer": "duck",
+            "byteLength": 25272,
+            "byteOffset": 0,
+            "target": 34963
+        },
+        "bufferView_30": {
+            "buffer": "duck",
+            "byteLength": 76768,
+            "byteOffset": 25272,
+            "target": 34962
+        }
+    },
+    "buffers": {
+        "duck": {
+            "byteLength": 102040,
+            "type": "arraybuffer",
+            "uri": "duck.bin"
+        }
+    },
+    "cameras": {
+        "cameraShape1": {
+            "name": "cameraShape1",
+            "perspective": {
+                "aspect_ratio": 1.5,
+                "yfov": 0.660593,
+                "zfar": 100,
+                "znear": 0.01
+            },
+            "type": "perspective"
+        }
+    },
+    "extensions": {
+        "KHR_materials_common": {
+            "lights": {
+                "directionalLightShape1-lib": {
+                    "directional": {
+                        "color": [
+                            1,
+                            1,
+                            1
+                        ]
+                    },
+                    "name": "directionalLightShape1",
+                    "type": "directional"
+                }
+            }
+        }
+    },
+    "extensionsUsed": [
+        "KHR_materials_common"
+    ],
+    "images": {
+        "file2": {
+            "name": "file2",
+            "uri": "duckCM.png"
+        }
+    },
+    "materials": {
+        "blinn3-fx": {
+            "extensions": {
+                "KHR_materials_common": {
+                    "doubleSided": false,
+                    "jointCount": 0,
+                    "technique": "BLINN",
+                    "transparent": false,
+                    "values": {
+                        "ambient": [
+                            0,
+                            0,
+                            0,
+                            1
+                        ],
+                        "diffuse": "texture_file2",
+                        "emission": [
+                            0,
+                            0,
+                            0,
+                            1
+                        ],
+                        "shininess": 38.4,
+                        "specular": [
+                            0,
+                            0,
+                            0,
+                            1
+                        ]
+                    }
+                }
+            },
+            "name": "blinn3"
+        }
+    },
+    "meshes": {
+        "LOD3spShape-lib": {
+            "name": "LOD3spShape",
+            "primitives": [
+                {
+                    "attributes": {
+                        "NORMAL": "accessor_25",
+                        "POSITION": "accessor_23",
+                        "TEXCOORD_0": "accessor_27"
+                    },
+                    "indices": "accessor_21",
+                    "material": "blinn3-fx",
+                    "mode": 4
+                }
+            ]
+        }
+    },
+    "nodes": {
+        "LOD3sp": {
+            "children": [],
+            "matrix": [
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1,
+                0,
+                0,
+                0,
+                0,
+                1
+            ],
+            "meshes": [
+                "LOD3spShape-lib"
+            ],
+            "name": "LOD3sp"
+        },
+        "camera1": {
+            "camera": "cameraShape1",
+            "children": [],
+            "matrix": [
+                -0.728969,
+                0,
+                -0.684547,
+                0,
+                -0.425205,
+                0.783693,
+                0.452797,
+                0,
+                0.536475,
+                0.621148,
+                -0.571288,
+                0,
+                4.00113,
+                4.63264,
+                -4.31078,
+                1
+            ],
+            "name": "camera1"
+        },
+        "directionalLight1": {
+            "children": [],
+            "extensions": {
+                "KHR_materials_common": {
+                    "light": "directionalLightShape1-lib"
+                }
+            },
+            "matrix": [
+                -0.954692,
+                0.218143,
+                -0.202429,
+                0,
+                0.014672,
+                0.713885,
+                0.700109,
+                0,
+                0.297235,
+                0.665418,
+                -0.684741,
+                0,
+                1.48654,
+                1.83672,
+                -2.92179,
+                1
+            ],
+            "name": "directionalLight1"
+        }
+    },
+    "samplers": {
+        "sampler_0": {
+            "magFilter": 9729,
+            "minFilter": 9987,
+            "wrapS": 10497,
+            "wrapT": 10497
+        }
+    },
+    "scene": "defaultScene",
+    "scenes": {
+        "defaultScene": {
+            "nodes": [
+                "LOD3sp",
+                "camera1",
+                "directionalLight1"
+            ]
+        }
+    },
+    "skins": {},
+    "textures": {
+        "texture_file2": {
+            "format": 6408,
+            "internalFormat": 6408,
+            "sampler": "sampler_0",
+            "source": "file2",
+            "target": 3553,
+            "type": 5121
+        }
+    }
+}

+ 0 - 0
examples/models/gltf/duck/duckCM.png → examples/models/gltf/duck/glTF-MaterialsCommon/duckCM.png


BIN
examples/models/gltf/duck/glTF/duck.bin


+ 119 - 154
examples/models/gltf/duck/duck.json → examples/models/gltf/duck/glTF/duck.gltf

@@ -1,26 +1,36 @@
 {
     "accessors": {
-        "attribute_23": {
+        "accessor_21": {
             "bufferView": "bufferView_29",
             "byteOffset": 0,
+            "byteStride": 0,
+            "componentType": 5123,
+            "count": 12636,
+            "type": "SCALAR"
+        },
+        "accessor_23": {
+            "bufferView": "bufferView_30",
+            "byteOffset": 0,
             "byteStride": 12,
+            "componentType": 5126,
             "count": 2399,
             "max": [
-                96.1799,
-                163.97,
-                53.9252
+                0.961799,
+                1.6397,
+                0.539252
             ],
             "min": [
-                -69.2985,
-                9.92937,
-                -61.3282
+                -0.692985,
+                0.0992937,
+                -0.613282
             ],
-            "type": 35665
+            "type": "VEC3"
         },
-        "attribute_25": {
-            "bufferView": "bufferView_29",
+        "accessor_25": {
+            "bufferView": "bufferView_30",
             "byteOffset": 28788,
             "byteStride": 12,
+            "componentType": 5126,
             "count": 2399,
             "max": [
                 0.999599,
@@ -32,12 +42,13 @@
                 -1,
                 -0.999832
             ],
-            "type": 35665
+            "type": "VEC3"
         },
-        "attribute_27": {
-            "bufferView": "bufferView_29",
+        "accessor_27": {
+            "bufferView": "bufferView_30",
             "byteOffset": 57576,
             "byteStride": 8,
+            "componentType": 5126,
             "count": 2399,
             "max": [
                 0.983346,
@@ -47,101 +58,84 @@
                 0.026409,
                 0.019963
             ],
-            "type": 35664
-        },
-        "indices_21": {
-            "bufferView": "bufferView_30",
-            "byteOffset": 0,
-            "count": 12636,
-            "type": 5123
+            "type": "VEC2"
         }
     },
     "animations": {},
     "asset": {
-        "generator": "collada2gltf@75061f683116dc0ffdad48f33c226e933132e98c"
+        "generator": "collada2gltf@ceec062e3d5793f2f249f53cbd843aee382ad40b",
+        "premultipliedAlpha": true,
+        "profile": {
+            "api": "WebGL",
+            "version": "1.0.2"
+        },
+        "version": 1
     },
     "bufferViews": {
         "bufferView_29": {
-            "buffer": "duck",
-            "byteLength": 76768,
-            "byteOffset": 0,
-            "target": 34962
-        },
-        "bufferView_30": {
             "buffer": "duck",
             "byteLength": 25272,
-            "byteOffset": 76768,
+            "byteOffset": 0,
             "target": 34963
         },
-        "bufferView_31": {
+        "bufferView_30": {
             "buffer": "duck",
-            "byteLength": 0,
-            "byteOffset": 102040
+            "byteLength": 76768,
+            "byteOffset": 25272,
+            "target": 34962
         }
     },
     "buffers": {
         "duck": {
             "byteLength": 102040,
-            "path": "duck.bin",
-            "type": "arraybuffer"
+            "type": "arraybuffer",
+            "uri": "duck.bin"
         }
     },
     "cameras": {
-        "camera_0": {
+        "cameraShape1": {
+            "name": "cameraShape1",
             "perspective": {
                 "aspect_ratio": 1.5,
-                "yfov": 37.8492,
-                "zfar": 10000,
-                "znear": 1
+                "yfov": 0.660593,
+                "zfar": 100,
+                "znear": 0.01
             },
             "type": "perspective"
         }
     },
     "images": {
-        "image_0": {
-            "path": "duckCM.png"
-        }
-    },
-    "lights": {
-        "directionalLightShape1-lib": {
-            "directional": {
-                "color": [
-                    1,
-                    1,
-                    1
-                ]
-            },
-            "type": "directional"
+        "file2": {
+            "name": "file2",
+            "uri": "duckCM.png"
         }
     },
     "materials": {
         "blinn3-fx": {
-            "instanceTechnique": {
-                "technique": "technique1",
-                "values": {
-                    "ambient": [
-                        0,
-                        0,
-                        0,
-                        1
-                    ],
-                    "diffuse": "texture_image_0",
-                    "emission": [
-                        0,
-                        0,
-                        0,
-                        1
-                    ],
-                    "shininess": 38.4,
-                    "specular": [
-                        0,
-                        0,
-                        0,
-                        1
-                    ]
-                }
-            },
-            "name": "blinn3"
+            "name": "blinn3",
+            "technique": "technique0",
+            "values": {
+                "ambient": [
+                    0,
+                    0,
+                    0,
+                    1
+                ],
+                "diffuse": "texture_file2",
+                "emission": [
+                    0,
+                    0,
+                    0,
+                    1
+                ],
+                "shininess": 38.4,
+                "specular": [
+                    0,
+                    0,
+                    0,
+                    1
+                ]
+            }
         }
     },
     "meshes": {
@@ -150,13 +144,13 @@
             "primitives": [
                 {
                     "attributes": {
-                        "NORMAL": "attribute_25",
-                        "POSITION": "attribute_23",
-                        "TEXCOORD_0": "attribute_27"
+                        "NORMAL": "accessor_25",
+                        "POSITION": "accessor_23",
+                        "TEXCOORD_0": "accessor_27"
                     },
-                    "indices": "indices_21",
+                    "indices": "accessor_21",
                     "material": "blinn3-fx",
-                    "primitive": 4
+                    "mode": 4
                 }
             ]
         }
@@ -188,7 +182,7 @@
             "name": "LOD3sp"
         },
         "camera1": {
-            "camera": "camera_0",
+            "camera": "cameraShape1",
             "children": [],
             "matrix": [
                 -0.728969,
@@ -203,22 +197,21 @@
                 0.621148,
                 -0.571288,
                 0,
-                400.113,
-                463.264,
-                -431.078,
+                4.00113,
+                4.63264,
+                -4.31078,
                 1
             ],
             "name": "camera1"
         },
         "directionalLight1": {
             "children": [],
-            "light": "directionalLightShape1-lib",
             "matrix": [
                 -0.954692,
                 0.218143,
-                -0.202428,
+                -0.202429,
                 0,
-                0.0146721,
+                0.014672,
                 0.713885,
                 0.700109,
                 0,
@@ -226,15 +219,14 @@
                 0.665418,
                 -0.684741,
                 0,
-                148.654,
-                183.672,
-                -292.179,
+                1.48654,
+                1.83672,
+                -2.92179,
                 1
             ],
             "name": "directionalLight1"
         }
     },
-    "profile": "WebGL 1.0.2",
     "programs": {
         "program_0": {
             "attributes": [
@@ -266,15 +258,22 @@
     },
     "shaders": {
         "duck0FS": {
-            "path": "duck0FS.glsl"
+            "type": 35632,
+            "uri": "duck0FS.glsl"
         },
         "duck0VS": {
-            "path": "duck0VS.glsl"
+            "type": 35633,
+            "uri": "duck0VS.glsl"
         }
     },
     "skins": {},
     "techniques": {
-        "technique1": {
+        "technique0": {
+            "attributes": {
+                "a_normal": "normal",
+                "a_position": "position",
+                "a_texcoord0": "texcoord0"
+            },
             "parameters": {
                 "ambient": {
                     "type": 35666
@@ -294,7 +293,8 @@
                     ]
                 },
                 "light0Transform": {
-                    "source": "directionalLight1",
+                    "node": "directionalLight1",
+                    "semantic": "MODELVIEW",
                     "type": 35676
                 },
                 "modelViewMatrix": {
@@ -328,70 +328,35 @@
                     "type": 35664
                 }
             },
-            "pass": "defaultPass",
-            "passes": {
-                "defaultPass": {
-                    "details": {
-                        "commonProfile": {
-                            "extras": {
-                                "doubleSided": false
-                            },
-                            "lightingModel": "Blinn",
-                            "parameters": [
-                                "ambient",
-                                "diffuse",
-                                "emission",
-                                "light0Color",
-                                "light0Transform",
-                                "modelViewMatrix",
-                                "normalMatrix",
-                                "projectionMatrix",
-                                "shininess",
-                                "specular"
-                            ],
-                            "texcoordBindings": {
-                                "diffuse": "TEXCOORD_0"
-                            }
-                        },
-                        "type": "COLLADA-1.4.1/commonProfile"
-                    },
-                    "instanceProgram": {
-                        "attributes": {
-                            "a_normal": "normal",
-                            "a_position": "position",
-                            "a_texcoord0": "texcoord0"
-                        },
-                        "program": "program_0",
-                        "uniforms": {
-                            "u_ambient": "ambient",
-                            "u_diffuse": "diffuse",
-                            "u_emission": "emission",
-                            "u_light0Color": "light0Color",
-                            "u_light0Transform": "light0Transform",
-                            "u_modelViewMatrix": "modelViewMatrix",
-                            "u_normalMatrix": "normalMatrix",
-                            "u_projectionMatrix": "projectionMatrix",
-                            "u_shininess": "shininess",
-                            "u_specular": "specular"
-                        }
-                    },
-                    "states": {
-                        "blendEnable": 0,
-                        "cullFaceEnable": 1,
-                        "depthMask": 1,
-                        "depthTestEnable": 1
-                    }
-                }
+            "program": "program_0",
+            "states": {
+                "enable": [
+                    2929,
+                    2884
+                ]
+            },
+            "uniforms": {
+                "u_ambient": "ambient",
+                "u_diffuse": "diffuse",
+                "u_emission": "emission",
+                "u_light0Color": "light0Color",
+                "u_light0Transform": "light0Transform",
+                "u_modelViewMatrix": "modelViewMatrix",
+                "u_normalMatrix": "normalMatrix",
+                "u_projectionMatrix": "projectionMatrix",
+                "u_shininess": "shininess",
+                "u_specular": "specular"
             }
         }
     },
     "textures": {
-        "texture_image_0": {
+        "texture_file2": {
             "format": 6408,
             "internalFormat": 6408,
             "sampler": "sampler_0",
-            "source": "image_0",
-            "target": 3553
+            "source": "file2",
+            "target": 3553,
+            "type": 5121
         }
     }
 }

+ 14 - 13
examples/models/gltf/duck/duck0FS.glsl → examples/models/gltf/duck/glTF/duck0FS.glsl

@@ -1,13 +1,14 @@
 precision highp float;
 varying vec3 v_normal;
-uniform vec3 u_light0Color;
-varying vec3 v_light0Direction;
-uniform float u_shininess;
 uniform vec4 u_ambient;
 varying vec2 v_texcoord0;
 uniform sampler2D u_diffuse;
 uniform vec4 u_emission;
 uniform vec4 u_specular;
+uniform float u_shininess;
+varying vec3 v_light0Direction;
+varying vec3 v_position;
+uniform vec3 u_light0Color;
 void main(void) {
 vec3 normal = normalize(v_normal);
 vec4 color = vec4(0., 0., 0., 0.);
@@ -16,21 +17,21 @@ vec3 diffuseLight = vec3(0., 0., 0.);
 vec4 emission;
 vec4 ambient;
 vec4 specular;
+ambient = u_ambient;
+diffuse = texture2D(u_diffuse, v_texcoord0);
+emission = u_emission;
+specular = u_specular;
 vec3 specularLight = vec3(0., 0., 0.);
 {
-float diffuseIntensity;
-float specularIntensity;
+float specularIntensity = 0.;
+float attenuation = 1.0;
 vec3 l = normalize(v_light0Direction);
-vec3 h = normalize(l+vec3(0.,0.,1.));
-diffuseIntensity = max(dot(normal,l), 0.);
-specularIntensity = pow(max(0.0,dot(normal,h)),u_shininess);
+vec3 viewDir = -normalize(v_position);
+vec3 h = normalize(l+viewDir);
+specularIntensity = max(0., pow(max(dot(normal,h), 0.) , u_shininess)) * attenuation;
 specularLight += u_light0Color * specularIntensity;
-diffuseLight += u_light0Color * diffuseIntensity;
+diffuseLight += u_light0Color * max(dot(normal,l), 0.) * attenuation;
 }
-ambient = u_ambient;
-diffuse = texture2D(u_diffuse, v_texcoord0);
-emission = u_emission;
-specular = u_specular;
 specular.xyz *= specularLight;
 color.xyz += specular.xyz;
 diffuse.xyz *= diffuseLight;

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