瀏覽代碼

Merge branch 'dev' into feat-loaders-text-decoding

Mr.doob 7 年之前
父節點
當前提交
2f1df3dc67

+ 3 - 3
docs/api/extras/core/Path.html

@@ -20,9 +20,9 @@
 		<h2>Example</h2>
 
 		<code>
-var v1 = new THREE.Vector3();
-var v2 = new THREE.Vector3(1, 45, 6);
-var v3 = new THREE.Vector3(34, 34, 676);
+var v1 = new THREE.Vector2();
+var v2 = new THREE.Vector2(1, 45);
+var v3 = new THREE.Vector2(34, 34);
 
 var vectors = [v1, v2, v3];
 

+ 2 - 2
docs/api/geometries/ConeBufferGeometry.html

@@ -42,11 +42,11 @@
 
 		<h2>Constructor</h2>
 
-		<h3>[name]([page:Float radius], [page:Float height], [page:Integer radiusSegments], [page:Integer heightSegments], [page:Boolean openEnded], [page:Float thetaStart], [page:Float thetaLength])</h3>
+		<h3>[name]([page:Float radius], [page:Float height], [page:Integer radialSegments], [page:Integer heightSegments], [page:Boolean openEnded], [page:Float thetaStart], [page:Float thetaLength])</h3>
 		<div>
 		radius — Radius of the cone base. Default is 20.<br />
 		height — Height of the cone. Default is 100.<br />
-		radiusSegments — Number of segmented faces around the circumference of the cone. Default is 8<br />
+		radialSegments — Number of segmented faces around the circumference of the cone. Default is 8<br />
 		heightSegments — Number of rows of faces along the height of the cone. Default is 1.<br />
 		openEnded — A Boolean indicating whether the base of the cone is open or capped. Default is false, meaning capped.<br />
 		thetaStart — Start angle for first segment, default = 0 (three o'clock position).<br />

+ 1 - 1
docs/api/geometries/ConeGeometry.html

@@ -46,7 +46,7 @@
 		<div>
 		radius — Radius of the cone at the base. Default is 20.<br />
 		height — Height of the cone. Default is 100.<br />
-		radiusSegments — Number of segmented faces around the circumference of the cone. Default is 8<br />
+		radialSegments — Number of segmented faces around the circumference of the cone. Default is 8<br />
 		heightSegments — Number of rows of faces along the height of the cone. Default is 1.<br />
 		openEnded — A Boolean indicating whether the base of the cone is open or capped. Default is false, meaning capped.<br />
 		thetaStart — Start angle for first segment, default = 0 (three o'clock position).<br />

+ 66 - 66
docs/api/geometries/CylinderBufferGeometry.html

@@ -1,67 +1,67 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!DOCTYPE html>
+<html lang="en">
+	<head>
 		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:BufferGeometry] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">This is the [page:BufferGeometry] port of [page:CylinderGeometry].</div>
-
-		<iframe id="scene" src="scenes/geometry-browser.html#CylinderBufferGeometry"></iframe>
-
-		<script>
-
-		// iOS iframe auto-resize workaround
-
-		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
-
-			var scene = document.getElementById( 'scene' );
-
-			scene.style.width = getComputedStyle( scene ).width;
-			scene.style.height = getComputedStyle( scene ).height;
-			scene.setAttribute( 'scrolling', 'no' );
-
-		}
-
-		</script>
-
-		<h2>Example</h2>
-
-		<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/geometries/CylinderGeometry.js src/geometries/CylinderGeometry.js]
-	</body>
-</html>
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is the [page:BufferGeometry] port of [page:CylinderGeometry].</div>
+
+		<iframe id="scene" src="scenes/geometry-browser.html#CylinderBufferGeometry"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>Example</h2>
+
+		<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 radialSegments], [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 />
+		radialSegments — 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/geometries/CylinderGeometry.js src/geometries/CylinderGeometry.js]
+	</body>
+</html>

+ 2 - 2
docs/api/geometries/CylinderGeometry.html

@@ -42,12 +42,12 @@
 
 		<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>
+		<h3>[name]([page:Float radiusTop], [page:Float radiusBottom], [page:Float height], [page:Integer radialSegments], [page:Integer heightSegments], [page:Boolean openEnded], [page:Float thetaStart], [page:Float thetaLength])</h3>
 		<div>
 		radiusTop — Radius of the cylinder at the top. Default is 1.<br />
 		radiusBottom — Radius of the cylinder at the bottom. Default is 1.<br />
 		height — Height of the cylinder. Default is 1.<br />
-		radiusSegments — Number of segmented faces around the circumference of the cylinder. Default is 8<br />
+		radialSegments — 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 />

+ 1 - 1
docs/api/geometries/ExtrudeBufferGeometry.html

