瀏覽代碼

Merge remote-tracking branch 'mrdoob/dev' into dev

Trevor Blackwell 7 年之前
父節點
當前提交
093ac1aab8

+ 1 - 1
build/three.js

@@ -6199,7 +6199,7 @@
 
 
 	var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n";
 	var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n";
 
 
-	var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n";
+	var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n";
 
 
 	var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n";
 	var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n";
 
 

文件差異過大導致無法顯示
+ 1 - 1
build/three.min.js


+ 1 - 1
build/three.module.js

@@ -6193,7 +6193,7 @@ var normal_fragment = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPositio
 
 
 var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n";
 var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n";
 
 
-var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n";
+var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n";
 
 
 var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n";
 var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n";
 
 

+ 18 - 10
docs/examples/loaders/BabylonLoader.html

@@ -8,10 +8,12 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">A loader for loading a <em>.babylon</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.babylon</em> resource. <br />
+		The <a href="https://doc.babylonjs.com/generals/file_format_map_(.babylon)"> .babylon </a> file format used by
+		<a href="https://www.babylonjs.com/">Babylon.js</a>.
+		</div>
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
@@ -23,17 +25,23 @@
 		loader.load(
 		loader.load(
 			// resource URL
 			// resource URL
 			'models/babylon/skull.babylon',
 			'models/babylon/skull.babylon',
-			// Function when resource is loaded
+			// called when resource is loaded
 			function ( object ) {
 			function ( object ) {
+
 				scene.add( object );
 				scene.add( object );
+
 			},
 			},
-			// Function called when download progresses
+			// called when loading is in progress
 			function ( xhr ) {
 			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
 			},
 			},
-			// Function called when download errors
+			// called when loading has errors
 			function ( xhr ) {
 			function ( xhr ) {
+
 				console.log( 'An error happened' );
 				console.log( 'An error happened' );
+
 			}
 			}
 		);
 		);
 		</code>
 		</code>
