소스 검색

Merge branch 'dev' into FBXLoader_fix_undefined_worldMatrices_map_error

Lewy Blue 7 년 전
부모
커밋
6cb3a02471
9개의 변경된 파일710개의 추가작업 그리고 624개의 파일을 삭제
  1. 56 29
      build/three.js
  2. 371 370
      build/three.min.js
  3. 56 29
      build/three.module.js
  4. 78 78
      docs/api/helpers/VertexNormalsHelper.html
  5. 32 13
      examples/js/loaders/ColladaLoader.js
  6. 68 83
      examples/js/loaders/FBXLoader.js
  7. 1 1
      examples/webgl_clipping_advanced.html
  8. 2 2
      package.json
  9. 46 19
      src/loaders/FileLoader.js

+ 56 - 29
build/three.js

@@ -10361,23 +10361,23 @@
 		}(),
 
 		rotateOnWorldAxis: function () {
-			
+
 			// rotate object on axis in world space
 			// axis is assumed to be normalized
 			// method assumes no rotated parent
 
 			var q1 = new Quaternion();
-			
+
 			return function rotateOnWorldAxis( axis, angle ) {
-			
+
 				q1.setFromAxisAngle( axis, angle );
-			
+
 				this.quaternion.premultiply( q1 );
-			
+
 				return this;
-			
+
 			};
-			
+
 		}(),
 
 		rotateX: function () {
@@ -21584,7 +21584,7 @@
 
 		// Clearing
 
-		this.getClearColor = function() {
+		this.getClearColor = function () {
 
 			return background.getClearColor();
 
@@ -21596,13 +21596,13 @@
 
 		};
 
-		this.getClearAlpha = function() {
+		this.getClearAlpha = function () {
 
 			return background.getClearAlpha();
 
 		};
 
-		this.setClearAlpha = function() {
+		this.setClearAlpha = function () {
 
 			background.setClearAlpha.apply( background, arguments );
 
@@ -30298,9 +30298,11 @@
 
 			if ( loading[ url ] !== undefined ) {
 
-				loading[ url ].push( function () {
+				loading[ url ].push( {
 
-					scope.load( url, onLoad, onProgress, onError );
+					onLoad: onLoad,
+					onProgress: onProgress,
+					onError: onError
 
 				} );
 
@@ -30403,6 +30405,14 @@
 
 				loading[ url ] = [];
 
+				loading[ url ].push( {
+
+					onLoad: onLoad,
+					onProgress: onProgress,
+					onError: onError
+
+				} );
+
 				var request = new XMLHttpRequest();
 
 				request.open( 'GET', url, true );
@@ -30413,9 +30423,18 @@
 
 					Cache.add( url, response );
 
+					var callbacks = loading[ url ];
+
+					delete loading[ url ];
+
 					if ( this.status === 200 ) {
 
-						if ( onLoad ) onLoad( response );
+						for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+							var callback = callbacks[ i ];
+							if ( callback.onLoad ) callback.onLoad( response );
+
+						}
 
 						scope.manager.itemEnd( url );
 
@@ -30426,46 +30445,54 @@
 
 						console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
 
-						if ( onLoad ) onLoad( response );
+						for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+							var callback = callbacks[ i ];
+							if ( callback.onLoad ) callback.onLoad( response );
+
+						}
 
 						scope.manager.itemEnd( url );
 
 					} else {
 
-						if ( onError ) onError( event );
+						for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+							var callback = callbacks[ i ];
+							if ( callback.onError ) callback.onError( event );
+
+						}
 
 						scope.manager.itemEnd( url );
 						scope.manager.itemError( url );
 
 					}
 
-					// Clean up duplicate requests.
+				}, false );
+
+				request.addEventListener( 'progress', function ( event ) {
 
 					var callbacks = loading[ url ];
 
-					for ( var i = 0; i < callbacks.length; i ++ ) {
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
 
-						callbacks[ i ]( response );
+						var callback = callbacks[ i ];
+						if ( callback.onProgress ) callback.onProgress( event );
 
 					}
 
-					delete loading[ url ];
-
 				}, false );
 
-				if ( onProgress !== undefined ) {
-
-					request.addEventListener( 'progress', function ( event ) {
-
-						onProgress( event );
+				request.addEventListener( 'error', function ( event ) {
 
-					}, false );
+					var callbacks = loading[ url ];
 
-				}
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
 
-				request.addEventListener( 'error', function ( event ) {
+						var callback = callbacks[ i ];
+						if ( callback.onError ) callback.onError( event );
 
-					if ( onError ) onError( event );
+					}
 
 					scope.manager.itemEnd( url );
 					scope.manager.itemError( url );

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 371 - 370
build/three.min.js


+ 56 - 29
build/three.module.js

@@ -10355,23 +10355,23 @@ Object.assign( Object3D.prototype, EventDispatcher.prototype, {
 	}(),
 
 	rotateOnWorldAxis: function () {
-		
+
 		// rotate object on axis in world space
 		// axis is assumed to be normalized
 		// method assumes no rotated parent
 
 		var q1 = new Quaternion();
-		
+
 		return function rotateOnWorldAxis( axis, angle ) {
-		
+
 			q1.setFromAxisAngle( axis, angle );
-		
+
 			this.quaternion.premultiply( q1 );
-		
+
 			return this;
-		
+
 		};
-		
+
 	}(),
 
 	rotateX: function () {
@@ -21578,7 +21578,7 @@ function WebGLRenderer( parameters ) {
 
 	// Clearing
 
-	this.getClearColor = function() {
+	this.getClearColor = function () {
 
 		return background.getClearColor();
 
@@ -21590,13 +21590,13 @@ function WebGLRenderer( parameters ) {
 
 	};
 
-	this.getClearAlpha = function() {
+	this.getClearAlpha = function () {
 
 		return background.getClearAlpha();
 
 	};
 
-	this.setClearAlpha = function() {
+	this.setClearAlpha = function () {
 
 		background.setClearAlpha.apply( background, arguments );
 
@@ -30292,9 +30292,11 @@ Object.assign( FileLoader.prototype, {
 
 		if ( loading[ url ] !== undefined ) {
 
-			loading[ url ].push( function () {
+			loading[ url ].push( {
 
-				scope.load( url, onLoad, onProgress, onError );
+				onLoad: onLoad,
+				onProgress: onProgress,
+				onError: onError
 
 			} );
 
@@ -30397,6 +30399,14 @@ Object.assign( FileLoader.prototype, {
 
 			loading[ url ] = [];
 
+			loading[ url ].push( {
+
+				onLoad: onLoad,
+				onProgress: onProgress,
+				onError: onError
+
+			} );
+
 			var request = new XMLHttpRequest();
 
 			request.open( 'GET', url, true );
@@ -30407,9 +30417,18 @@ Object.assign( FileLoader.prototype, {
 
 				Cache.add( url, response );
 
+				var callbacks = loading[ url ];
+
+				delete loading[ url ];
+
 				if ( this.status === 200 ) {
 
-					if ( onLoad ) onLoad( response );
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+						var callback = callbacks[ i ];
+						if ( callback.onLoad ) callback.onLoad( response );
+
+					}
 
 					scope.manager.itemEnd( url );
 
@@ -30420,46 +30439,54 @@ Object.assign( FileLoader.prototype, {
 
 					console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
 
-					if ( onLoad ) onLoad( response );
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+						var callback = callbacks[ i ];
+						if ( callback.onLoad ) callback.onLoad( response );
+
+					}
 
 					scope.manager.itemEnd( url );
 
 				} else {
 
-					if ( onError ) onError( event );
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+						var callback = callbacks[ i ];
+						if ( callback.onError ) callback.onError( event );
+
+					}
 
 					scope.manager.itemEnd( url );
 					scope.manager.itemError( url );
 
 				}
 
-				// Clean up duplicate requests.
+			}, false );
+
+			request.addEventListener( 'progress', function ( event ) {
 
 				var callbacks = loading[ url ];
 
-				for ( var i = 0; i < callbacks.length; i ++ ) {
+				for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
 
-					callbacks[ i ]( response );
+					var callback = callbacks[ i ];
+					if ( callback.onProgress ) callback.onProgress( event );
 
 				}
 
-				delete loading[ url ];
-
 			}, false );
 
-			if ( onProgress !== undefined ) {
-
-				request.addEventListener( 'progress', function ( event ) {
-
-					onProgress( event );
+			request.addEventListener( 'error', function ( event ) {
 
-				}, false );
+				var callbacks = loading[ url ];
 
-			}
+				for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
 
-			request.addEventListener( 'error', function ( event ) {
+					var callback = callbacks[ i ];
+					if ( callback.onError ) callback.onError( event );
 
-				if ( onError ) onError( event );
+				}
 
 				scope.manager.itemEnd( url );
 				scope.manager.itemError( url );

+ 78 - 78
docs/api/helpers/VertexNormalsHelper.html

@@ -1,79 +1,79 @@
-<!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:Line] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">
-			Renders [page:ArrowHelper arrows] to visualize an object's vertex normal vectors.
-			Requires that normals have been specified in a [page:BufferAttribute custom attribute] or
-			have been calculated using [page:Geometry.computeVertexNormals computeVertexNormals].<br /><br />
-
-			Unline [page:FaceNormalsHelper], this works with [page:BufferGeometry].
-		</div>
-
-		<h2>Example</h2>
-
-		[example:webgl_helpers WebGL / helpers]
-
-		<code>
-		var geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 );
-		var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
-		var box = new THREE.Mesh( geometry, material );
-
-		var helper = new THREE.VertexNormalsHelper( box, 2, 0x00ff00, 1 );
-
-		scene.add( box );
-		scene.add( helper );
-		</code>
-
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Object3D object], [page:Number size], [page:Hex color], [page:Number linewidth] )</h3>
-		<div>
-			[page:Object3D object] -- object for which to render vertex normals.<br />
-			[page:Number size] -- (optional) length of the arrows. Default is 1.<br />
-			[page:Hex color] -- hex color of the arrows. Default is 0xff0000.<br />
-			[page:Number linewidth] -- (optional) width of the arrow lines. Default is 1.
-		</div>
-
-
-		<h2>Properties</h2>
-		<div>See the base [page:LineSegments] class for common properties.</div>
-
-		<h3>[property:object matrixAutoUpdate]</h3>
-		<div>
-			See [page:Object3D.matrixAutoUpdate]. Set to *false* here as the helper is using the
-			objects's [page:Object3D.matrixWorld matrixWorld].
-		</div>
-
-		<h3>[property:Object3D object]</h3>
-		<div>The object for which the vertex normals are being visualized.</div>
-
-		<h3>[property:Number size]</h3>
-		<div>Length of the arrows. Default is *1*.</div>
-
-
-		<h2>Methods</h2>
-		<div>See the base [page:LineSegments] class for common methods.</div>
-
-
-		<h3>[method:null update]()</h3>
-		<div>Updates the vertex normal preview based on movement of the object.</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:Line] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+			Renders [page:ArrowHelper arrows] to visualize an object's vertex normal vectors.
+			Requires that normals have been specified in a [page:BufferAttribute custom attribute] or
+			have been calculated using [page:Geometry.computeVertexNormals computeVertexNormals].<br /><br />
+
+			Unlike [page:FaceNormalsHelper], this works with [page:BufferGeometry].
+		</div>
+
+		<h2>Example</h2>
+
+		[example:webgl_helpers WebGL / helpers]
+
+		<code>
+		var geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 );
+		var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
+		var box = new THREE.Mesh( geometry, material );
+
+		var helper = new THREE.VertexNormalsHelper( box, 2, 0x00ff00, 1 );
+
+		scene.add( box );
+		scene.add( helper );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]( [page:Object3D object], [page:Number size], [page:Hex color], [page:Number linewidth] )</h3>
+		<div>
+			[page:Object3D object] -- object for which to render vertex normals.<br />
+			[page:Number size] -- (optional) length of the arrows. Default is 1.<br />
+			[page:Hex color] -- hex color of the arrows. Default is 0xff0000.<br />
+			[page:Number linewidth] -- (optional) width of the arrow lines. Default is 1.
+		</div>
+
+
+		<h2>Properties</h2>
+		<div>See the base [page:LineSegments] class for common properties.</div>
+
+		<h3>[property:object matrixAutoUpdate]</h3>
+		<div>
+			See [page:Object3D.matrixAutoUpdate]. Set to *false* here as the helper is using the
+			objects's [page:Object3D.matrixWorld matrixWorld].
+		</div>
+
+		<h3>[property:Object3D object]</h3>
+		<div>The object for which the vertex normals are being visualized.</div>
+
+		<h3>[property:Number size]</h3>
+		<div>Length of the arrows. Default is *1*.</div>
+
+
+		<h2>Methods</h2>
+		<div>See the base [page:LineSegments] class for common methods.</div>
+
+
+		<h3>[method:null update]()</h3>
+		<div>Updates the vertex normal preview based on movement of the object.</div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

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

@@ -128,6 +128,12 @@ THREE.ColladaLoader.prototype = {
 
 		}
 
+		function generateId() {
+
+			return 'three_default_' + ( count ++ );
+
+		}
+
 		function isEmpty( object ) {
 
 			return Object.keys( object ).length === 0;
@@ -2719,6 +2725,26 @@ THREE.ColladaLoader.prototype = {
 
 		// nodes
 
+		function prepareNodes( xml ) {
+
+			var elements = xml.getElementsByTagName( 'node' );
+
+			// ensure all node elements have id attributes
+
+			for ( var i = 0; i < elements.length; i ++ ) {
+
+				var element = elements[ i ];
+
+				if ( element.hasAttribute( 'id' ) === false ) {
+
+					element.setAttribute( 'id', generateId() );
+
+				}
+
+			}
+
+		}
+
 		var matrix = new THREE.Matrix4();
 		var vector = new THREE.Vector3();
 
@@ -2748,14 +2774,8 @@ THREE.ColladaLoader.prototype = {
 				switch ( child.nodeName ) {
 
 					case 'node':
-
-						if ( child.hasAttribute( 'id' ) ) {
-
-							data.nodes.push( child.getAttribute( 'id' ) );
-							parseNode( child );
-
-						}
-
+						data.nodes.push( child.getAttribute( 'id' ) );
+						parseNode( child );
 						break;
 
 					case 'instance_camera':
@@ -2814,11 +2834,7 @@ THREE.ColladaLoader.prototype = {
 
 			}
 
-			if ( xml.hasAttribute( 'id' ) ) {
-
-				library.nodes[ xml.getAttribute( 'id' ) ] = data;
-
-			}
+			library.nodes[ data.id ] = data;
 
 			return data;
 
@@ -3220,6 +3236,8 @@ THREE.ColladaLoader.prototype = {
 				children: []
 			};
 
+			prepareNodes( xml );
+
 			var elements = getElementsByTagName( xml, 'node' );
 
 			for ( var i = 0; i < elements.length; i ++ ) {
@@ -3345,6 +3363,7 @@ THREE.ColladaLoader.prototype = {
 
 		var animations = [];
 		var kinematics = {};
+		var count = 0;
 
 		//
 

+ 68 - 83
examples/js/loaders/FBXLoader.js

@@ -262,14 +262,6 @@
 
 		if ( typeof content === 'string' ) {
 
-			// ASCII format sometimes an extra ',' gets added to the end of the content string
-			// TODO: Investigate why the parser is adding this character
-			if ( content.slice( - 1 ) === ',' ) {
-
-				content = content.slice( 0, - 1 );
-
-			}
-
 			return 'data:' + type + ';base64,' + content;
 
 		} else {
@@ -391,12 +383,6 @@
 
 			var values = textureNode.properties.Scaling.value;
 
-			if ( typeof values === 'string' ) {
-
-				values = parseFloatArray( values );
-
-			}
-
 			texture.repeat.x = values[ 0 ];
 			texture.repeat.y = values[ 1 ];
 
@@ -505,7 +491,7 @@
 
 		if ( properties.BumpFactor ) {
 
-			parameters.bumpScale = parseFloat( properties.BumpFactor.value );
+			parameters.bumpScale = properties.BumpFactor.value;
 
 		}
 		if ( properties.Diffuse ) {
@@ -515,12 +501,12 @@
 		}
 		if ( properties.DisplacementFactor ) {
 
-			parameters.displacementScale = parseFloat( properties.DisplacementFactor.value );
+			parameters.displacementScale = properties.DisplacementFactor.value;
 
 		}
 		if ( properties.ReflectionFactor ) {
 
-			parameters.reflectivity = parseFloat( properties.ReflectionFactor.value );
+			parameters.reflectivity = properties.ReflectionFactor.value;
 
 		}
 		if ( properties.Specular ) {
@@ -530,7 +516,7 @@
 		}
 		if ( properties.Shininess ) {
 
-			parameters.shininess = parseFloat( properties.Shininess.value );
+			parameters.shininess = properties.Shininess.value;
 
 		}
 		if ( properties.Emissive ) {
@@ -563,56 +549,44 @@
 			switch ( type ) {
 
 				case 'Bump':
-				case ' "Bump':
 					parameters.bumpMap = textureMap.get( relationship.ID );
 					break;
 
 				case 'DiffuseColor':
-				case ' "DiffuseColor':
 					parameters.map = textureMap.get( relationship.ID );
 					break;
 
 				case 'DisplacementColor':
-				case ' "DisplacementColor':
 					parameters.displacementMap = textureMap.get( relationship.ID );
 					break;
 
 
 				case 'EmissiveColor':
-				case ' "EmissiveColor':
 					parameters.emissiveMap = textureMap.get( relationship.ID );
 					break;
 
 				case 'NormalMap':
-				case ' "NormalMap':
 					parameters.normalMap = textureMap.get( relationship.ID );
 					break;
 
 				case 'ReflectionColor':
-				case ' "ReflectionColor':
 					parameters.envMap = textureMap.get( relationship.ID );
 					parameters.envMap.mapping = THREE.EquirectangularReflectionMapping;
 					break;
 
 				case 'SpecularColor':
-				case ' "SpecularColor':
 					parameters.specularMap = textureMap.get( relationship.ID );
 					break;
 
 				case 'TransparentColor':
-				case ' "TransparentColor':
 					parameters.alphaMap = textureMap.get( relationship.ID );
 					parameters.transparent = true;
 					break;
 
 				case 'AmbientColor':
-				case ' "AmbientColor':
 				case 'ShininessExponent': // AKA glossiness map
-				case ' "ShininessExponent':
 				case 'SpecularFactor': // AKA specularLevel
-				case ' "SpecularFactor':
 				case 'VectorDisplacementColor': // NOTE: Seems to be a copy of DisplacementColor
-				case ' "VectorDisplacementColor':
 				default:
 					console.warn( 'THREE.FBXLoader: %s map is not supported in three.js, skipping texture.', type );
 					break;
@@ -1062,6 +1036,27 @@
 
 		}
 
+		// the loop above doesn't add the last group, do that here.
+		if ( geo.groups.length > 0 ) {
+
+			var lastGroup = geo.groups[ geo.groups.length - 1 ];
+			var lastIndex = lastGroup.start + lastGroup.count;
+
+			if ( lastIndex !== materialIndexBuffer.length ) {
+
+				geo.addGroup( lastIndex, materialIndexBuffer.length - lastIndex, prevMaterialIndex );
+
+			}
+
+		}
+
+		// catch case where the whole geometry has a single non-zero index
+		if ( geo.groups.length === 0 && materialIndexBuffer[ 0 ] !== 0 ) {
+
+			geo.addGroup( 0, materialIndexBuffer.length, materialIndexBuffer[ 0 ] );
+
+		}
+
 		return geo;
 
 	}
@@ -1501,7 +1496,7 @@
 						} else {
 
 							var type = 0;
-							if ( cameraAttribute.CameraProjectionType !== undefined && ( cameraAttribute.CameraProjectionType.value === '1' || cameraAttribute.CameraProjectionType.value === 1 ) ) {
+							if ( cameraAttribute.CameraProjectionType !== undefined && cameraAttribute.CameraProjectionType.value === 1 ) {
 
 								type = 1;
 
@@ -1527,8 +1522,8 @@
 
 							if ( cameraAttribute.AspectWidth !== undefined && cameraAttribute.AspectHeight !== undefined ) {
 
-								width = parseFloat( cameraAttribute.AspectWidth.value );
-								height = parseFloat( cameraAttribute.AspectHeight.value );
+								width = cameraAttribute.AspectWidth.value;
+								height = cameraAttribute.AspectHeight.value;
 
 							}
 
@@ -1537,19 +1532,17 @@
 							var fov = 45;
 							if ( cameraAttribute.FieldOfView !== undefined ) {
 
-								fov = parseFloat( cameraAttribute.FieldOfView.value );
+								fov = cameraAttribute.FieldOfView.value;
 
 							}
 
 							switch ( type ) {
 
-								case '0': // Perspective
-								case 0:
+								case 0: // Perspective
 									model = new THREE.PerspectiveCamera( fov, aspect, nearClippingPlane, farClippingPlane );
 									break;
 
-								case '1': // Orthographic
-								case 1:
+								case 1: // Orthographic
 									model = new THREE.OrthographicCamera( - width / 2, width / 2, height / 2, - height / 2, nearClippingPlane, farClippingPlane );
 									break;
 
@@ -1611,20 +1604,14 @@
 
 							if ( lightAttribute.Color !== undefined ) {
 
-								var temp = lightAttribute.Color.value.split( ',' );
-
-								var r = parseFloat( temp[ 0 ] );
-								var g = parseFloat( temp[ 1 ] );
-								var b = parseFloat( temp[ 1 ] );
-
-								color = new THREE.Color( r, g, b );
+								color = parseColor( lightAttribute.Color.value );
 
 							}
 
 							var intensity = ( lightAttribute.Intensity === undefined ) ? 1 : lightAttribute.Intensity.value / 100;
 
 							// light disabled
-							if ( lightAttribute.CastLightOnObject !== undefined && ( lightAttribute.CastLightOnObject.value === '0' || lightAttribute.CastLightOnObject.value === 0 ) ) {
+							if ( lightAttribute.CastLightOnObject !== undefined && lightAttribute.CastLightOnObject.value === 0 ) {
 
 								intensity = 0;
 
@@ -1633,7 +1620,7 @@
 							var distance = 0;
 							if ( lightAttribute.FarAttenuationEnd !== undefined ) {
 
-								if ( lightAttribute.EnableFarAttenuation !== undefined && ( lightAttribute.EnableFarAttenuation.value === '0' || lightAttribute.EnableFarAttenuation.value === 0 ) ) {
+								if ( lightAttribute.EnableFarAttenuation !== undefined && lightAttribute.EnableFarAttenuation.value === 0 ) {
 
 									distance = 0;
 
@@ -1651,18 +1638,15 @@
 
 							switch ( type ) {
 
-								case '0': // Point
-								case 0:
+								case 0: // Point
 									model = new THREE.PointLight( color, intensity, distance, decay );
 									break;
 
-								case '1': // Directional
-								case 1:
+								case 1: // Directional
 									model = new THREE.DirectionalLight( color, intensity );
 									break;
 
-								case '2': // Spot
-								case 2:
+								case 2: // Spot
 									var angle = Math.PI / 3;
 
 									if ( lightAttribute.InnerAngle !== undefined ) {
@@ -1692,7 +1676,7 @@
 
 							}
 
-							if ( lightAttribute.CastShadows !== undefined && ( lightAttribute.CastShadows.value === '1' || lightAttribute.CastShadows.value === 1 ) ) {
+							if ( lightAttribute.CastShadows !== undefined && lightAttribute.CastShadows.value === 1 ) {
 
 								model.castShadow = true;
 
@@ -1745,7 +1729,7 @@
 
 						} else {
 
-							material = new THREE.MeshStandardMaterial( { color: 0x3300ff } );
+							material = new THREE.MeshPhongMaterial( { color: 0xcccccc } );
 							materials.push( material );
 
 						}
@@ -1818,13 +1802,13 @@
 
 			if ( 'Lcl_Translation' in node.properties ) {
 
-				model.position.fromArray( parseFloatArray( node.properties.Lcl_Translation.value ) );
+				model.position.fromArray( node.properties.Lcl_Translation.value );
 
 			}
 
 			if ( 'Lcl_Rotation' in node.properties ) {
 
-				var rotation = parseFloatArray( node.properties.Lcl_Rotation.value ).map( degreeToRadian );
+				var rotation = node.properties.Lcl_Rotation.value.map( degreeToRadian );
 				rotation.push( 'ZYX' );
 				model.rotation.fromArray( rotation );
 
@@ -1832,7 +1816,7 @@
 
 			if ( 'Lcl_Scaling' in node.properties ) {
 
-				model.scale.fromArray( parseFloatArray( node.properties.Lcl_Scaling.value ) );
+				model.scale.fromArray( node.properties.Lcl_Scaling.value );
 
 			}
 
@@ -1871,17 +1855,13 @@
 
 					var child = conns.children[ childrenIndex ];
 
-					if ( child.relationship === 'LookAtProperty' || child.relationship === ' "LookAtProperty' ) {
+					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.split( ',' ).map( function ( val ) {
-
-								return parseFloat( val );
-
-							} );
+							var pos = lookAtTarget.properties.Lcl_Translation.value;
 
 							// DirectionalLight, SpotLight
 							if ( model.target !== undefined ) {
@@ -2105,7 +2085,7 @@
 
 				if ( 'CustomFrameRate' in FBXTree.GlobalSettings.properties ) {
 
-					fps = parseFloat( FBXTree.GlobalSettings.properties.CustomFrameRate.value );
+					fps = FBXTree.GlobalSettings.properties.CustomFrameRate.value;
 
 					fps = ( fps === - 1 ) ? 30 : fps;
 
@@ -4146,7 +4126,7 @@
 					//	 "iVB..."
 					if ( propName === 'Content' && propValue === ',' ) {
 
-						propValue = split[ ++ lineNum ].replace( /"/g, '' ).trim();
+						propValue = split[ ++ lineNum ].replace( /"/g, '' ).replace( /,$/, '' ).trim();
 
 					}
 
@@ -4188,7 +4168,6 @@
 
 		parseNodeBegin: function ( line, nodeName, nodeAttrs ) {
 
-			// var nodeName = match[1];
 			var node = { 'name': nodeName, properties: {}, 'subNodes': {} };
 			var attrs = this.parseNodeAttr( nodeAttrs );
 			var currentNode = this.getCurrentNode();
@@ -4198,11 +4177,9 @@
 
 				this.allNodes.add( nodeName, node );
 
-			} else {
-
-				// a subnode
+			} else { // a subnode
 
-				// already exists subnode, then append it
+				// if the subnode already exists, append it
 				if ( nodeName in currentNode.subNodes ) {
 
 					var tmp = currentNode.subNodes[ nodeName ];
@@ -4248,6 +4225,7 @@
 
 			}
 
+
 			// for this		  ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
 			// NodeAttribute: 1001463072, "NodeAttribute::", "LimbNode" {
 			if ( nodeAttrs ) {
@@ -4297,8 +4275,8 @@
 			var currentNode = this.getCurrentNode();
 			var parentName = currentNode.name;
 
-			// special case parent node's is like "Properties70"
-			// these children nodes must treat with careful
+			// special case where the parent node is something like "Properties70"
+			// these children nodes must treated carefully
 			if ( parentName !== undefined ) {
 
 				var propMatch = parentName.match( /Properties(\d)+/ );
@@ -4311,7 +4289,7 @@
 
 			}
 
-			// special case Connections
+			// Connections
 			if ( propName === 'C' ) {
 
 				var connProps = propValue.split( ',' ).slice( 1 );
@@ -4320,6 +4298,12 @@
 
 				var rest = propValue.split( ',' ).slice( 3 );
 
+				rest = rest.map( function ( elem ) {
+
+					return elem.trim().replace( /^"/, '' );
+
+				} );
+
 				propName = 'connections';
 				propValue = [ from, to ];
 				append( propValue, rest );
@@ -4332,7 +4316,7 @@
 
 			}
 
-			// special case Connections
+			// Node
 			if ( propName === 'Node' ) {
 
 				var id = parseInt( propValue );
@@ -4357,7 +4341,6 @@
 
 			} else {
 
-				// console.log( propName + ":  " + propValue );
 				if ( Array.isArray( currentNode.properties[ propName ] ) ) {
 
 					currentNode.properties[ propName ].push( propValue );
@@ -4407,19 +4390,27 @@
 			}
 			*/
 
-			// cast value in its type
+			// cast value to its type
 			switch ( innerPropType1 ) {
 
 				case 'int':
+				case 'enum':
+				case 'bool':
+				case 'ULongLong':
 					innerPropValue = parseInt( innerPropValue );
 					break;
 
 				case 'double':
+				case 'Number':
+				case 'FieldOfView':
 					innerPropValue = parseFloat( innerPropValue );
 					break;
 
 				case 'ColorRGB':
 				case 'Vector3D':
+				case 'Lcl_Translation':
+				case 'Lcl_Rotation':
+				case 'Lcl_Scaling':
 					innerPropValue = parseFloatArray( innerPropValue );
 					break;
 
@@ -4671,12 +4662,6 @@
 
 					}
 
-					if ( innerPropType1.indexOf( 'Lcl_' ) === 0 ) {
-
-						innerPropValue = innerPropValue.toString();
-
-					}
-
 					// this will be copied to parent. see above.
 					properties[ innerPropName ] = {
 

+ 1 - 1
examples/webgl_clipping_advanced.html

@@ -117,7 +117,7 @@
 						xAxis.x, yAxis.x, zAxis.x, trans.x,
 						xAxis.y, yAxis.y, zAxis.y, trans.y,
 						xAxis.z, yAxis.z, zAxis.z, trans.z,
-							0,		0,		0,			1 );
+						0,	 0,	  0,	   1 );
 
 				};
 

+ 2 - 2
package.json

@@ -31,7 +31,7 @@
     "build-test": "rollup -c test/rollup.unit.config.js",
     "build-uglify": "rollup -c && uglifyjs build/three.js -cm --preamble \"// threejs.org/license\" > build/three.min.js",
     "build-closure": "rollup -c && java -jar node_modules/google-closure-compiler/compiler.jar --warning_level=VERBOSE --jscomp_off=globalThis --jscomp_off=checkTypes --externs utils/build/externs.js --language_in=ECMASCRIPT5_STRICT --js build/three.js --js_output_file build/three.min.js",
-    "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"http-server\"",
+    "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"serve --port 8080\"",
     "start": "npm run dev",
     "lint": "eslint src",
     "test": "rollup -c test/rollup.unit.config.js -w",
@@ -55,10 +55,10 @@
     "eslint": "^4.1.1",
     "eslint-config-mdcs": "^4.2.2",
     "google-closure-compiler": "^20170521.0.0",
-    "http-server": "^0.10.0",
     "qunitjs": "^2.1.1",
     "rollup": "^0.43.0",
     "rollup-watch": "^4.0.0",
+    "serve": "^6.3.1",
     "uglify-js": "^3.0.23"
   }
 }

+ 46 - 19
src/loaders/FileLoader.js

@@ -45,9 +45,11 @@ Object.assign( FileLoader.prototype, {
 
 		if ( loading[ url ] !== undefined ) {
 
-			loading[ url ].push( function () {
+			loading[ url ].push( {
 
-				scope.load( url, onLoad, onProgress, onError );
+				onLoad: onLoad,
+				onProgress: onProgress,
+				onError: onError
 
 			} );
 
@@ -150,6 +152,14 @@ Object.assign( FileLoader.prototype, {
 
 			loading[ url ] = [];
 
+			loading[ url ].push( {
+
+				onLoad: onLoad,
+				onProgress: onProgress,
+				onError: onError
+
+			} );
+
 			var request = new XMLHttpRequest();
 
 			request.open( 'GET', url, true );
@@ -160,9 +170,18 @@ Object.assign( FileLoader.prototype, {
 
 				Cache.add( url, response );
 
+				var callbacks = loading[ url ];
+
+				delete loading[ url ];
+
 				if ( this.status === 200 ) {
 
-					if ( onLoad ) onLoad( response );
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+						var callback = callbacks[ i ];
+						if ( callback.onLoad ) callback.onLoad( response );
+
+					}
 
 					scope.manager.itemEnd( url );
 
@@ -173,46 +192,54 @@ Object.assign( FileLoader.prototype, {
 
 					console.warn( 'THREE.FileLoader: HTTP Status 0 received.' );
 
-					if ( onLoad ) onLoad( response );
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+						var callback = callbacks[ i ];
+						if ( callback.onLoad ) callback.onLoad( response );
+
+					}
 
 					scope.manager.itemEnd( url );
 
 				} else {
 
-					if ( onError ) onError( event );
+					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
+
+						var callback = callbacks[ i ];
+						if ( callback.onError ) callback.onError( event );
+
+					}
 
 					scope.manager.itemEnd( url );
 					scope.manager.itemError( url );
 
 				}
 
-				// Clean up duplicate requests.
+			}, false );
+
+			request.addEventListener( 'progress', function ( event ) {
 
 				var callbacks = loading[ url ];
 
-				for ( var i = 0; i < callbacks.length; i ++ ) {
+				for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
 
-					callbacks[ i ]( response );
+					var callback = callbacks[ i ];
+					if ( callback.onProgress ) callback.onProgress( event );
 
 				}
 
-				delete loading[ url ];
-
 			}, false );
 
-			if ( onProgress !== undefined ) {
-
-				request.addEventListener( 'progress', function ( event ) {
-
-					onProgress( event );
+			request.addEventListener( 'error', function ( event ) {
 
-				}, false );
+				var callbacks = loading[ url ];
 
-			}
+				for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
 
-			request.addEventListener( 'error', function ( event ) {
+					var callback = callbacks[ i ];
+					if ( callback.onError ) callback.onError( event );
 
-				if ( onError ) onError( event );
+				}
 
 				scope.manager.itemEnd( url );
 				scope.manager.itemError( url );

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.