@@ -140,6 +140,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		[link:https://github.com/mrdoob/three.js/blob/master/src/ExtrudeGeometry.js src/ExtrudeGeometry.js]
 	</body>
 </html>

+ 1 - 1
docs/api/geometries/TextBufferGeometry.html

@@ -155,6 +155,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		[link:https://github.com/mrdoob/three.js/blob/master/src/TextGeometry.js src/TextGeometry.js]
 	</body>
 </html>

+ 104 - 104
docs/api/geometries/TubeBufferGeometry.html

@@ -1,105 +1,105 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!DOCTYPE html>
+<html lang="en">
+	<head>
 		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:BufferGeometry] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">Creates a tube that extrudes along a 3d curve.</div>
-
-		<iframe id="scene" src="scenes/geometry-browser.html#TubeBufferGeometry"></iframe>
-
-		<script>
-
-		// iOS iframe auto-resize workaround
-
-		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
-
-			var scene = document.getElementById( 'scene' );
-
-			scene.style.width = getComputedStyle( scene ).width;
-			scene.style.height = getComputedStyle( scene ).height;
-			scene.setAttribute( 'scrolling', 'no' );
-
-		}
-
-		</script>
-
-		<h2>Example</h2>
-
-		<code>
-		function CustomSinCurve( scale ) {
-
-			THREE.Curve.call( this );
-
-			this.scale = ( scale === undefined ) ? 1 : scale;
-
-		}
-
-		CustomSinCurve.prototype = Object.create( THREE.Curve.prototype );
-		CustomSinCurve.prototype.constructor = CustomSinCurve;
-
-		CustomSinCurve.prototype.getPoint = function ( t ) {
-
-			var tx = t * 3 - 1.5;
-			var ty = Math.sin( 2 * Math.PI * t );
-			var tz = 0;
-
-			return new THREE.Vector3( tx, ty, tz ).multiplyScalar( this.scale );
-
-		};
-
-		var path = new CustomSinCurve( 10 );
-		var geometry = new THREE.TubeBufferGeometry( path, 20, 2, 8, false );
-		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
-		var mesh = new THREE.Mesh( geometry, material );
-		scene.add( mesh );
-		</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]([page:Curve path], [page:Integer tubularSegments], [page:Float radius], [page:Integer radiusSegments], [page:Boolean closed])</h3>
-		<div>
-		path — [page:Curve] - A path that inherits from the [page:Curve] base class<br />
-		tubularSegments — [page:Integer] - The number of segments that make up the tube, default is 64<br />
-		radius — [page:Float] - The radius of the tube, default is 1<br />
-		radiusSegments — [page:Integer] - The number of segments that make up the cross-section, default is 8 <br />
-		closed — [page:Boolean] Is the tube open or closed, default is false <br />
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>[property:Object parameters]</h3>
-		<div>
-		An object with all of the parameters that were used to generate the geometry.
-		</div>
-
-		<h3>[property:Array tangents]</h3>
-		<div>
-		An array of [page:Vector3] tangents
-		</div>
-
-		<h3>[property:Array normals]</h3>
-		<div>
-		An array of [page:Vector3] normals
-		</div>
-
-		<h3>[property:Array binormals]</h3>
-		<div>
-		An array of [page:Vector3] binormals
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js src/geometries/TubeGeometry.js]
-	</body>
-</html>
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">Creates a tube that extrudes along a 3d curve.</div>
+
+		<iframe id="scene" src="scenes/geometry-browser.html#TubeBufferGeometry"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>Example</h2>
+
+		<code>
+		function CustomSinCurve( scale ) {
+
+			THREE.Curve.call( this );
+
+			this.scale = ( scale === undefined ) ? 1 : scale;
+
+		}
+
+		CustomSinCurve.prototype = Object.create( THREE.Curve.prototype );
+		CustomSinCurve.prototype.constructor = CustomSinCurve;
+
+		CustomSinCurve.prototype.getPoint = function ( t ) {
+
+			var tx = t * 3 - 1.5;
+			var ty = Math.sin( 2 * Math.PI * t );
+			var tz = 0;
+
+			return new THREE.Vector3( tx, ty, tz ).multiplyScalar( this.scale );
+
+		};
+
+		var path = new CustomSinCurve( 10 );
+		var geometry = new THREE.TubeBufferGeometry( path, 20, 2, 8, false );
+		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+		var mesh = new THREE.Mesh( geometry, material );
+		scene.add( mesh );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Curve path], [page:Integer tubularSegments], [page:Float radius], [page:Integer radialSegments], [page:Boolean closed])</h3>
+		<div>
+		path — [page:Curve] - A path that inherits from the [page:Curve] base class<br />
+		tubularSegments — [page:Integer] - The number of segments that make up the tube, default is 64<br />
+		radius — [page:Float] - The radius of the tube, default is 1<br />
+		radialSegments — [page:Integer] - The number of segments that make up the cross-section, default is 8 <br />
+		closed — [page:Boolean] Is the tube open or closed, default is false <br />
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<div>
+		An object with all of the parameters that were used to generate the geometry.
+		</div>
+
+		<h3>[property:Array tangents]</h3>
+		<div>
+		An array of [page:Vector3] tangents
+		</div>
+
+		<h3>[property:Array normals]</h3>
+		<div>
+		An array of [page:Vector3] normals
+		</div>
+
+		<h3>[property:Array binormals]</h3>
+		<div>
+		An array of [page:Vector3] binormals
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js src/geometries/TubeGeometry.js]
+	</body>
+</html>

+ 104 - 104
docs/api/geometries/TubeGeometry.html

@@ -1,105 +1,105 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!DOCTYPE html>
+<html lang="en">
+	<head>
 		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:Geometry] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">Creates a tube that extrudes along a 3d curve.</div>