@@ -57,10 +65,10 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-		[page:String url] — required<br />
-		[page:function onLoad] — Will be called when load completes. The argument will be the loaded [page:Object3D].<br />
-		[page:function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.babylon</em> file.<br />
+		[page:function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.<br />
+		[page:function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.
 		Begin loading from url and call onLoad with the parsed response content.

+ 37 - 20
docs/examples/loaders/GLTFLoader.html

@@ -11,9 +11,7 @@
 		[page:Loader] &rarr;
 		[page:Loader] &rarr;
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">
-		A loader for *glTF* 2.0 resources.
-		<br /><br />
+		<div class="desc"> A loader for loading <em>glTF 2.0</em> resource. <br />
 		<a href="https://www.khronos.org/gltf">glTF</a> (GL Transmission Format) is an
 		<a href="https://www.khronos.org/gltf">glTF</a> (GL Transmission Format) is an
 		<a href="https://github.com/KhronosGroup/glTF/tree/master/specification/2.0">open format specification</a>
 		<a href="https://github.com/KhronosGroup/glTF/tree/master/specification/2.0">open format specification</a>
 		for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
 		for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
@@ -48,19 +46,38 @@
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
 		<code>
 		<code>
-		// Instantiate a loader
-		var loader = new THREE.GLTFLoader();
-
-		// Load a glTF resource
-		loader.load( 'models/gltf/duck/duck.gltf', function ( gltf ) {
-			scene.add( gltf.scene );
-
-			gltf.animations; // Array&lt;THREE.AnimationClip&gt;
-			gltf.scene;      // THREE.Scene
-			gltf.scenes;     // Array&lt;THREE.Scene&gt;
-			gltf.cameras;    // Array&lt;THREE.Camera&gt;
-		} );
-		</code>
+			// Instantiate a loader
+			var loader = new THREE.GLTFLoader();
+	
+			// Load a glTF resource
+			loader.load(
+				// resource URL
+				'models/gltf/duck/duck.gltf',
+				// called when the resource is loaded
+				function ( gltf ) {
+	
+					scene.add( gltf.scene );
+	
+					gltf.animations; // Array&lt;THREE.AnimationClip&gt;
+					gltf.scene; // THREE.Scene
+					gltf.scenes; // Array&lt;THREE.Scene&gt;
+					gltf.cameras; // Array&lt;THREE.Camera&gt;
+	
+				},
+				// called when loading is in progresses
+				function ( xhr ) {
+	
+					console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+	
+				},
+				// called when loading has errors
+				function ( error ) {
+	
+					console.log( 'An error happened' );
+	
+				}
+			);
+			</code>
 
 
 		[example:webgl_loader_gltf]
 		[example:webgl_loader_gltf]
 
 
@@ -81,10 +98,10 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded JSON response returned from [page:Function parse].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.gltf</em> or <em>.glb</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after the loading is successfully completed. The function receives the loaded JSON response returned from [page:Function parse].<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 		Begin loading from url and call the callback function with the parsed response content.
 		Begin loading from url and call the callback function with the parsed response content.

+ 9 - 6
docs/examples/loaders/MTLLoader.html

@@ -11,7 +11,10 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJMTLLoader] and [page:UTF8Loader].</div>
+		<div class="desc">A loader for loading an <em>.mtl</em> resource, used internaly by [page:OBJMTLLoader] and [page:UTF8Loader].<br />
+		The Material Template Library format (MTL) or .MTL File Format is a companion file format to .OBJ that describes surface shading
+		(material) properties of objects within one or more .OBJ files. 		
+		</div>
 
 
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
@@ -23,7 +26,7 @@
 			Creates a new [name].
 			Creates a new [name].
 		</div>
 		</div>
 
 
-		<!-- <h2>Properties</h2> -->
+		<h2>Properties</h2>
 
 
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>
@@ -31,10 +34,10 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-			[page:String url] — required<br />
-			[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator] instance.<br />
-			[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-			[page:Function onError] — Will be called when load errors.<br />
+			[page:String url] — A string containing the path/URL of the <em>.mtl</em> file.<br />
+			[page:Function onLoad] — (optional) A function to be called after the loading is successfully completed. The function receives the loaded [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator] instance.<br />
+			[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+			[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 			Begin loading from url and return the loaded material.
 			Begin loading from url and return the loaded material.

+ 25 - 6
docs/examples/loaders/OBJLoader.html

@@ -11,7 +11,12 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">A loader for loading an <em>.obj</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.obj</em> resource.<br />
+		The <a href="https://en.wikipedia.org/wiki/Wavefront_.obj_file">OBJ file format</a> is a simple data-format 
+		that represents 3D geometry in a human redeable format as, the position of each vertex, the UV position of 
+		each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of 
+		vertices, and texture vertices.
+		</div>
 
 
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
@@ -24,9 +29,23 @@
 		loader.load(
 		loader.load(
 			// resource URL
 			// resource URL
 			'models/monster.obj',
 			'models/monster.obj',
-			// Function when resource is loaded
+			// called when resource is loaded
 			function ( object ) {
 			function ( object ) {
+
 				scene.add( object );
 				scene.add( object );
+
+			},
+			// called when loading is in progresses
+			function ( xhr ) {
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
+			},
+			// called when loading has errors
+			function ( error ) {
+
+				console.log( 'An error happened' );
+
 			}
 			}
 		);
 		);
 		</code>
 		</code>
@@ -51,10 +70,10 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-		[page:String url] — A string representing the path to the obj file. Required.<br />
-		[page:Function onLoad] — A function to be called when the load completes. The function receives loaded [page:Object3D] as an argument.<br />
-		[page:Function onProgress] — A function to be called while the loading is in progress. The function receives a XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — A function to be called if the request fails. The function receives the error.<br />
+		[page:String url] — A string containing the path/URL of the <em>.obj</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after the loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The function receives a XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.
 		Begin loading from url and call onLoad with the parsed response content.

+ 13 - 8
docs/examples/loaders/OBJLoader2.html

@@ -11,7 +11,12 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">A loader for loading an <em>.obj</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.obj</em> resource. <br />
+		The <a href="https://en.wikipedia.org/wiki/Wavefront_.obj_file">OBJ file format</a> is a simple data-format 
+		that represents 3D geometry in a human redeable format as, the position of each vertex, the UV position of 
+		each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of 
+		vertices, and texture vertices.
+		</div>
 
 
 		<h2>Examples</h2>
 		<h2>Examples</h2>
 
 
@@ -67,15 +72,15 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError], [page:Function onMeshAlter], [page:boolean useAsync] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError], [page:Function onMeshAlter], [page:boolean useAsync] )</h3>
 		<div>
 		<div>
-			[page:String url] - URL of the file to load<br>
-			[page:Function onLoad] - Called after loading was successfully completed<br>
-			[page:Function onProgress] - Called to report progress of loading. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br>
-			[page:Function onError] - Called after an error occurred during loading.<br>
-			[page:Function onMeshAlter] - Called after a new mesh raw data becomes available to allow alteration<br>
-			[page:boolean useAsync] - If true uses async loading with worker, if false loads data synchronously
+			[page:String url] - A string containing the path/URL of the <em>.obj</em> file.<br>
+			[page:Function onLoad] - (optional) A function to be called after loading is successfully completed. The function receives loaded [page:Object3D] as an argument.<br>
+			[page:Function onProgress] - (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br>
+			[page:Function onError] - (optional) A function to be called if an error occurrs during loading. The function receives the error as an argument.<br>
+			[page:Function onMeshAlter] - (optional) A function to be called after a new mesh raw data becomes available for alteration.<br>
+			[page:boolean useAsync] - (optional) If true, uses async loading with worker, if false loads data synchronously.
 		</div>
 		</div>
 		<div>
 		<div>
-			Use this convenient method to load an OBJ file at the given URL. Per default the fileLoader uses an arraybuffer.
+			Use this convenient method to load an OBJ file at the given URL. By default the fileLoader uses an arraybuffer.
 		</div>
 		</div>
 
 
 
 

+ 24 - 8
docs/examples/loaders/PCDLoader.html

@@ -11,8 +11,10 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">A loader for <em>PCD</em> files. Loads ascii and binary.
-			Compressed binary files are not supported.</div>
+		<div class="desc">A loader for loading a <em>.pcd</em> resource. <br />
+		Point Cloud Data is a file format for <a href="https://en.wikipedia.org/wiki/Point_Cloud_Library">Point Cloud Library</a>. <br />
+		Loader support ascii and binary. Compressed binary files are not supported.
+		</div>
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
@@ -24,10 +26,24 @@
 		// load a resource
 		// load a resource
 		loader.load(
 		loader.load(
 			// resource URL
 			// resource URL
-			'pointcloud.pcd' ,
-			// Function when resource is loaded
+			'pointcloud.pcd',
+			// called when the resource is loaded
 			function ( mesh ) {
 			function ( mesh ) {
+
 				scene.add( mesh );
 				scene.add( mesh );
+
+			},
+			// called when loading is in progresses
+			function ( xhr ) {
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
+			},
+			// called when loading has errors
+			function ( error ) {
+
+				console.log( 'An error happened' );
+
 			}
 			}
 		);
 		);
 		</code>
 		</code>
@@ -56,10 +72,10 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Object3D].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.pcd</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives loaded [page:Object3D] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.
 		Begin loading from url and call onLoad with the parsed response content.

+ 16 - 13
docs/examples/loaders/PDBLoader.html

@@ -11,10 +11,8 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">
-		A loader for loading a <em>.pdb</em> resource.
-		<br /><br />
-		The <a href="http://en.wikipedia.org/wiki/Protein_Data_Bank_(file_format)">Protein Data Bank file format</a> is a textual file format describing the three-dimensional structures of molecules.
+		<div class="desc">A loader for loading a <em>.pdb</em> resource.<br>
+		The <a href="http://en.wikipedia.org/wiki/Protein_Data_Bank_(file_format)">Protein Data Bank</a> file format is a textual file describing the three-dimensional structures of molecules.
 		</div>
 		</div>
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
@@ -27,7 +25,7 @@
 		loader.load(
 		loader.load(
 			// resource URL
 			// resource URL
 			'models/molecules/caffeine.pdb',
 			'models/molecules/caffeine.pdb',
-			// Function when resource is loaded
+			// called when the resource is loaded
 			function ( pdb ) {
 			function ( pdb ) {
 
 
 				var geometryAtoms = pdb.geometryAtoms;
 				var geometryAtoms = pdb.geometryAtoms;
@@ -35,14 +33,19 @@
 				var json = pdb.json;
 				var json = pdb.json;
 
 
 				console.log( 'This molecule has ' + json.atoms.length + ' atoms' );
 				console.log( 'This molecule has ' + json.atoms.length + ' atoms' );
+
 			},
 			},
-			// Function called when download progresses
+			// called when loading is in progresses
 			function ( xhr ) {
 			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
 			},
 			},
-			// Function called when download errors
-			function ( xhr ) {
+			// called when loading has errors
+			function ( error ) {
+
 				console.log( 'An error happened' );
 				console.log( 'An error happened' );
+
 			}
 			}
 		);
 		);
 		</code>
 		</code>
@@ -67,10 +70,10 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-		[page:String url] — required. URL to the <em>.pdb</em> file<br />
-		[page:Function onLoad] — Will be called when load completes. The arguments will be an [page:BufferGeometry geometryAtoms], [page:BufferGeometry geometryBonds] and the [page:Object JSON] structure.<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.pdb</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the object having the following properties. [page:BufferGeometry geometryAtoms], [page:BufferGeometry geometryBonds] and the [page:Object JSON] structure.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 		Begin loading from url and call onLoad with the parsed response content.
 		Begin loading from url and call onLoad with the parsed response content.

+ 43 - 5
docs/examples/loaders/SVGLoader.html

@@ -11,9 +11,47 @@
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">A loader for loading an <em>.svg</em> resource.</div>
+		<div class="desc">A loader for loading a <em>.svg</em> resource.<br >
+		<a href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">Scalabe Vector Graphics</a> is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.			
+		</div>
+
+		<h2>Example</h2>
+		
+		<code>
+		// instantiate a loader
+		var loader = new THREE.PDBLoader();
+
+		// load a PDB resource
+		loader.load(
+			// resource URL
+			'models/molecules/caffeine.pdb',
+			// called when the resource is loaded
+			function ( pdb ) {
+
+				var geometryAtoms = pdb.geometryAtoms;
+				var geometryBonds = pdb.geometryBonds;
+				var json = pdb.json;
+
+				console.log( 'This molecule has ' + json.atoms.length + ' atoms' );
+
+			},
+			// called when loading is in progresses
+			function ( xhr ) {
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
+			},
+			// called when loading has errors
+			function ( error ) {
+
+				console.log( 'An error happened' );
 
 
+			}
+		);
+		</code>
 
 
+		[example:webgl_loader_svg]
+		
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
 		<h3>[name]( [page:LoadingManager manager] )</h3>
 		<h3>[name]( [page:LoadingManager manager] )</h3>
@@ -31,10 +69,10 @@
 
 
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:null load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:SVGDocument].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.svg</em> file.<br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:SVGDocument] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 		Begin loading from url and call onLoad with the response content.
 		Begin loading from url and call onLoad with the response content.