-
-		<iframe id="scene" src="scenes/geometry-browser.html#TubeGeometry"></iframe>
-
-		<script>
-
-		// iOS iframe auto-resize workaround
-
-		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
-
-			var scene = document.getElementById( 'scene' );
-
-			scene.style.width = getComputedStyle( scene ).width;
-			scene.style.height = getComputedStyle( scene ).height;
-			scene.setAttribute( 'scrolling', 'no' );
-
-		}
-
-		</script>
-
-		<h2>Example</h2>
-
-		<code>
-		function CustomSinCurve( scale ) {
-
-			THREE.Curve.call( this );
-
-			this.scale = ( scale === undefined ) ? 1 : scale;
-
-		}
-
-		CustomSinCurve.prototype = Object.create( THREE.Curve.prototype );
-		CustomSinCurve.prototype.constructor = CustomSinCurve;
-
-		CustomSinCurve.prototype.getPoint = function ( t ) {
-
-			var tx = t * 3 - 1.5;
-			var ty = Math.sin( 2 * Math.PI * t );
-			var tz = 0;
-
-			return new THREE.Vector3( tx, ty, tz ).multiplyScalar( this.scale );
-
-		};
-
-		var path = new CustomSinCurve( 10 );
-		var geometry = new THREE.TubeGeometry( path, 20, 2, 8, false );
-		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
-		var mesh = new THREE.Mesh( geometry, material );
-		scene.add( mesh );
-		</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]([page:Curve path], [page:Integer tubularSegments], [page:Float radius], [page:Integer radiusSegments], [page:Boolean closed])</h3>
-		<div>
-		path — [page:Curve] - A path that inherits from the [page:Curve] base class<br />
-		tubularSegments — [page:Integer] - The number of segments that make up the tube, default is 64<br />
-		radius — [page:Float] - The radius of the tube, default is 1<br />
-		radiusSegments — [page:Integer] - The number of segments that make up the cross-section, default is 8 <br />
-		closed — [page:Boolean] Is the tube open or closed, default is false <br />
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>[property:Object parameters]</h3>
-		<div>
-		An object with all of the parameters that were used to generate the geometry.
-		</div>
-
-		<h3>[property:Array tangents]</h3>
-		<div>
-		An array of [page:Vector3] tangents
-		</div>
-
-		<h3>[property:Array normals]</h3>
-		<div>
-		An array of [page:Vector3] normals
-		</div>
-
-		<h3>[property:Array binormals]</h3>
-		<div>
-		An array of [page:Vector3] binormals
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Geometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">Creates a tube that extrudes along a 3d curve.</div>
+
+		<iframe id="scene" src="scenes/geometry-browser.html#TubeGeometry"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script>
+
+		<h2>Example</h2>
+
+		<code>
+		function CustomSinCurve( scale ) {
+
+			THREE.Curve.call( this );
+
+			this.scale = ( scale === undefined ) ? 1 : scale;
+
+		}
+
+		CustomSinCurve.prototype = Object.create( THREE.Curve.prototype );
+		CustomSinCurve.prototype.constructor = CustomSinCurve;
+
+		CustomSinCurve.prototype.getPoint = function ( t ) {
+
+			var tx = t * 3 - 1.5;
+			var ty = Math.sin( 2 * Math.PI * t );
+			var tz = 0;
+
+			return new THREE.Vector3( tx, ty, tz ).multiplyScalar( this.scale );
+
+		};
+
+		var path = new CustomSinCurve( 10 );
+		var geometry = new THREE.TubeGeometry( path, 20, 2, 8, false );
+		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
+		var mesh = new THREE.Mesh( geometry, material );
+		scene.add( mesh );
+		</code>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Curve path], [page:Integer tubularSegments], [page:Float radius], [page:Integer radialSegments], [page:Boolean closed])</h3>
+		<div>
+		path — [page:Curve] - A path that inherits from the [page:Curve] base class<br />
+		tubularSegments — [page:Integer] - The number of segments that make up the tube, default is 64<br />
+		radius — [page:Float] - The radius of the tube, default is 1<br />
+		radialSegments — [page:Integer] - The number of segments that make up the cross-section, default is 8 <br />
+		closed — [page:Boolean] Is the tube open or closed, default is false <br />
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<h3>[property:Object parameters]</h3>
+		<div>
+		An object with all of the parameters that were used to generate the geometry.
+		</div>
+
+		<h3>[property:Array tangents]</h3>
+		<div>
+		An array of [page:Vector3] tangents
+		</div>
+
+		<h3>[property:Array normals]</h3>
+		<div>
+		An array of [page:Vector3] normals
+		</div>
+
+		<h3>[property:Array binormals]</h3>
+		<div>
+		An array of [page:Vector3] binormals
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 1 - 1
docs/api/objects/Mesh.html

@@ -67,7 +67,7 @@
 
 		<h3>[property:Material material]</h3>
 		<div>
-			An instance of material derived from the [page:Material] base class, defining the
+			An instance of material derived from the [page:Material] base class or an array of materials, defining the
 			object's appearance. Default is a [page:MeshBasicMaterial] with a random colour.
 		</div>
 

+ 1 - 1
docs/list.js

@@ -176,8 +176,8 @@ var list = {
 			"TorusGeometry": "api/geometries/TorusGeometry",
 			"TorusKnotBufferGeometry": "api/geometries/TorusKnotBufferGeometry",
 			"TorusKnotGeometry": "api/geometries/TorusKnotGeometry",
-			"TubeGeometry": "api/geometries/TubeGeometry",
 			"TubeBufferGeometry": "api/geometries/TubeBufferGeometry",
+			"TubeGeometry": "api/geometries/TubeGeometry",
 			"WireframeGeometry": "api/geometries/WireframeGeometry"
 		},
 

+ 1 - 0
examples/files.js

@@ -93,6 +93,7 @@ var files = {
 		"webgl_loader_json_blender",
 		"webgl_loader_json_claraio",
 		"webgl_loader_json_objconverter",
+		"webgl_loader_kmz",
 		"webgl_loader_md2",
 		"webgl_loader_md2_control",
 		"webgl_loader_mmd",

+ 8 - 2
examples/js/exporters/GLTFExporter.js

@@ -271,13 +271,19 @@ THREE.GLTFExporter.prototype = {
 
 				buffer: processBuffer( data, componentType, start, count ),
 				byteOffset: byteOffset,
-				byteLength: byteLength,
-				byteStride: data.itemSize * componentSize
+				byteLength: byteLength
 
 			};
 
 			if ( target !== undefined ) gltfBufferView.target = target;
 
+			if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
+
+				// Only define byteStride for vertex attributes.
+				gltfBufferView.byteStride = data.itemSize * componentSize;
+
+			}
+
 			byteOffset += byteLength;
 
 			outputJSON.bufferViews.push( gltfBufferView );

+ 178 - 158
examples/js/loaders/FBXLoader.js