+ 19 - 12
docs/examples/loaders/TGALoader.html

@@ -10,8 +10,9 @@
 	<body>
 	<body>
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">Class for loading a <em>.tga</em> [page:DataTexture texture].</div>
-
+		<div class="desc">A loader for loading a <em>.tga</em> resource. <br />
+		<a href="https://en.wikipedia.org/wiki/Truevision_TGA">TGA</a> is a raster graphics, image file format.
+		</div>
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
@@ -23,20 +24,26 @@
 		var texture = loader.load(
 		var texture = loader.load(
 			// resource URL
 			// resource URL
 			'textures/crate_grey8.tga'
 			'textures/crate_grey8.tga'
-			// Function when resource is loaded
+			// called when loading is completed
 			function ( texture ) {
 			function ( texture ) {
+
 				console.log( 'Texture is loaded' );
 				console.log( 'Texture is loaded' );
+
 			},
 			},
-			// Function called when download progresses
+			// called when the loading is in progresses
 			function ( xhr ) {
 			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+
 			},
 			},
-			// Function called when download errors
-			function ( xhr ) {
+			// called when the loading failes
+			function ( error ) {
+
 				console.log( 'An error happened' );
 				console.log( 'An error happened' );
+
 			}
 			}
 		);
 		);
-
+		
 		var material = new THREE.MeshPhongMaterial( {
 		var material = new THREE.MeshPhongMaterial( {
 			color: 0xffffff,
 			color: 0xffffff,
 			map: texture
 			map: texture
@@ -60,10 +67,10 @@
 
 
 		<h3>[method:DataTexture load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<h3>[method:DataTexture load]( [page:String url], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
 		<div>
 		<div>
-		[page:String url] — required<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:DataTexture].<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
+		[page:String url] — A string containing the path/URL of the <em>.tga</em> file. <br />
+		[page:Function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives loaded [page:DataTexture] as an argument.<br />
+		[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
+		[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.<br />
 		</div>
 		</div>
 		<div>
 		<div>
 		Begin loading from url and pass the loaded [page:DataTexture texture] to onLoad. The [page:DataTexture texture] is also directly returned for immediate use (but may not be fully loaded).
 		Begin loading from url and pass the loaded [page:DataTexture texture] to onLoad. The [page:DataTexture texture] is also directly returned for immediate use (but may not be fully loaded).

+ 1 - 1
examples/js/shaders/SAOShader.js

@@ -102,7 +102,7 @@ THREE.SAOShader = {
 
 
 		"vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {",
 		"vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {",
 		"	#if NORMAL_TEXTURE == 1",
 		"	#if NORMAL_TEXTURE == 1",
-		"	return -unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );",
+		"	return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );",
 		"	#else",
 		"	#else",
 		"	return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );",
 		"	return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );",
 		"	#endif",
 		"	#endif",

+ 1 - 1
src/renderers/shaders/ShaderChunk/packing.glsl

@@ -3,7 +3,7 @@ vec3 packNormalToRGB( const in vec3 normal ) {
 }
 }
 
 
 vec3 unpackRGBToNormal( const in vec3 rgb ) {
 vec3 unpackRGBToNormal( const in vec3 rgb ) {
-	return 1.0 - 2.0 * rgb.xyz;
+	return 2.0 * rgb.xyz - 1.0;
 }
 }
 
 
 const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
 const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)

+ 114 - 98
utils/exporters/blender/addons/io_three/__init__.py

@@ -636,14 +636,14 @@ class ExportThree(bpy.types.Operator, ExportHelper):
         default=constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
         default=constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
 
 
     option_round_value = IntProperty(
     option_round_value = IntProperty(
-        name="Precision",
+        name="",
         min=0,
         min=0,
         max=16,
         max=16,
         description="Floating point precision",
         description="Floating point precision",
         default=constants.EXPORT_OPTIONS[constants.PRECISION])
         default=constants.EXPORT_OPTIONS[constants.PRECISION])
 
 
     option_custom_properties = BoolProperty(
     option_custom_properties = BoolProperty(
-        name="Custom Props",
+        name="Custom Properties",
         description="Export custom properties as userData",
         description="Export custom properties as userData",
         default=False)
         default=False)
 
 
@@ -828,166 +828,182 @@ class ExportThree(bpy.types.Operator, ExportHelper):
 
 
         layout = self.layout
         layout = self.layout
 
 
+        ## Scene {
+        box = layout.box()
+        column = box.column(True)
+        row = column.row(True)
+        row.alignment = 'CENTER'
+
+        row.label(text="SCENE", icon="SCENE_DATA")
+
+        row = box.row()
+        row.prop(self.properties, 'option_export_scene')
+        row.prop(self.properties, 'option_materials')
+
+        #row = box.row()
+        #row.prop(self.properties, 'option_embed_geometry')
+
+        row = box.row()
+        row.prop(self.properties, 'option_lights')
+        row.prop(self.properties, 'option_cameras')
+
+        row = box.row()
+        row.prop(self.properties, 'option_hierarchy')
+        ## }
+
+        layout.separator()
+
         ## Geometry {
         ## Geometry {
-        row = layout.row()
-        row.label(text="GEOMETRY:")
+        box = layout.box()
+        column = box.column(True)
+        row = column.row(True)
+        row.alignment = 'CENTER'
 
 
-        row = layout.row()
+        row.label(text="GEOMETRY", icon="MESH_DATA")
+
+        row = box.row()
+        row.prop(self.properties, 'option_geometry_type')
+
+        row = box.row()
+        row.prop(self.properties, 'option_index_type')
+
+        row = box.row()
         row.prop(self.properties, 'option_vertices')
         row.prop(self.properties, 'option_vertices')
         col = row.column()
         col = row.column()
         col.prop(self.properties, 'option_faces')
         col.prop(self.properties, 'option_faces')
         col.enabled = using_geometry
         col.enabled = using_geometry
 
 
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_normals')
         row.prop(self.properties, 'option_normals')
         row.prop(self.properties, 'option_uv_coords')
         row.prop(self.properties, 'option_uv_coords')
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_bones')
-        row.prop(self.properties, 'option_skinning')
+        row = box.row()
+        row.prop(self.properties, 'option_apply_modifiers')
 
 
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_extra_vgroups')
         row.prop(self.properties, 'option_extra_vgroups')
         row.enabled = not using_geometry
         row.enabled = not using_geometry
+        ## }
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_apply_modifiers')
+        layout.separator()
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_geometry_type')
+        ## Materials {
+        box = layout.box()
+        column = box.column(True)
+        row = column.row(True)
+        row.alignment = 'CENTER'
+        row.label(text="MATERIAL", icon="MATERIAL_DATA")
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_index_type')
+        row = box.row()
+        row.prop(self.properties, 'option_colors')
+        row.prop(self.properties, 'option_mix_colors')
 
 
+        row = box.row()
+        row.prop(self.properties, 'option_face_materials')
+        row.enabled = using_geometry
         ## }
         ## }
 
 
         layout.separator()
         layout.separator()
 
 
-        ## Materials {
-        row = layout.row()
-        row.label(text="- Shading:")
+        ## Textures {
+        box = layout.box()
+        column = box.column(True)
+        row = column.row(True)
+        row.alignment = 'CENTER'
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_face_materials')
-        row.enabled = using_geometry
+        row.label(text="TEXTURE", icon="TEXTURE_DATA")
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_colors')
+        row = box.row()
+        row.prop(self.properties, 'option_maps')
+        row.prop(self.properties, 'option_export_textures')
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_mix_colors')
+        row = box.row()
+        row.prop(self.properties, 'option_embed_textures')
+        row.enabled = self.properties.option_export_textures
+
+        row = box.row()
+        row.prop(self.properties, 'option_texture_folder')
+        ## }
+
+        layout.separator()
+
+        ## Armature {
+        box = layout.box()
+        column = box.column(True)
+        row = column.row(True)
+        row.alignment = 'CENTER'
+
+        row.label(text="ARMATURE", icon="ARMATURE_DATA")
+
+        row = box.row()
+        row.prop(self.properties, 'option_bones')
+        row.prop(self.properties, 'option_skinning')
         ## }
         ## }
 
 
         layout.separator()
         layout.separator()
 
 
         ## Animation {
         ## Animation {
-        row = layout.row()
-        row.label(text="- Animation:")
+        box = layout.box()
+        column = box.column(True)
+        row = column.row(True)
+        row.alignment = 'CENTER'
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_animation_morph')
+        row.label(text="ANIMATION", icon="POSE_DATA")
 
 
-        row = layout.row()
+        row = box.row()
+        row.prop(self.properties, 'option_animation_morph')
         row.prop(self.properties, 'option_blend_shape')
         row.prop(self.properties, 'option_blend_shape')
 
 
-        row = layout.row()
+        row = box.row()
         row.label(text="Skeletal animations:")
         row.label(text="Skeletal animations:")
-
-        row = layout.row()
         row.prop(self.properties, 'option_animation_skeletal')
         row.prop(self.properties, 'option_animation_skeletal')
 
 
-        row = layout.row()
-        row.label(text="Keyframe animations:")
-
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_keyframes')
         row.prop(self.properties, 'option_keyframes')
 
 
-        layout.row()
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_influences')
         row.prop(self.properties, 'option_influences')
 
 
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_frame_step')
         row.prop(self.properties, 'option_frame_step')
 
 
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_frame_index_as_time')
         row.prop(self.properties, 'option_frame_index_as_time')
 
 
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_embed_animation')
         row.prop(self.properties, 'option_embed_animation')
-
         ## }
         ## }
 
 
         layout.separator()
         layout.separator()
 
 
-        ## Scene {
-        row = layout.row()
-        row.label(text="SCENE:")
-
-        row = layout.row()
-        row.prop(self.properties, 'option_export_scene')
-        row.prop(self.properties, 'option_materials')
-
-        #row = layout.row()
-        #row.prop(self.properties, 'option_embed_geometry')
-
-        row = layout.row()
-        row.prop(self.properties, 'option_lights')
-        row.prop(self.properties, 'option_cameras')
-        ## }
-
-        row = layout.row()
-        row.prop(self.properties, 'option_hierarchy')
-
-        layout.separator()
-
         ## Settings {
         ## Settings {
-        row = layout.row()
-        row.label(text="SETTINGS:")
-
-        row = layout.row()
-        row.prop(self.properties, 'option_maps')
-
-        row = layout.row()
-        row.prop(self.properties, 'option_export_textures')
-
-        row = layout.row()
-        row.prop(self.properties, 'option_embed_textures')
-        row.enabled = self.properties.option_export_textures
+        box = layout.box()
+        column = box.column(True)
+        row = column.row(True)
+        row.alignment = 'CENTER'
 
 
-        row = layout.row()
-        row.prop(self.properties, 'option_texture_folder')
+        row.label(text="SETTINGS", icon="SETTINGS")
 
 
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_scale')
         row.prop(self.properties, 'option_scale')
 
 
-        layout.row()
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_round_off')
         row.prop(self.properties, 'option_round_off')
-        row = layout.row()
         row.prop(self.properties, 'option_round_value')
         row.prop(self.properties, 'option_round_value')
 
 
-        layout.row()
-        row = layout.row()
-        row.label(text="Custom Properties")
-
-        row = layout.row()
+        row = box.row()
         row.prop(self.properties, 'option_custom_properties')
         row.prop(self.properties, 'option_custom_properties')
 
 
-        layout.row()
-        row = layout.row()
-        row.label(text="Logging verbosity:")
+        row = box.row()
+        row.prop(self.properties, 'option_indent')
 
 
-        row = layout.row()
+        row = box.row()
+        row.label(text="Logging verbosity:")
         row.prop(self.properties, 'option_logging')
         row.prop(self.properties, 'option_logging')
 
 
-        row = layout.row()
+        row = box.row()
         row.label(text="File compression format:")
         row.label(text="File compression format:")
-
-        row = layout.row()
         row.prop(self.properties, 'option_compression')
         row.prop(self.properties, 'option_compression')
-
-        row = layout.row()
-        row.prop(self.properties, 'option_indent')
         ## }
         ## }
 
 
         ## Operators {
         ## Operators {

+ 7 - 0
utils/exporters/blender/addons/io_three/constants.py

@@ -387,3 +387,10 @@ DBG_COLORS = (0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee,
 DOUBLE_SIDED = 'doubleSided'
 DOUBLE_SIDED = 'doubleSided'
 
 
 EXPORT_SETTINGS_KEY = 'threeExportSettings'
 EXPORT_SETTINGS_KEY = 'threeExportSettings'
+
+# flips vectors
+
+XZ_Y = "XZ_Y"
+X_ZY = "X_ZY"
+XYZ = "XYZ"
+_XY_Z = "_XY_Z"

+ 4 - 6
utils/exporters/blender/addons/io_three/exporter/api/mesh.py

@@ -14,12 +14,10 @@ from .. import constants, utilities, logger, exceptions
 
 
 # flips vectors 
 # flips vectors 
 
 
-#TODO: add these strings into constants.py
-
-XZ_Y = "XZ_Y"
-X_ZY = "X_ZY"
-XYZ = "XYZ"
-_XY_Z = "_XY_Z"
+XZ_Y = constants.XZ_Y
+X_ZY = constants.X_ZY
+XYZ = constants.XYZ
+_XY_Z = constants._XY_Z
 
 
 
 
 def flip_axes (a, dir=XYZ):
 def flip_axes (a, dir=XYZ):

部分文件因文件數量過多而無法顯示