@@ -103,9 +103,9 @@
 			var images = parseImages( FBXTree );
 			var textures = parseTextures( FBXTree, new THREE.TextureLoader( this.manager ).setPath( resourceDirectory ), images, connections );
 			var materials = parseMaterials( FBXTree, textures, connections );
-			var deformers = parseDeformers( FBXTree, connections );
-			var geometryMap = parseGeometries( FBXTree, connections, deformers );
-			var sceneGraph = parseScene( FBXTree, connections, deformers, geometryMap, materials );
+			var skeletons = parseDeformers( FBXTree, connections );
+			var geometryMap = parseGeometries( FBXTree, connections, skeletons );
+			var sceneGraph = parseScene( FBXTree, connections, skeletons, geometryMap, materials );
 
 			return sceneGraph;
 
@@ -310,7 +310,7 @@
 
 		var texture = loadTexture( textureNode, loader, imageMap, connections );
 
-		texture.FBX_ID = textureNode.id;
+		texture.ID = textureNode.id;
 
 		texture.name = textureNode.attrName;
 
@@ -419,7 +419,7 @@
 	// FBX format currently only supports Lambert and Phong shading models
 	function parseMaterial( FBXTree, materialNode, textureMap, connections ) {
 
-		var FBX_ID = materialNode.id;
+		var ID = materialNode.id;
 		var name = materialNode.attrName;
 		var type = materialNode.properties.ShadingModel;
 
@@ -431,9 +431,9 @@
 		}
 
 		// Ignore unused materials which don't have any connections.
-		if ( ! connections.has( FBX_ID ) ) return null;
+		if ( ! connections.has( ID ) ) return null;
 
-		var parameters = parseParameters( FBXTree, materialNode.properties, textureMap, FBX_ID, connections );
+		var parameters = parseParameters( FBXTree, materialNode.properties, textureMap, ID, connections );
 
 		var material;
 
@@ -461,8 +461,7 @@
 
 	// Parse FBX material and return parameters suitable for a three.js material
 	// Also parse the texture map and return any textures associated with the material
-	function parseParameters( FBXTree, properties, textureMap, FBX_ID, connections ) {
-
+	function parseParameters( FBXTree, properties, textureMap, ID, connections ) {
 
 		var parameters = {};
 
@@ -517,7 +516,7 @@
 
 		}
 
-		connections.get( FBX_ID ).children.forEach( function ( child ) {
+		connections.get( ID ).children.forEach( function ( child ) {
 
 			var type = child.relationship;
 
@@ -594,7 +593,7 @@
 	// Generates map of Skeleton-like objects for use later when generating and binding skeletons.
 	function parseDeformers( FBXTree, connections ) {
 
-		var deformers = {};
+		var skeletons = {};
 
 		if ( 'Deformer' in FBXTree.Objects.subNodes ) {
 
@@ -607,10 +606,14 @@
 				if ( deformerNode.attrType === 'Skin' ) {
 
 					var relationships = connections.get( parseInt( nodeID ) );
+
 					var skeleton = parseSkeleton( relationships, DeformerNodes );
-					skeleton.FBX_ID = parseInt( nodeID );
+					skeleton.ID = nodeID;
+
+					if ( relationships.parents.length > 1 ) console.warn( 'THREE.FBXLoader: skeleton attached to more than one geometry is not supported.' );
+					skeleton.geometryID = relationships.parents[ 0 ].ID;
 
-					deformers[ nodeID ] = skeleton;
+					skeletons[ nodeID ] = skeleton;
 
 				}
 
@@ -618,47 +621,51 @@
 
 		}
 
-		return deformers;
+		return skeletons;
 
 	}
 
 	// Parse single nodes in FBXTree.Objects.subNodes.Deformer
-	// Generates a "Skeleton Representation" of FBX nodes based on an FBX Skin Deformer's connections
-	// and an object containing SubDeformer nodes.
-	function parseSkeleton( connections, DeformerNodes ) {
+	// The top level deformer nodes have type 'Skin' and subDeformer nodes have type 'Cluster'
+	// Each skin node represents a skeleton and each cluster node represents a bone
+	function parseSkeleton( connections, deformerNodes ) {
 
-		var subDeformers = {};
+		var rawBones = [];
 
-		connections.children.forEach( function ( child, i ) {
+		connections.children.forEach( function ( child ) {
 
-			var subDeformerNode = DeformerNodes[ child.ID ];
+			var subDeformerNode = deformerNodes[ child.ID ];
 
-			var subDeformer = {
+			if ( subDeformerNode.attrType !== 'Cluster' ) return;
 
-				FBX_ID: child.ID,
-				index: i,
+			var rawBone = {
+
+				ID: child.ID,
 				indices: [],
 				weights: [],
+
+				// the global initial transform of the geometry node this bone is connected to
 				transform: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.Transform.properties.a ),
+
+				// the global initial transform of this bone
 				transformLink: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.TransformLink.properties.a ),
-				linkMode: subDeformerNode.properties.Mode,
 
 			};
 
 			if ( 'Indexes' in subDeformerNode.subNodes ) {
 
-				subDeformer.indices = subDeformerNode.subNodes.Indexes.properties.a;
-				subDeformer.weights = subDeformerNode.subNodes.Weights.properties.a;
+				rawBone.indices = subDeformerNode.subNodes.Indexes.properties.a;
+				rawBone.weights = subDeformerNode.subNodes.Weights.properties.a;
 
 			}
 
-			subDeformers[ child.ID ] = subDeformer;
+			rawBones.push( rawBone );
 
 		} );
 
 		return {
 
-			map: subDeformers,
+			rawBones: rawBones,
 			bones: []
 
 		};
@@ -666,7 +673,7 @@
 	}
 
 	// Parse nodes in FBXTree.Objects.subNodes.Geometry
-	function parseGeometries( FBXTree, connections, deformers ) {
+	function parseGeometries( FBXTree, connections, skeletons ) {
 
 		var geometryMap = new Map();
 
@@ -677,7 +684,7 @@
 			for ( var nodeID in geometryNodes ) {
 
 				var relationships = connections.get( parseInt( nodeID ) );
-				var geo = parseGeometry( FBXTree, relationships, geometryNodes[ nodeID ], deformers );
+				var geo = parseGeometry( FBXTree, relationships, geometryNodes[ nodeID ], skeletons );
 				geometryMap.set( parseInt( nodeID ), geo );
 
 			}
@@ -689,12 +696,12 @@
 	}
 
 	// Parse single node in FBXTree.Objects.subNodes.Geometry
-	function parseGeometry( FBXTree, relationships, geometryNode, deformers ) {
+	function parseGeometry( FBXTree, relationships, geometryNode, skeletons ) {
 
 		switch ( geometryNode.attrType ) {
 
 			case 'Mesh':
-				return parseMeshGeometry( FBXTree, relationships, geometryNode, deformers );
+				return parseMeshGeometry( FBXTree, relationships, geometryNode, skeletons );
 				break;
 
 			case 'NurbsCurve':
@@ -706,27 +713,25 @@
 	}
 
 	// Parse single node mesh geometry in FBXTree.Objects.subNodes.Geometry
-	function parseMeshGeometry( FBXTree, relationships, geometryNode, deformers ) {
-
-		var deformer = relationships.children.reduce( function ( deformer, child ) {
-
-			if ( deformers[ child.ID ] !== undefined ) deformer = deformers[ child.ID ];
-
-			return deformer;
-
-		}, null );
+	function parseMeshGeometry( FBXTree, relationships, geometryNode, skeletons ) {
 
 		var modelNodes = relationships.parents.map( function ( parent ) {
 
-			var modelNode = FBXTree.Objects.subNodes.Model[ parent.ID ];
-
-			return modelNode;
+			return FBXTree.Objects.subNodes.Model[ parent.ID ];
 
 		} );
 
 		// don't create geometry if it is not associated with any models
 		if ( modelNodes.length === 0 ) return;
 
+		var skeleton = relationships.children.reduce( function ( skeleton, child ) {
+
+			if ( skeletons[ child.ID ] !== undefined ) skeleton = skeletons[ child.ID ];
+
+			return skeleton;
+
+		}, null );
+
 		var preTransform = new THREE.Matrix4();
 
 		// TODO: if there is more than one model associated with the geometry, AND the models have
@@ -751,12 +756,12 @@
 
 		}
 
-		return genGeometry( FBXTree, relationships, geometryNode, deformer, preTransform );
+		return genGeometry( FBXTree, relationships, geometryNode, skeleton, preTransform );
 
 	}
 
 	// Generate a THREE.BufferGeometry from a node in FBXTree.Objects.subNodes.Geometry
-	function genGeometry( FBXTree, relationships, geometryNode, deformer, preTransform ) {
+	function genGeometry( FBXTree, relationships, geometryNode, skeleton, preTransform ) {
 
 		var subNodes = geometryNode.subNodes;
 
@@ -805,30 +810,25 @@
 
 		var weightTable = {};
 
-		if ( deformer ) {
-
-			var subDeformers = deformer.map;
+		if ( skeleton !== null ) {
 
-			for ( var key in subDeformers ) {
+			skeleton.rawBones.forEach( function ( rawBone, i ) {
 
-				var subDeformer = subDeformers[ key ];
-
-				subDeformer.indices.forEach( function ( index, i ) {
-
-					var weight = subDeformer.weights[ i ];
+				// loop over the bone's vertex indices and weights
+				rawBone.indices.forEach( function ( index, j ) {
 
 					if ( weightTable[ index ] === undefined ) weightTable[ index ] = [];
 
 					weightTable[ index ].push( {
 
-						id: subDeformer.index,
-						weight: weight
+						id: i,
+						weight: rawBone.weights[ j ],
 
 					} );
 
 				} );
 
-			}
+			} );
 
 		}
 
@@ -876,7 +876,7 @@
 
 			}
 
-			if ( deformer ) {
+			if ( skeleton ) {
 
 				if ( weightTable[ vertexIndex ] !== undefined ) {
 
@@ -999,7 +999,7 @@
 					vertexBuffer.push( vertexPositions[ vertexPositionIndexes[ i * 3 + 1 ] ] );
 					vertexBuffer.push( vertexPositions[ vertexPositionIndexes[ i * 3 + 2 ] ] );
 
-					if ( deformer ) {
+					if ( skeleton ) {
 
 						vertexWeightsBuffer.push( faceWeights[ 0 ] );
 						vertexWeightsBuffer.push( faceWeights[ 1 ] );
@@ -1126,14 +1126,14 @@
 
 		}
 
-		if ( deformer ) {
+		if ( skeleton ) {
 
 			geo.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( weightsIndicesBuffer, 4 ) );
 
 			geo.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( vertexWeightsBuffer, 4 ) );
 
 			// used later to bind the skeleton to the model
-			geo.FBX_Deformer = deformer;
+			geo.FBX_Deformer = skeleton;
 
 		}
 
@@ -1487,21 +1487,20 @@
 	}
 
 	// create the main THREE.Group() to be returned by the loader
-	function parseScene( FBXTree, connections, deformers, geometryMap, materialMap ) {
+	function parseScene( FBXTree, connections, skeletons, geometryMap, materialMap ) {
 
 		var sceneGraph = new THREE.Group();
 
-		var modelMap = parseModels( FBXTree, deformers, geometryMap, materialMap, connections );
+		var modelMap = parseModels( FBXTree, skeletons, geometryMap, materialMap, connections );
 
 		var modelNodes = FBXTree.Objects.subNodes.Model;
 
 		modelMap.forEach( function ( model ) {
 
-			var modelNode = modelNodes[ model.FBX_ID ];
-
-			setModelTransforms( FBXTree, model, modelNode, connections, sceneGraph );
+			var modelNode = modelNodes[ model.ID ];
+			setLookAtProperties( FBXTree, model, modelNode, connections, sceneGraph );
 
-			var parentConnections = connections.get( model.FBX_ID ).parents;
+			var parentConnections = connections.get( model.ID ).parents;
 
 			parentConnections.forEach( function ( connection ) {
 
@@ -1516,9 +1515,11 @@
 
 			}
 
+
 		} );
 
-		bindSkeleton( FBXTree, deformers, geometryMap, modelMap, connections, sceneGraph );
+
+		bindSkeleton( FBXTree, skeletons, geometryMap, modelMap, connections, sceneGraph );
 
 		addAnimations( FBXTree, connections, sceneGraph, modelMap );
 
@@ -1529,7 +1530,7 @@
 	}
 
 	// parse nodes in FBXTree.Objects.subNodes.Model
-	function parseModels( FBXTree, deformers, geometryMap, materialMap, connections ) {
+	function parseModels( FBXTree, skeletons, geometryMap, materialMap, connections ) {
 
 		var modelMap = new Map();
 		var modelNodes = FBXTree.Objects.subNodes.Model;
@@ -1539,37 +1540,8 @@
 			var id = parseInt( nodeID );
 			var node = modelNodes[ nodeID ];
 			var relationships = connections.get( id );
-			var model = null;
-
-			// create bones
-			relationships.parents.forEach( function ( parent ) {
-
-				for ( var FBX_ID in deformers ) {
-
-					var deformer = deformers[ FBX_ID ];
-					var subDeformers = deformer.map;
-					var subDeformer = subDeformers[ parent.ID ];
-
-					if ( subDeformer ) {
-
-						var model2 = model;
-						model = new THREE.Bone();
-						deformer.bones[ subDeformer.index ] = model;
-
-						// In cases where a bone is shared between multiple meshes
-						// model will already be defined and we'll hit this case
-						// TODO: currently doesn't work correctly
-						if ( model2 !== null ) {
-
-							model.add( model2 );
-
-						}
-
-					}
 
-				}
-
-			} );
+			var model = buildSkeleton( relationships, skeletons, id, node.attrName );
 
 			if ( ! model ) {
 
@@ -1587,17 +1559,20 @@
 					case 'NurbsCurve':
 						model = createCurve( relationships, geometryMap );
 						break;
+					case 'LimbNode': // usually associated with a Bone, however if a Bone was not created we'll make a Group instead
+					case 'Null':
 					default:
 						model = new THREE.Group();
 						break;
 
 				}
 
-			}
+				model.name = THREE.PropertyBinding.sanitizeNodeName( node.attrName );
+				model.ID = id;
 
-			model.name = THREE.PropertyBinding.sanitizeNodeName( node.attrName );
-			model.FBX_ID = id;
+			}
 
+			setModelTransforms( FBXTree, model, node );
 			modelMap.set( id, model );
 
 		}
@@ -1606,6 +1581,49 @@
 
 	}
 
+	function buildSkeleton( relationships, skeletons, id, name ) {
+
+		var bone = null;
+
+		relationships.parents.forEach( function ( parent ) {
+
+			for ( var ID in skeletons ) {
+
+				var skeleton = skeletons[ ID ];
+
+				skeleton.rawBones.forEach( function ( rawBone, i ) {
+
+					if ( rawBone.ID === parent.ID ) {
+
+						var subBone = bone;
+						bone = new THREE.Bone();
+
+						// set name and id here - otherwise in cases where "subBone" is created it will not have a name / id
+						bone.name = THREE.PropertyBinding.sanitizeNodeName( name );
+						bone.ID = id;
+
+						skeleton.bones[ i ] = bone;
+
+						// In cases where a bone is shared between multiple meshes
+						// duplicate the bone here and and it as a child of the first bone
+						if ( subBone !== null ) {
+
+							bone.add( subBone );
+
+						}
+
+					}
+
+				} );
+
+			}
+
+		} );
+
+		return bone;
+
+	}
+
 	// create a THREE.PerspectiveCamera or THREE.OrthographicCamera
 	function createCamera( FBXTree, relationships ) {
 
@@ -1924,8 +1942,46 @@
 
 	}
 
+	function setLookAtProperties( FBXTree, model, modelNode, connections, sceneGraph ) {
+
+		if ( 'LookAtProperty' in modelNode.properties ) {
+
+			var children = connections.get( model.ID ).children;
+
+			children.forEach( function ( child ) {
+
+				if ( child.relationship === 'LookAtProperty' ) {
+
+					var lookAtTarget = FBXTree.Objects.subNodes.Model[ child.ID ];
+
+					if ( 'Lcl_Translation' in lookAtTarget.properties ) {
+
+						var pos = lookAtTarget.properties.Lcl_Translation.value;
+
+						// DirectionalLight, SpotLight
+						if ( model.target !== undefined ) {
+
+							model.target.position.fromArray( pos );
+							sceneGraph.add( model.target );
+
+						} else { // Cameras and other Object3Ds
+
+							model.lookAt( new THREE.Vector3().fromArray( pos ) );
+
+						}
+
+					}
+
+				}
+
+			} );
+
+		}
+
+	}
+
 	// parse the model node for transform details and apply them to the model
-	function setModelTransforms( FBXTree, model, modelNode, connections, sceneGraph ) {
+	function setModelTransforms( FBXTree, model, modelNode ) {
 
 		// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
 		if ( 'RotationOrder' in modelNode.properties ) {
@@ -1991,43 +2047,9 @@
 
 		}
 
-		if ( 'LookAtProperty' in modelNode.properties ) {
-
-			var children = connections.get( model.FBX_ID ).children;
-
-			children.forEach( function ( child ) {
-
-				if ( child.relationship === 'LookAtProperty' ) {
-
-					var lookAtTarget = FBXTree.Objects.subNodes.Model[ child.ID ];
-
-					if ( 'Lcl_Translation' in lookAtTarget.properties ) {
-
-						var pos = lookAtTarget.properties.Lcl_Translation.value;
-
-						// DirectionalLight, SpotLight
-						if ( model.target !== undefined ) {
-
-							model.target.position.fromArray( pos );
-							sceneGraph.add( model.target );
-
-						} else { // Cameras and other Object3Ds
-
-							model.lookAt( new THREE.Vector3().fromArray( pos ) );
-
-						}
-
-					}
-
-				}
-
-			} );
-
-		}
-
 	}
 
-	function bindSkeleton( FBXTree, deformers, geometryMap, modelMap, connections, sceneGraph ) {
+	function bindSkeleton( FBXTree, skeletons, geometryMap, modelMap, connections, sceneGraph ) {
 
 		// Now with the bones created, we can update the skeletons and bind them to the skinned meshes.
 		sceneGraph.updateMatrixWorld( true );
@@ -2067,47 +2089,45 @@
 
 		}
 
-		for ( var FBX_ID in deformers ) {
+		for ( var ID in skeletons ) {
 
-			var deformer = deformers[ FBX_ID ];
-			var subDeformers = deformer.map;
+			var skeleton = skeletons[ ID ];
 
-			for ( var key in subDeformers ) {
+			skeleton.bones.forEach( function ( bone, i ) {
 
-				var subDeformer = subDeformers[ key ];
-				var subDeformerIndex = subDeformer.index;
+				// if the bone's initial transform is set in a poseNode, copy that
+				if ( worldMatrices.has( bone.ID ) ) {
 
-				var bone = deformer.bones[ subDeformerIndex ];
-				if ( ! worldMatrices.has( bone.FBX_ID ) ) {
+					var mat = worldMatrices.get( bone.ID );
+					bone.matrixWorld.copy( mat );
 
-					break;
+				}
+				// otherwise use the transform from the rawBone
+				else {
+
+					bone.matrixWorld.copy( skeleton.rawBones[ i ].transformLink )
 
 				}
-				var mat = worldMatrices.get( bone.FBX_ID );
-				bone.matrixWorld.copy( mat );
 
-			}
+			} );
 
 			// Now that skeleton is in bind pose, bind to model.
-			deformer.skeleton = new THREE.Skeleton( deformer.bones );
-
-			var relationships = connections.get( deformer.FBX_ID );
-			var parents = relationships.parents;
+			var parents = connections.get( parseInt( skeleton.ID ) ).parents;
 
 			parents.forEach( function ( parent ) {
 
 				if ( geometryMap.has( parent.ID ) ) {
 
 					var geoID = parent.ID;
-					var georelationships = connections.get( geoID );
+					var geoRelationships = connections.get( geoID );
 
-					georelationships.parents.forEach( function ( geoConnParent ) {
+					geoRelationships.parents.forEach( function ( geoConnParent ) {
 
 						if ( modelMap.has( geoConnParent.ID ) ) {
 
 							var model = modelMap.get( geoConnParent.ID );
 
-							model.bind( deformer.skeleton, model.matrixWorld );
+							model.bind( new THREE.Skeleton( skeleton.bones ), model.matrixWorld );
 
 						}
 

+ 77 - 40
examples/js/loaders/XLoader.js

@@ -237,14 +237,17 @@
 		}
 
 		createClass( XLoader, [ {
-			key: 'load',
-			value: function load( _arg, onLoad, onProgress, onError ) {
+			key: '_setArgOption',
+			value: function _setArgOption( _arg ) {
 
-				var _this = this;
+				var _start = arguments.length > 1 && arguments[ 1 ] !== undefined ? arguments[ 1 ] : 0;
 
-				var loader = new THREE.FileLoader( this.manager );
-				loader.setResponseType( 'arraybuffer' );
-				for ( var i = 0; i < _arg.length; i ++ ) {
+				if ( ! _arg ) {
+
+					return;
+
+				}
+				for ( var i = _start; i < _arg.length; i ++ ) {
 
 					switch ( i ) {
 
@@ -263,12 +266,78 @@
 					this.options = {};
 
 				}
+
+			}
+		}, {
+			key: 'load',
+			value: function load( _arg, onLoad, onProgress, onError ) {
+
+				var _this = this;
+
+				this._setArgOption( _arg );
+				var loader = new THREE.FileLoader( this.manager );
+				loader.setResponseType( 'arraybuffer' );
 				loader.load( this.url, function ( response ) {
 
 					_this._parse( response, onLoad );
 
 				}, onProgress, onError );
 
+			}
+		}, {
+			key: 'fromResponsedData',
+			value: function fromResponsedData( _data, _arg, onLoad ) {
+
+				this._setArgOption( _arg );
+				this._parse( _data, onLoad );
+
+			}
+		}, {
+			key: '_readLine',
+			value: function _readLine( line ) {
+
+				var readed = 0;
+				while ( true ) {
+
+					var find = - 1;
+					find = line.indexOf( '//', readed );
+					if ( find === - 1 ) {
+
+						find = line.indexOf( '#', readed );
+
+					}
+					if ( find > - 1 && find < 2 ) {
+
+						var foundNewLine = - 1;
+						foundNewLine = line.indexOf( "\r\n", readed );
+						if ( foundNewLine > 0 ) {
+
+							readed = foundNewLine + 2;
+
+						} else {
+
+							foundNewLine = line.indexOf( "\r", readed );
+							if ( foundNewLine > 0 ) {
+
+								readed = foundNewLine + 1;
+
+							} else {
+
+								readed = line.indexOf( "\n", readed ) + 1;
+
+							}
+
+						}
+
+					} else {
+
+						break;
+
+					}
+
+				}
+				return line.substr( readed );
+
 			}
 		}, {
 			key: '_readLine',
@@ -511,7 +580,6 @@
 
 				} else {
 
-					this._readFinalize();
 					setTimeout( function () {
 
 						_this2.onLoad( {
@@ -870,15 +938,7 @@
 			value: function _readNormalVector1( line ) {
 
 				var data = this._readLine( line.trim() ).substr( 0, line.length - 2 ).split( ";" );
-				if ( this.options.zflag ) {
-
-					this._currentGeo.normalVectors.push( new THREE.Vector3( parseFloat( data[ 0 ] ) * - 1, parseFloat( data[ 1 ] ) * - 1, parseFloat( data[ 2 ] ) * - 1 ) );
-
-				} else {
-
-					this._currentGeo.normalVectors.push( new THREE.Vector3( parseFloat( data[ 0 ] ), parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ) ) );
-
-				}
+				this._currentGeo.normalVectors.push( new THREE.Vector3( parseFloat( data[ 0 ] ), parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ) ) );
 
 			}
 		}, {
@@ -1059,15 +1119,7 @@
 				var _nowMat = new THREE.MeshPhongMaterial( {
 					color: Math.random() * 0xffffff
 				} );
-				if ( this.options.zflag ) {
-
-					_nowMat.side = THREE.BackSide;
-
-				} else {
-
-					_nowMat.side = THREE.FrontSide;
-
-				}
+				_nowMat.side = THREE.FrontSide;
 				_nowMat.name = this._currentObject.name;
 				var endRead = 0;
 				var find = this._currentObject.data.indexOf( ';;', endRead );
@@ -1527,21 +1579,6 @@
 				}
 				return put;
 
-			}
-		}, {
-			key: '_readFinalize',
-			value: function _readFinalize() {
-
-				if ( this.options.zflag ) {
-
-					for ( var i = 0; i < this.Meshes.length; i ++ ) {
-
-						this.Meshes[ i ].scale.set( - 1, 1, 1 );
-
-					}
-
-				}
-
 			}
 		}, {
 			key: '_ParseMatrixData',

二進制
examples/models/amf/rook.amf


二進制
examples/models/kmz/Box.kmz


+ 1 - 0
examples/models/kmz/Readme.txt

@@ -0,0 +1 @@
+Box.dae in Box.kmz is from https://github.com/KhronosGroup/glTF-Sample-Models

+ 2 - 0
examples/webgl_loader_amf.html

@@ -50,6 +50,8 @@
 		<script src="js/Detector.js"></script>
 		<script src="js/controls/OrbitControls.js"></script>
 
+		<script src="js/libs/jszip.min.js"></script>
+
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

+ 123 - 0
examples/webgl_loader_kmz.html

@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - KMZ</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				font-family: Monospace;
+				background-color: #000000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				z-index: 100;
+				display:block;
+
+			}
+
+			a { color: skyblue }
+			.button { background:#999; color:#eee; padding:0.2em 0.5em; cursor:pointer }
+			.highlight { background:orange; color:#fff; }
+
+			span {
+				display: inline-block;
+				width: 60px;
+				float: left;
+				text-align: center;
+			}
+
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a>
+			<a href="https://developers.google.com/kml/documentation/kmzarchives" target="_blank" rel="noopener">KMZ File format</a>
+		</div>
+
+		<script src="../build/three.js"></script>
+		<script src="js/loaders/KMZLoader.js"></script>
+		<script src="js/loaders/ColladaLoader.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/controls/OrbitControls.js"></script>
+
+		<script src="js/libs/jszip.min.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var camera, scene, renderer;
+
+			init();
+
+			function init() {
+
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0x999999 );
+
+				var light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( 0.5, 1.0, 0.5 ).normalize();
+
+				scene.add( light );
+
+				camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 500 );
+
+				camera.position.y = 5;
+				camera.position.z = 10;
+
+				scene.add( camera );
+
+				var grid = new THREE.GridHelper( 50, 50, 0xffffff, 0x555555 );
+				scene.add( grid );
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				var loader = new THREE.KMZLoader();
+				loader.load( './models/kmz/Box.kmz', function ( kmz ) {
+
+					kmz.scene.position.y = 0.5;
+					scene.add( kmz.scene );
+					render();
+
+				} );
+
+				var controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.addEventListener( 'change', render );
+				controls.update();
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				render();
+
+			}
+
+			function render() {
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 3 - 3
examples/webgl_loader_x.html

@@ -163,7 +163,7 @@
 
             //download Model file
 
-            loader.load( [ 'models/xfile/SSR06_model.x', { zflag: false } ], function ( object ) {
+            loader.load( [ 'models/xfile/SSR06_model.x' ], function ( object ) {
 
                 for ( var i = 0; i < object.models.length; i ++ ) {
 
@@ -245,7 +245,7 @@
             } else {
 
                 var loader2 = new THREE.XLoader( manager, Texloader );
-                loader2.load( [ 'models/xfile/' + animeName + '.x', { zflag: false, putPos: false, putScl: false } ], function () {
+                loader2.load( [ 'models/xfile/' + animeName + '.x', { putPos: false, putScl: false } ], function () {
 
                     // !! important!
                     // associate divided model and animation.
@@ -307,4 +307,4 @@
 
 </body>
 
-</html>
+</html>

+ 1 - 1
src/loaders/FileLoader.js

@@ -168,7 +168,7 @@ Object.assign( FileLoader.prototype, {
 
 			request.addEventListener( 'load', function ( event ) {
 
-				var response = event.target.response;
+				var response = this.response;
 
 				Cache.add( url, response );