ソースを参照

Merge branch 'dev' of github.com:mrdoob/three.js into zh_doc

gogoend 6 年 前
コミット
441c5321f6
65 ファイル変更1959 行追加4558 行削除
  1. 276 337
      build/three.js
  2. 527 525
      build/three.min.js
  3. 276 337
      build/three.module.js
  4. 1 1
      docs/api/en/math/Matrix4.html
  5. 2 2
      docs/manual/en/introduction/Creating-a-scene.html
  6. 1 1
      docs/manual/zh/introduction/Creating-a-scene.html
  7. 0 3
      editor/index.html
  8. 0 29
      editor/js/Loader.js
  9. 0 3
      editor/sw.js
  10. 11 11
      examples/files.js
  11. 2 162
      examples/js/controls/OrbitControls.js
  12. 0 658
      examples/js/libs/ctm.js
  13. 0 517
      examples/js/libs/lzma.js
  14. 18 12
      examples/js/loaders/STLLoader.js
  15. 0 279
      examples/js/loaders/ctm/CTMLoader.js
  16. 0 19
      examples/js/loaders/ctm/CTMWorker.js
  17. 2 162
      examples/jsm/controls/OrbitControls.js
  18. 1 0
      examples/jsm/loaders/GLTFLoader.js
  19. 18 12
      examples/jsm/loaders/STLLoader.js
  20. 0 20
      examples/jsm/loaders/ctm/CTMLoader.d.ts
  21. 0 288
      examples/jsm/loaders/ctm/CTMLoader.js
  22. 9 2
      examples/jsm/nodes/core/FunctionNode.js
  23. 0 2
      examples/jsm/nodes/materials/nodes/StandardNode.js
  24. 5 3
      examples/jsm/nodes/misc/TextureCubeNode.js
  25. BIN
      examples/models/ctm/LeePerry.ctm
  26. BIN
      examples/models/ctm/WaltHead.ctm
  27. BIN
      examples/models/ctm/ben.ctm
  28. BIN
      examples/models/ctm/camaro/camaro.ctm
  29. 0 113
      examples/models/ctm/camaro/camaro.js
  30. BIN
      examples/models/ctm/camaro/car-ao.png
  31. BIN
      examples/models/ctm/camaro/plane-ao-256.png
  32. BIN
      examples/models/ctm/hand.ctm
  33. BIN
      examples/textures/nvidia_tentacle/tentacle_object_space.png
  34. BIN
      examples/textures/nvidia_tentacle/tentacle_tangent_space.png
  35. 1 0
      examples/textures/pbr/Scratched_gold/Scratched_gold.txt
  36. BIN
      examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_AO.png
  37. BIN
      examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Base_Color.png
  38. BIN
      examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Height.png
  39. BIN
      examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Normal.png
  40. BIN
      examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Roughness.png
  41. 7 3
      examples/webgl_furnace_test.html
  42. 0 242
      examples/webgl_loader_ctm_materials.html
  43. 0 3
      examples/webgl_loader_stl.html
  44. 13 8
      examples/webgl_materials_clearcoat_normalmap.html
  45. 139 69
      examples/webgl_materials_nodes.html
  46. 3 10
      src/Three.Legacy.js
  47. 66 63
      src/animation/PropertyBinding.js
  48. 126 153
      src/core/BufferGeometry.js
  49. 46 71
      src/core/Geometry.js
  50. 121 160
      src/core/Object3D.js
  51. 215 213
      src/loaders/Loader.js
  52. 3 0
      src/loaders/MaterialLoader.js
  53. 7 0
      src/materials/Material.js
  54. 37 37
      src/objects/Points.js
  55. 15 19
      src/polyfills.js
  56. 1 1
      src/renderers/shaders/ShaderChunk/dithering_fragment.glsl.js
  57. 1 1
      src/renderers/shaders/ShaderChunk/dithering_pars_fragment.glsl.js
  58. 1 1
      src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js
  59. 1 1
      src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js
  60. 1 1
      src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js
  61. 1 1
      src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js
  62. 1 1
      src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js
  63. 3 1
      src/renderers/webgl/WebGLProgram.js
  64. 1 0
      src/renderers/webgl/WebGLPrograms.js
  65. 0 1
      utils/modularize.js

ファイルの差分が大きいため隠しています
+ 276 - 337
build/three.js


ファイルの差分が大きいため隠しています
+ 527 - 525
build/three.min.js


ファイルの差分が大きいため隠しています
+ 276 - 337
build/three.module.js


+ 1 - 1
docs/api/en/math/Matrix4.html

@@ -56,7 +56,7 @@
 
 			This means that calling
 		<code>
-var m = new Matrix4();
+var m = new THREE.Matrix4();
 
 m.set( 11, 12, 13, 14,
        21, 22, 23, 24,

+ 2 - 2
docs/manual/en/introduction/Creating-a-scene.html

@@ -20,7 +20,7 @@
 		&lt;!DOCTYPE html&gt;
 		&lt;html&gt;
 			&lt;head&gt;
-				&lt;meta charset=utf-8&gt;
+				&lt;meta charset="utf-8"&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
 				&lt;style&gt;
 					body { margin: 0; }
@@ -118,7 +118,7 @@
 		<h2>The result</h2>
 		<p>Congratulations! You have now completed your first three.js application. It's simple, you have to start somewhere.</p>
 
-		<p>The full code is available below. Play around with it to get a better understanding of how it works.</p>
+		<p>The full code is available below and as an editable [link:https://jsfiddle.net/mkba0ecu/ live example]. Play around with it to get a better understanding of how it works.</p>
 
 		<code>
 		&lt;html&gt;

+ 1 - 1
docs/manual/zh/introduction/Creating-a-scene.html

@@ -20,7 +20,7 @@
 		&lt;!DOCTYPE html&gt;
 		&lt;html&gt;
 			&lt;head&gt;
-				&lt;meta charset=utf-8&gt;
+				&lt;meta charset="utf-8"&gt;
 				&lt;title&gt;My first three.js app&lt;/title&gt;
 				&lt;style&gt;
 					body { margin: 0; }

+ 0 - 3
editor/index.html

@@ -22,8 +22,6 @@
 		<script src="../examples/js/libs/chevrotain.min.js"></script> <!-- VRML -->
 		<script src="../examples/js/libs/jszip.min.js"></script>
 		<script src="../examples/js/libs/inflate.min.js"></script> <!-- FBX -->
-		<script src="../examples/js/libs/lzma.js"></script> <!-- CTM -->
-		<script src="../examples/js/libs/ctm.js"></script> <!-- CTM -->
 
 		<script src="../examples/js/loaders/AMFLoader.js"></script>
 		<script src="../examples/js/loaders/AWDLoader.js"></script>
@@ -45,7 +43,6 @@
 		<script src="../examples/js/loaders/TDSLoader.js"></script>
 		<script src="../examples/js/loaders/VRMLLoader.js"></script>
 		<script src="../examples/js/loaders/VTKLoader.js"></script>
-		<script src="../examples/js/loaders/ctm/CTMLoader.js"></script>
 
 		<script src="../examples/js/exporters/ColladaExporter.js"></script>
 		<script src="../examples/js/exporters/GLTFExporter.js"></script>

+ 0 - 29
editor/js/Loader.js

@@ -140,35 +140,6 @@ var Loader = function ( editor ) {
 
 				break;
 
-			case 'ctm':
-
-				reader.addEventListener( 'load', function ( event ) {
-
-					var data = new Uint8Array( event.target.result );
-
-					var stream = new CTM.Stream( data );
-					stream.offset = 0;
-
-					var loader = new THREE.CTMLoader();
-					loader.createModel( new CTM.File( stream ), function ( geometry ) {
-
-						geometry.sourceType = "ctm";
-						geometry.sourceFile = file.name;
-
-						var material = new THREE.MeshStandardMaterial();
-
-						var mesh = new THREE.Mesh( geometry, material );
-						mesh.name = filename;
-
-						editor.execute( new AddObjectCommand( editor, mesh ) );
-
-					} );
-
-				}, false );
-				reader.readAsArrayBuffer( file );
-
-				break;
-
 			case 'dae':
 
 				reader.addEventListener( 'load', function ( event ) {

+ 0 - 3
editor/sw.js

@@ -13,8 +13,6 @@ const staticAssets = [
 	'../examples/js/libs/chevrotain.min.js',
 	'../examples/js/libs/jszip.min.js',
 	'../examples/js/libs/inflate.min.js',
-	'../examples/js/libs/lzma.js',
-	'../examples/js/libs/ctm.js',
 
 	'../examples/js/loaders/AMFLoader.js',
 	'../examples/js/loaders/AWDLoader.js',
@@ -36,7 +34,6 @@ const staticAssets = [
 	'../examples/js/loaders/TDSLoader.js',
 	'../examples/js/loaders/VRMLLoader.js',
 	'../examples/js/loaders/VTKLoader.js',
-	'../examples/js/loaders/ctm/CTMLoader.js',
 
 	'../examples/js/exporters/ColladaExporter.js',
 	'../examples/js/exporters/GLTFExporter.js',

+ 11 - 11
examples/files.js

@@ -85,8 +85,6 @@ var files = {
 		"webgl_loader_collada",
 		"webgl_loader_collada_kinematics",
 		"webgl_loader_collada_skinning",
-		"webgl_loader_ctm",
-		"webgl_loader_ctm_materials",
 		"webgl_loader_draco",
 		"webgl_loader_fbx",
 		"webgl_loader_fbx_nurbs",
@@ -103,7 +101,6 @@ var files = {
 		"webgl_loader_mmd",
 		"webgl_loader_mmd_pose",
 		"webgl_loader_mmd_audio",
-		"webgl_loader_nodes",
 		"webgl_loader_nrrd",
 		"webgl_loader_obj",
 		"webgl_loader_obj_mtl",
@@ -160,13 +157,10 @@ var files = {
 		"webgl_materials_envmaps",
 		"webgl_materials_envmaps_exr",
 		"webgl_materials_envmaps_hdr",
-		"webgl_materials_envmaps_hdr_nodes",
 		"webgl_materials_envmaps_parallax",
-		"webgl_materials_envmaps_pmrem_nodes",
 		"webgl_materials_grass",
 		"webgl_materials_lightmap",
 		"webgl_materials_matcap",
-		"webgl_materials_nodes",
 		"webgl_materials_normalmap",
 		"webgl_materials_normalmap_object_space",
 		"webgl_materials_parallaxmap",
@@ -193,7 +187,6 @@ var files = {
 		"webgl_materials_wireframe",
 		"webgl_math_orientation_transform",
 		"webgl_mirror",
-		"webgl_mirror_nodes",
 		"webgl_modifier_simplifier",
 		"webgl_modifier_subdivision",
 		"webgl_modifier_tessellation",
@@ -214,7 +207,6 @@ var files = {
 		"webgl_panorama_equirectangular",
 		"webgl_performance",
 		"webgl_performance_doublesided",
-		"webgl_performance_nodes",
 		"webgl_performance_static",
 		"webgl_points_billboards",
 		"webgl_points_dynamic",
@@ -242,7 +234,6 @@ var files = {
 		"webgl_shadowmesh",
 		"webgl_skinning_simple",
 		"webgl_sprites",
-		"webgl_sprites_nodes",
 		"webgl_terrain_dynamic",
 		"webgl_test_memory",
 		"webgl_test_memory2",
@@ -252,6 +243,17 @@ var files = {
 		"webgl_water",
 		"webgl_water_flowmap"
 	],
+	"webgl / nodes": [
+		"webgl_loader_nodes",
+		"webgl_materials_envmaps_hdr_nodes",
+		"webgl_materials_envmaps_pmrem_nodes",
+		"webgl_materials_nodes",
+		"webgl_mirror_nodes",
+		"webgl_performance_nodes",
+		"webgl_postprocessing_nodes",
+		"webgl_postprocessing_nodes_pass",
+		"webgl_sprites_nodes",
+	],
 	"webgl / postprocessing": [
 		"webgl_postprocessing",
 		"webgl_postprocessing_advanced",
@@ -267,8 +269,6 @@ var files = {
 		"webgl_postprocessing_masking",
 		"webgl_postprocessing_ssaa",
 		"webgl_postprocessing_ssaa_unbiased",
-		"webgl_postprocessing_nodes",
-		"webgl_postprocessing_nodes_pass",
 		"webgl_postprocessing_outline",
 		"webgl_postprocessing_pixel",
 		"webgl_postprocessing_procedural",

+ 2 - 162
examples/js/controls/OrbitControls.js

@@ -460,32 +460,24 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseDownRotate( event ) {
 
-		//console.log( 'handleMouseDownRotate' );
-
 		rotateStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownDolly( event ) {
 
-		//console.log( 'handleMouseDownDolly' );
-
 		dollyStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownPan( event ) {
 
-		//console.log( 'handleMouseDownPan' );
-
 		panStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseMoveRotate( event ) {
 
-		//console.log( 'handleMouseMoveRotate' );
-
 		rotateEnd.set( event.clientX, event.clientY );
 
 		rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
@@ -504,8 +496,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMoveDolly( event ) {
 
-		//console.log( 'handleMouseMoveDolly' );
-
 		dollyEnd.set( event.clientX, event.clientY );
 
 		dollyDelta.subVectors( dollyEnd, dollyStart );
@@ -528,8 +518,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMovePan( event ) {
 
-		//console.log( 'handleMouseMovePan' );
-
 		panEnd.set( event.clientX, event.clientY );
 
 		panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
@@ -544,14 +532,12 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleMouseUp( /*event*/ ) {
 
-		// console.log( 'handleMouseUp' );
+		// no-op
 
 	}
 
 	function handleMouseWheel( event ) {
 
-		// console.log( 'handleMouseWheel' );
-
 		if ( event.deltaY < 0 ) {
 
 			dollyOut( getZoomScale() );
@@ -568,8 +554,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleKeyDown( event ) {
 
-		// console.log( 'handleKeyDown' );
-
 		var needsUpdate = false;
 
 		switch ( event.keyCode ) {
@@ -610,8 +594,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartRotate( event ) {
 
-		//console.log( 'handleTouchStartRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -629,8 +611,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartPan( event ) {
 
-		//console.log( 'handleTouchStartPan' );
-
 		if ( event.touches.length == 1 ) {
 
 			panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -648,8 +628,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDolly( event ) {
 
-		//console.log( 'handleTouchStartDolly' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -661,8 +639,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyPan( event ) {
 
-		//console.log( 'handleTouchStartDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enablePan ) handleTouchStartPan( event );
@@ -671,8 +647,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyRotate( event ) {
 
-		//console.log( 'handleTouchStartDollyRotate' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enableRotate ) handleTouchStartRotate( event );
@@ -681,8 +655,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveRotate( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -710,8 +682,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMovePan( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -735,8 +705,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDolly( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -754,8 +722,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyPan( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enablePan ) handleTouchMovePan( event );
@@ -764,8 +730,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyRotate( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enableRotate ) handleTouchMoveRotate( event );
@@ -774,7 +738,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	function handleTouchEnd( /*event*/ ) {
 
-		//console.log( 'handleTouchEnd' );
+		// no-op
 
 	}
 
@@ -1181,130 +1145,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
 THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;
 
-Object.defineProperties( THREE.OrbitControls.prototype, {
-
-	center: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
-			return this.target;
-
-		}
-
-	},
-
-	// backward compatibility
-
-	noZoom: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			return ! this.enableZoom;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			this.enableZoom = ! value;
-
-		}
-
-	},
-
-	noRotate: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			return ! this.enableRotate;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			this.enableRotate = ! value;
-
-		}
-
-	},
-
-	noPan: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			return ! this.enablePan;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			this.enablePan = ! value;
-
-		}
-
-	},
-
-	noKeys: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			return ! this.enableKeys;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			this.enableKeys = ! value;
-
-		}
-
-	},
-
-	staticMoving: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			return ! this.enableDamping;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			this.enableDamping = ! value;
-
-		}
-
-	},
-
-	dynamicDampingFactor: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			return this.dampingFactor;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			this.dampingFactor = value;
-
-		}
-
-	}
-
-} );
 
 // This set of controls performs orbiting, dollying (zooming), and panning.
 // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).

+ 0 - 658
examples/js/libs/ctm.js

@@ -1,658 +0,0 @@
-/*
-Copyright (c) 2011 Juan Mellado
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-/*
-References:
-- "OpenCTM: The Open Compressed Triangle Mesh file format" by Marcus Geelnard
-  http://openctm.sourceforge.net/
-*/
-
-var CTM = CTM || {};
-
-// browserify support
-if ( typeof module === 'object' ) {
-
-	module.exports = CTM;
-
-}
-
-CTM.CompressionMethod = {
-  RAW: 0x00574152,
-  MG1: 0x0031474d,
-  MG2: 0x0032474d
-};
-
-CTM.Flags = {
-  NORMALS: 0x00000001
-};
-
-CTM.File = function(stream) {
-	this.load(stream);
-};
-
-CTM.File.prototype.load = function(stream) {
-	this.header = new CTM.FileHeader(stream);
-
-	this.body = new CTM.FileBody(this.header);
-
-	this.getReader().read(stream, this.body);
-};
-
-CTM.File.prototype.getReader = function() {
-	var reader;
-
-	switch (this.header.compressionMethod){
-		case CTM.CompressionMethod.RAW:
-			reader = new CTM.ReaderRAW();
-			break;
-		case CTM.CompressionMethod.MG1:
-			reader = new CTM.ReaderMG1();
-			break;
-		case CTM.CompressionMethod.MG2:
-			reader = new CTM.ReaderMG2();
-			break;
-	}
-
-	return reader;
-};
-
-CTM.FileHeader = function(stream) {
-	stream.readInt32(); //magic "OCTM"
-	this.fileFormat = stream.readInt32();
-	this.compressionMethod = stream.readInt32();
-	this.vertexCount = stream.readInt32();
-	this.triangleCount = stream.readInt32();
-	this.uvMapCount = stream.readInt32();
-	this.attrMapCount = stream.readInt32();
-	this.flags = stream.readInt32();
-	this.comment = stream.readString();
-};
-
-CTM.FileHeader.prototype.hasNormals = function() {
-	return this.flags & CTM.Flags.NORMALS;
-};
-
-CTM.FileBody = function(header) {
-	var i = header.triangleCount * 3,
-      v = header.vertexCount * 3,
-      n = header.hasNormals() ? header.vertexCount * 3 : 0,
-      u = header.vertexCount * 2,
-      a = header.vertexCount * 4,
-      j = 0;
-
-	var data = new ArrayBuffer(
-    (i + v + n + (u * header.uvMapCount) + (a * header.attrMapCount) ) * 4);
-
-	this.indices = new Uint32Array(data, 0, i);
-
-	this.vertices = new Float32Array(data, i * 4, v);
-
-	if ( header.hasNormals() ) {
-		this.normals = new Float32Array(data, (i + v) * 4, n);
-	}
-
-	if (header.uvMapCount) {
-		this.uvMaps = [];
-		for (j = 0; j < header.uvMapCount; ++ j) {
-			this.uvMaps[j] = { uv: new Float32Array(data,
-        (i + v + n + (j * u) ) * 4, u) };
-		}
-	}
-
-	if (header.attrMapCount) {
-		this.attrMaps = [];
-		for (j = 0; j < header.attrMapCount; ++ j) {
-			this.attrMaps[j] = { attr: new Float32Array(data,
-        (i + v + n + (u * header.uvMapCount) + (j * a) ) * 4, a) };
-		}
-	}
-};
-
-CTM.FileMG2Header = function(stream) {
-	stream.readInt32(); //magic "MG2H"
-	this.vertexPrecision = stream.readFloat32();
-	this.normalPrecision = stream.readFloat32();
-	this.lowerBoundx = stream.readFloat32();
-	this.lowerBoundy = stream.readFloat32();
-	this.lowerBoundz = stream.readFloat32();
-	this.higherBoundx = stream.readFloat32();
-	this.higherBoundy = stream.readFloat32();
-	this.higherBoundz = stream.readFloat32();
-	this.divx = stream.readInt32();
-	this.divy = stream.readInt32();
-	this.divz = stream.readInt32();
-
-	this.sizex = (this.higherBoundx - this.lowerBoundx) / this.divx;
-	this.sizey = (this.higherBoundy - this.lowerBoundy) / this.divy;
-	this.sizez = (this.higherBoundz - this.lowerBoundz) / this.divz;
-};
-
-CTM.ReaderRAW = function() {
-};
-
-CTM.ReaderRAW.prototype.read = function(stream, body) {
-	this.readIndices(stream, body.indices);
-	this.readVertices(stream, body.vertices);
-
-	if (body.normals) {
-		this.readNormals(stream, body.normals);
-	}
-	if (body.uvMaps) {
-		this.readUVMaps(stream, body.uvMaps);
-	}
-	if (body.attrMaps) {
-		this.readAttrMaps(stream, body.attrMaps);
-	}
-};
-
-CTM.ReaderRAW.prototype.readIndices = function(stream, indices) {
-	stream.readInt32(); //magic "INDX"
-	stream.readArrayInt32(indices);
-};
-
-CTM.ReaderRAW.prototype.readVertices = function(stream, vertices) {
-	stream.readInt32(); //magic "VERT"
-	stream.readArrayFloat32(vertices);
-};
-
-CTM.ReaderRAW.prototype.readNormals = function(stream, normals) {
-	stream.readInt32(); //magic "NORM"
-	stream.readArrayFloat32(normals);
-};
-
-CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps) {
-	var i = 0;
-	for (; i < uvMaps.length; ++ i) {
-		stream.readInt32(); //magic "TEXC"
-
-		uvMaps[i].name = stream.readString();
-		uvMaps[i].filename = stream.readString();
-		stream.readArrayFloat32(uvMaps[i].uv);
-	}
-};
-
-CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps) {
-	var i = 0;
-	for (; i < attrMaps.length; ++ i) {
-		stream.readInt32(); //magic "ATTR"
-
-		attrMaps[i].name = stream.readString();
-		stream.readArrayFloat32(attrMaps[i].attr);
-	}
-};
-
-CTM.ReaderMG1 = function() {
-};
-
-CTM.ReaderMG1.prototype.read = function(stream, body) {
-	this.readIndices(stream, body.indices);
-	this.readVertices(stream, body.vertices);
-
-	if (body.normals) {
-		this.readNormals(stream, body.normals);
-	}
-	if (body.uvMaps) {
-		this.readUVMaps(stream, body.uvMaps);
-	}
-	if (body.attrMaps) {
-		this.readAttrMaps(stream, body.attrMaps);
-	}
-};
-
-CTM.ReaderMG1.prototype.readIndices = function(stream, indices) {
-	stream.readInt32(); //magic "INDX"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(indices, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	CTM.restoreIndices(indices, indices.length);
-};
-
-CTM.ReaderMG1.prototype.readVertices = function(stream, vertices) {
-	stream.readInt32(); //magic "VERT"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(vertices, 1);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-};
-
-CTM.ReaderMG1.prototype.readNormals = function(stream, normals) {
-	stream.readInt32(); //magic "NORM"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(normals, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-};
-
-CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps) {
-	var i = 0;
-	for (; i < uvMaps.length; ++ i) {
-		stream.readInt32(); //magic "TEXC"
-
-		uvMaps[i].name = stream.readString();
-		uvMaps[i].filename = stream.readString();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-	}
-};
-
-CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps) {
-	var i = 0;
-	for (; i < attrMaps.length; ++ i) {
-		stream.readInt32(); //magic "ATTR"
-
-		attrMaps[i].name = stream.readString();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-	}
-};
-
-CTM.ReaderMG2 = function() {
-};
-
-CTM.ReaderMG2.prototype.read = function(stream, body) {
-	this.MG2Header = new CTM.FileMG2Header(stream);
-
-	this.readVertices(stream, body.vertices);
-	this.readIndices(stream, body.indices);
-
-	if (body.normals) {
-		this.readNormals(stream, body);
-	}
-	if (body.uvMaps) {
-		this.readUVMaps(stream, body.uvMaps);
-	}
-	if (body.attrMaps) {
-		this.readAttrMaps(stream, body.attrMaps);
-	}
-};
-
-CTM.ReaderMG2.prototype.readVertices = function(stream, vertices) {
-	stream.readInt32(); //magic "VERT"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(vertices, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	var gridIndices = this.readGridIndices(stream, vertices);
-
-	CTM.restoreVertices(vertices, this.MG2Header, gridIndices, this.MG2Header.vertexPrecision);
-};
-
-CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices) {
-	stream.readInt32(); //magic "GIDX"
-	stream.readInt32(); //packed size
-
-	var gridIndices = new Uint32Array(vertices.length / 3);
-
-	var interleaved = new CTM.InterleavedStream(gridIndices, 1);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	CTM.restoreGridIndices(gridIndices, gridIndices.length);
-
-	return gridIndices;
-};
-
-CTM.ReaderMG2.prototype.readIndices = function(stream, indices) {
-	stream.readInt32(); //magic "INDX"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(indices, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	CTM.restoreIndices(indices, indices.length);
-};
-
-CTM.ReaderMG2.prototype.readNormals = function(stream, body) {
-	stream.readInt32(); //magic "NORM"
-	stream.readInt32(); //packed size
-
-	var interleaved = new CTM.InterleavedStream(body.normals, 3);
-	LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-	var smooth = CTM.calcSmoothNormals(body.indices, body.vertices);
-
-	CTM.restoreNormals(body.normals, smooth, this.MG2Header.normalPrecision);
-};
-
-CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps) {
-	var i = 0;
-	for (; i < uvMaps.length; ++ i) {
-		stream.readInt32(); //magic "TEXC"
-
-		uvMaps[i].name = stream.readString();
-		uvMaps[i].filename = stream.readString();
-
-		var precision = stream.readFloat32();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-		CTM.restoreMap(uvMaps[i].uv, 2, precision);
-	}
-};
-
-CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps) {
-	var i = 0;
-	for (; i < attrMaps.length; ++ i) {
-		stream.readInt32(); //magic "ATTR"
-
-		attrMaps[i].name = stream.readString();
-
-		var precision = stream.readFloat32();
-
-		stream.readInt32(); //packed size
-
-		var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4);
-		LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
-
-		CTM.restoreMap(attrMaps[i].attr, 4, precision);
-	}
-};
-
-CTM.restoreIndices = function(indices, len) {
-	var i = 3;
-	if (len > 0) {
-		indices[2] += indices[0];
-		indices[1] += indices[0];
-	}
-	for (; i < len; i += 3) {
-		indices[i] += indices[i - 3];
-
-		if (indices[i] === indices[i - 3]) {
-			indices[i + 1] += indices[i - 2];
-		}else {
-			indices[i + 1] += indices[i];
-		}
-
-		indices[i + 2] += indices[i];
-	}
-};
-
-CTM.restoreGridIndices = function(gridIndices, len) {
-	var i = 1;
-	for (; i < len; ++ i) {
-		gridIndices[i] += gridIndices[i - 1];
-	}
-};
-
-CTM.restoreVertices = function(vertices, grid, gridIndices, precision) {
-	var gridIdx, delta, x, y, z,
-      intVertices = new Uint32Array(vertices.buffer, vertices.byteOffset, vertices.length),
-      ydiv = grid.divx, zdiv = ydiv * grid.divy,
-      prevGridIdx = 0x7fffffff, prevDelta = 0,
-      i = 0, j = 0, len = gridIndices.length;
-
-	for (; i < len; j += 3) {
-		x = gridIdx = gridIndices[i ++];
-
-		z = ~~(x / zdiv);
-		x -= ~~(z * zdiv);
-		y = ~~(x / ydiv);
-		x -= ~~(y * ydiv);
-
-		delta = intVertices[j];
-		if (gridIdx === prevGridIdx) {
-			delta += prevDelta;
-		}
-
-		vertices[j]     = grid.lowerBoundx +
-      x * grid.sizex + precision * delta;
-		vertices[j + 1] = grid.lowerBoundy +
-      y * grid.sizey + precision * intVertices[j + 1];
-		vertices[j + 2] = grid.lowerBoundz +
-      z * grid.sizez + precision * intVertices[j + 2];
-
-		prevGridIdx = gridIdx;
-		prevDelta = delta;
-	}
-};
-
-CTM.restoreNormals = function(normals, smooth, precision) {
-	var ro, phi, theta, sinPhi,
-      nx, ny, nz, by, bz, len,
-      intNormals = new Uint32Array(normals.buffer, normals.byteOffset, normals.length),
-      i = 0, k = normals.length,
-      PI_DIV_2 = 3.141592653589793238462643 * 0.5;
-
-	for (; i < k; i += 3) {
-		ro = intNormals[i] * precision;
-		phi = intNormals[i + 1];
-
-		if (phi === 0) {
-			normals[i]     = smooth[i]     * ro;
-			normals[i + 1] = smooth[i + 1] * ro;
-			normals[i + 2] = smooth[i + 2] * ro;
-		}else {
-
-			if (phi <= 4) {
-				theta = (intNormals[i + 2] - 2) * PI_DIV_2;
-			}else {
-				theta = ( (intNormals[i + 2] * 4 / phi) - 2) * PI_DIV_2;
-			}
-
-			phi *= precision * PI_DIV_2;
-			sinPhi = ro * Math.sin(phi);
-
-			nx = sinPhi * Math.cos(theta);
-			ny = sinPhi * Math.sin(theta);
-			nz = ro * Math.cos(phi);
-
-			bz = smooth[i + 1];
-			by = smooth[i] - smooth[i + 2];
-
-			len = Math.sqrt(2 * bz * bz + by * by);
-			if (len > 1e-20) {
-				by /= len;
-				bz /= len;
-			}
-
-			normals[i] = smooth[i] * nz + (smooth[i + 1] * bz - smooth[i + 2] * by) * ny - bz * nx;
-			normals[i + 1] = smooth[i + 1] * nz - (smooth[i + 2] + smooth[i]) * bz  * ny + by * nx;
-			normals[i + 2] = smooth[i + 2] * nz + (smooth[i] * by + smooth[i + 1] * bz) * ny + bz * nx;
-		}
-	}
-};
-
-CTM.restoreMap = function(map, count, precision) {
-	var delta, value,
-      intMap = new Uint32Array(map.buffer, map.byteOffset, map.length),
-      i = 0, j, len = map.length;
-
-	for (; i < count; ++ i) {
-		delta = 0;
-
-		for (j = i; j < len; j += count) {
-			value = intMap[j];
-
-			delta += value & 1 ? -( (value + 1) >> 1) : value >> 1;
-
-			map[j] = delta * precision;
-		}
-	}
-};
-
-CTM.calcSmoothNormals = function(indices, vertices) {
-	var smooth = new Float32Array(vertices.length),
-      indx, indy, indz, nx, ny, nz,
-      v1x, v1y, v1z, v2x, v2y, v2z, len,
-      i, k;
-
-	for (i = 0, k = indices.length; i < k;) {
-		indx = indices[i ++] * 3;
-		indy = indices[i ++] * 3;
-		indz = indices[i ++] * 3;
-
-		v1x = vertices[indy]     - vertices[indx];
-		v2x = vertices[indz]     - vertices[indx];
-		v1y = vertices[indy + 1] - vertices[indx + 1];
-		v2y = vertices[indz + 1] - vertices[indx + 1];
-		v1z = vertices[indy + 2] - vertices[indx + 2];
-		v2z = vertices[indz + 2] - vertices[indx + 2];
-
-		nx = v1y * v2z - v1z * v2y;
-		ny = v1z * v2x - v1x * v2z;
-		nz = v1x * v2y - v1y * v2x;
-
-		len = Math.sqrt(nx * nx + ny * ny + nz * nz);
-		if (len > 1e-10) {
-			nx /= len;
-			ny /= len;
-			nz /= len;
-		}
-
-		smooth[indx]     += nx;
-		smooth[indx + 1] += ny;
-		smooth[indx + 2] += nz;
-		smooth[indy]     += nx;
-		smooth[indy + 1] += ny;
-		smooth[indy + 2] += nz;
-		smooth[indz]     += nx;
-		smooth[indz + 1] += ny;
-		smooth[indz + 2] += nz;
-	}
-
-	for (i = 0, k = smooth.length; i < k; i += 3) {
-		len = Math.sqrt(smooth[i] * smooth[i] +
-      smooth[i + 1] * smooth[i + 1] +
-      smooth[i + 2] * smooth[i + 2]);
-
-		if (len > 1e-10) {
-			smooth[i]     /= len;
-			smooth[i + 1] /= len;
-			smooth[i + 2] /= len;
-		}
-	}
-
-	return smooth;
-};
-
-CTM.isLittleEndian = (function() {
-	var buffer = new ArrayBuffer(2),
-      bytes = new Uint8Array(buffer),
-      ints = new Uint16Array(buffer);
-
-	bytes[0] = 1;
-
-	return ints[0] === 1;
-}());
-
-CTM.InterleavedStream = function(data, count) {
-	this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
-	this.offset = CTM.isLittleEndian ? 3 : 0;
-	this.count = count * 4;
-	this.len = this.data.length;
-};
-
-CTM.InterleavedStream.prototype.writeByte = function(value) {
-	this.data[this.offset] = value;
-
-	this.offset += this.count;
-	if (this.offset >= this.len) {
-
-		this.offset -= this.len - 4;
-		if (this.offset >= this.count) {
-
-			this.offset -= this.count + (CTM.isLittleEndian ? 1 : -1);
-		}
-	}
-};
-
-CTM.Stream = function(data) {
-	this.data = data;
-	this.offset = 0;
-};
-
-CTM.Stream.prototype.TWO_POW_MINUS23 = Math.pow(2, -23);
-
-CTM.Stream.prototype.TWO_POW_MINUS126 = Math.pow(2, -126);
-
-CTM.Stream.prototype.readByte = function() {
-	return this.data[this.offset ++] & 0xff;
-};
-
-CTM.Stream.prototype.readInt32 = function() {
-	var i = this.readByte();
-	i |= this.readByte() << 8;
-	i |= this.readByte() << 16;
-	return i | (this.readByte() << 24);
-};
-
-CTM.Stream.prototype.readFloat32 = function() {
-	var m = this.readByte();
-	m += this.readByte() << 8;
-
-	var b1 = this.readByte();
-	var b2 = this.readByte();
-
-	m += (b1 & 0x7f) << 16;
-	var e = ( (b2 & 0x7f) << 1) | ( (b1 & 0x80) >>> 7);
-	var s = b2 & 0x80 ? -1 : 1;
-
-	if (e === 255) {
-		return m !== 0 ? NaN : s * Infinity;
-	}
-	if (e > 0) {
-		return s * (1 + (m * this.TWO_POW_MINUS23) ) * Math.pow(2, e - 127);
-	}
-	if (m !== 0) {
-		return s * m * this.TWO_POW_MINUS126;
-	}
-	return s * 0;
-};
-
-CTM.Stream.prototype.readString = function() {
-	var len = this.readInt32();
-
-	this.offset += len;
-
-	return String.fromCharCode.apply(null, this.data.subarray(this.offset - len, this.offset));
-};
-
-CTM.Stream.prototype.readArrayInt32 = function(array) {
-	var i = 0, len = array.length;
-
-	while (i < len) {
-		array[i ++] = this.readInt32();
-	}
-
-	return array;
-};
-
-CTM.Stream.prototype.readArrayFloat32 = function(array) {
-	var i = 0, len = array.length;
-
-	while (i < len) {
-		array[i ++] = this.readFloat32();
-	}
-
-	return array;
-};

+ 0 - 517
examples/js/libs/lzma.js

@@ -1,517 +0,0 @@
-
-var LZMA = LZMA || {};
-
-// browserify support
-if ( typeof module === 'object' ) {
-
-	module.exports = LZMA;
-
-}
-
-LZMA.OutWindow = function() {
-	this._windowSize = 0;
-};
-
-LZMA.OutWindow.prototype.create = function(windowSize) {
-	if ( (!this._buffer) || (this._windowSize !== windowSize) ) {
-		this._buffer = [];
-	}
-	this._windowSize = windowSize;
-	this._pos = 0;
-	this._streamPos = 0;
-};
-
-LZMA.OutWindow.prototype.flush = function() {
-	var size = this._pos - this._streamPos;
-	if (size !== 0) {
-		while (size --) {
-			this._stream.writeByte(this._buffer[this._streamPos ++]);
-		}
-		if (this._pos >= this._windowSize) {
-			this._pos = 0;
-		}
-		this._streamPos = this._pos;
-	}
-};
-
-LZMA.OutWindow.prototype.releaseStream = function() {
-	this.flush();
-	this._stream = null;
-};
-
-LZMA.OutWindow.prototype.setStream = function(stream) {
-	this.releaseStream();
-	this._stream = stream;
-};
-
-LZMA.OutWindow.prototype.init = function(solid) {
-	if (!solid) {
-		this._streamPos = 0;
-		this._pos = 0;
-	}
-};
-
-LZMA.OutWindow.prototype.copyBlock = function(distance, len) {
-	var pos = this._pos - distance - 1;
-	if (pos < 0) {
-		pos += this._windowSize;
-	}
-	while (len --) {
-		if (pos >= this._windowSize) {
-			pos = 0;
-		}
-		this._buffer[this._pos ++] = this._buffer[pos ++];
-		if (this._pos >= this._windowSize) {
-			this.flush();
-		}
-	}
-};
-
-LZMA.OutWindow.prototype.putByte = function(b) {
-	this._buffer[this._pos ++] = b;
-	if (this._pos >= this._windowSize) {
-		this.flush();
-	}
-};
-
-LZMA.OutWindow.prototype.getByte = function(distance) {
-	var pos = this._pos - distance - 1;
-	if (pos < 0) {
-		pos += this._windowSize;
-	}
-	return this._buffer[pos];
-};
-
-LZMA.RangeDecoder = function() {
-};
-
-LZMA.RangeDecoder.prototype.setStream = function(stream) {
-	this._stream = stream;
-};
-
-LZMA.RangeDecoder.prototype.releaseStream = function() {
-	this._stream = null;
-};
-
-LZMA.RangeDecoder.prototype.init = function() {
-	var i = 5;
-
-	this._code = 0;
-	this._range = -1;
-
-	while (i --) {
-		this._code = (this._code << 8) | this._stream.readByte();
-	}
-};
-
-LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits) {
-	var result = 0, i = numTotalBits, t;
-
-	while (i --) {
-		this._range >>>= 1;
-		t = (this._code - this._range) >>> 31;
-		this._code -= this._range & (t - 1);
-		result = (result << 1) | (1 - t);
-
-		if ( (this._range & 0xff000000) === 0) {
-			this._code = (this._code << 8) | this._stream.readByte();
-			this._range <<= 8;
-		}
-	}
-
-	return result;
-};
-
-LZMA.RangeDecoder.prototype.decodeBit = function(probs, index) {
-	var prob = probs[index],
-      newBound = (this._range >>> 11) * prob;
-
-	if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ) {
-		this._range = newBound;
-		probs[index] += (2048 - prob) >>> 5;
-		if ( (this._range & 0xff000000) === 0) {
-			this._code = (this._code << 8) | this._stream.readByte();
-			this._range <<= 8;
-		}
-		return 0;
-	}
-
-	this._range -= newBound;
-	this._code -= newBound;
-	probs[index] -= prob >>> 5;
-	if ( (this._range & 0xff000000) === 0) {
-		this._code = (this._code << 8) | this._stream.readByte();
-		this._range <<= 8;
-	}
-	return 1;
-};
-
-LZMA.initBitModels = function(probs, len) {
-	while (len --) {
-		probs[len] = 1024;
-	}
-};
-
-LZMA.BitTreeDecoder = function(numBitLevels) {
-	this._models = [];
-	this._numBitLevels = numBitLevels;
-};
-
-LZMA.BitTreeDecoder.prototype.init = function() {
-	LZMA.initBitModels(this._models, 1 << this._numBitLevels);
-};
-
-LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder) {
-	var m = 1, i = this._numBitLevels;
-
-	while (i --) {
-		m = (m << 1) | rangeDecoder.decodeBit(this._models, m);
-	}
-	return m - (1 << this._numBitLevels);
-};
-
-LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder) {
-	var m = 1, symbol = 0, i = 0, bit;
-
-	for (; i < this._numBitLevels; ++ i) {
-		bit = rangeDecoder.decodeBit(this._models, m);
-		m = (m << 1) | bit;
-		symbol |= bit << i;
-	}
-	return symbol;
-};
-
-LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels) {
-	var m = 1, symbol = 0, i = 0, bit;
-
-	for (; i < numBitLevels; ++ i) {
-		bit = rangeDecoder.decodeBit(models, startIndex + m);
-		m = (m << 1) | bit;
-		symbol |= bit << i;
-	}
-	return symbol;
-};
-
-LZMA.LenDecoder = function() {
-	this._choice = [];
-	this._lowCoder = [];
-	this._midCoder = [];
-	this._highCoder = new LZMA.BitTreeDecoder(8);
-	this._numPosStates = 0;
-};
-
-LZMA.LenDecoder.prototype.create = function(numPosStates) {
-	for (; this._numPosStates < numPosStates; ++ this._numPosStates) {
-		this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
-		this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
-	}
-};
-
-LZMA.LenDecoder.prototype.init = function() {
-	var i = this._numPosStates;
-	LZMA.initBitModels(this._choice, 2);
-	while (i --) {
-		this._lowCoder[i].init();
-		this._midCoder[i].init();
-	}
-	this._highCoder.init();
-};
-
-LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState) {
-	if (rangeDecoder.decodeBit(this._choice, 0) === 0) {
-		return this._lowCoder[posState].decode(rangeDecoder);
-	}
-	if (rangeDecoder.decodeBit(this._choice, 1) === 0) {
-		return 8 + this._midCoder[posState].decode(rangeDecoder);
-	}
-	return 16 + this._highCoder.decode(rangeDecoder);
-};
-
-LZMA.Decoder2 = function() {
-	this._decoders = [];
-};
-
-LZMA.Decoder2.prototype.init = function() {
-	LZMA.initBitModels(this._decoders, 0x300);
-};
-
-LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder) {
-	var symbol = 1;
-
-	do {
-		symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
-	}while (symbol < 0x100);
-
-	return symbol & 0xff;
-};
-
-LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte) {
-	var symbol = 1, matchBit, bit;
-
-	do {
-		matchBit = (matchByte >> 7) & 1;
-		matchByte <<= 1;
-		bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol);
-		symbol = (symbol << 1) | bit;
-		if (matchBit !== bit) {
-			while (symbol < 0x100) {
-				symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
-			}
-			break;
-		}
-	}while (symbol < 0x100);
-
-	return symbol & 0xff;
-};
-
-LZMA.LiteralDecoder = function() {
-};
-
-LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits) {
-	var i;
-
-	if (this._coders
-    && (this._numPrevBits === numPrevBits)
-    && (this._numPosBits === numPosBits) ) {
-		return;
-	}
-	this._numPosBits = numPosBits;
-	this._posMask = (1 << numPosBits) - 1;
-	this._numPrevBits = numPrevBits;
-
-	this._coders = [];
-
-	i = 1 << (this._numPrevBits + this._numPosBits);
-	while (i --) {
-		this._coders[i] = new LZMA.Decoder2();
-	}
-};
-
-LZMA.LiteralDecoder.prototype.init = function() {
-	var i = 1 << (this._numPrevBits + this._numPosBits);
-	while (i --) {
-		this._coders[i].init();
-	}
-};
-
-LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte) {
-	return this._coders[( (pos & this._posMask) << this._numPrevBits)
-    + ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )];
-};
-
-LZMA.Decoder = function() {
-	this._outWindow = new LZMA.OutWindow();
-	this._rangeDecoder = new LZMA.RangeDecoder();
-	this._isMatchDecoders = [];
-	this._isRepDecoders = [];
-	this._isRepG0Decoders = [];
-	this._isRepG1Decoders = [];
-	this._isRepG2Decoders = [];
-	this._isRep0LongDecoders = [];
-	this._posSlotDecoder = [];
-	this._posDecoders = [];
-	this._posAlignDecoder = new LZMA.BitTreeDecoder(4);
-	this._lenDecoder = new LZMA.LenDecoder();
-	this._repLenDecoder = new LZMA.LenDecoder();
-	this._literalDecoder = new LZMA.LiteralDecoder();
-	this._dictionarySize = -1;
-	this._dictionarySizeCheck = -1;
-
-	this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6);
-	this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6);
-	this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6);
-	this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6);
-};
-
-LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize) {
-	if (dictionarySize < 0) {
-		return false;
-	}
-	if (this._dictionarySize !== dictionarySize) {
-		this._dictionarySize = dictionarySize;
-		this._dictionarySizeCheck = Math.max(this._dictionarySize, 1);
-		this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) );
-	}
-	return true;
-};
-
-LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb) {
-	var numPosStates = 1 << pb;
-
-	if (lc > 8 || lp > 4 || pb > 4) {
-		return false;
-	}
-
-	this._literalDecoder.create(lp, lc);
-
-	this._lenDecoder.create(numPosStates);
-	this._repLenDecoder.create(numPosStates);
-	this._posStateMask = numPosStates - 1;
-
-	return true;
-};
-
-LZMA.Decoder.prototype.init = function() {
-	var i = 4;
-
-	this._outWindow.init(false);
-
-	LZMA.initBitModels(this._isMatchDecoders, 192);
-	LZMA.initBitModels(this._isRep0LongDecoders, 192);
-	LZMA.initBitModels(this._isRepDecoders, 12);
-	LZMA.initBitModels(this._isRepG0Decoders, 12);
-	LZMA.initBitModels(this._isRepG1Decoders, 12);
-	LZMA.initBitModels(this._isRepG2Decoders, 12);
-	LZMA.initBitModels(this._posDecoders, 114);
-
-	this._literalDecoder.init();
-
-	while (i --) {
-		this._posSlotDecoder[i].init();
-	}
-
-	this._lenDecoder.init();
-	this._repLenDecoder.init();
-	this._posAlignDecoder.init();
-	this._rangeDecoder.init();
-};
-
-LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize) {
-	var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0,
-      posState, decoder2, len, distance, posSlot, numDirectBits;
-
-	this._rangeDecoder.setStream(inStream);
-	this._outWindow.setStream(outStream);
-
-	this.init();
-
-	while (outSize < 0 || nowPos64 < outSize) {
-		posState = nowPos64 & this._posStateMask;
-
-		if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0) {
-			decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte);
-
-			if (state >= 7) {
-				prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) );
-			}else {
-				prevByte = decoder2.decodeNormal(this._rangeDecoder);
-			}
-			this._outWindow.putByte(prevByte);
-
-			state = state < 4 ? 0 : state - (state < 10 ? 3 : 6);
-
-		}else {
-
-			if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1) {
-				len = 0;
-				if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0) {
-					if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0) {
-						state = state < 7 ? 9 : 11;
-						len = 1;
-					}
-				}else {
-					if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0) {
-						distance = rep1;
-					}else {
-						if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0) {
-							distance = rep2;
-						}else {
-							distance = rep3;
-							rep3 = rep2;
-						}
-						rep2 = rep1;
-					}
-					rep1 = rep0;
-					rep0 = distance;
-				}
-				if (len === 0) {
-					len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState);
-					state = state < 7 ? 8 : 11;
-				}
-			}else {
-				rep3 = rep2;
-				rep2 = rep1;
-				rep1 = rep0;
-
-				len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState);
-				state = state < 7 ? 7 : 10;
-
-				posSlot = this._posSlotDecoder[len <= 5 ? len - 2 : 3].decode(this._rangeDecoder);
-				if (posSlot >= 4) {
-
-					numDirectBits = (posSlot >> 1) - 1;
-					rep0 = (2 | (posSlot & 1) ) << numDirectBits;
-
-					if (posSlot < 14) {
-						rep0 += LZMA.reverseDecode2(this._posDecoders,
-                rep0 - posSlot - 1, this._rangeDecoder, numDirectBits);
-					}else {
-						rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4;
-						rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder);
-						if (rep0 < 0) {
-							if (rep0 === -1) {
-								break;
-							}
-							return false;
-						}
-					}
-				}else {
-					rep0 = posSlot;
-				}
-			}
-
-			if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck) {
-				return false;
-			}
-
-			this._outWindow.copyBlock(rep0, len);
-			nowPos64 += len;
-			prevByte = this._outWindow.getByte(0);
-		}
-	}
-
-	this._outWindow.flush();
-	this._outWindow.releaseStream();
-	this._rangeDecoder.releaseStream();
-
-	return true;
-};
-
-LZMA.Decoder.prototype.setDecoderProperties = function(properties) {
-	var value, lc, lp, pb, dictionarySize;
-
-	if (properties.size < 5) {
-		return false;
-	}
-
-	value = properties.readByte();
-	lc = value % 9;
-	value = ~~(value / 9);
-	lp = value % 5;
-	pb = ~~(value / 5);
-
-	if ( !this.setLcLpPb(lc, lp, pb) ) {
-		return false;
-	}
-
-	dictionarySize = properties.readByte();
-	dictionarySize |= properties.readByte() << 8;
-	dictionarySize |= properties.readByte() << 16;
-	dictionarySize += properties.readByte() * 16777216;
-
-	return this.setDictionarySize(dictionarySize);
-};
-
-LZMA.decompress = function(properties, inStream, outStream, outSize) {
-	var decoder = new LZMA.Decoder();
-
-	if ( !decoder.setDecoderProperties(properties) ) {
-		throw "Incorrect stream properties";
-	}
-
-	if ( !decoder.decode(inStream, outStream, outSize) ) {
-		throw "Error in data stream";
-	}
-
-	return true;
-};

+ 18 - 12
examples/js/loaders/STLLoader.js

@@ -3,6 +3,7 @@
  * @author mrdoob / http://mrdoob.com/
  * @author gero3 / https://github.com/gero3
  * @author Mugen87 / https://github.com/Mugen87
+ * @author neverhood311 / https://github.com/neverhood311
  *
  * Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
  *
@@ -148,7 +149,7 @@ THREE.STLLoader.prototype = {
 					( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) {
 
 					hasColors = true;
-					colors = [];
+					colors = new Float32Array( faces * 3 * 3 );
 
 					defaultR = reader.getUint8( index + 6 ) / 255;
 					defaultG = reader.getUint8( index + 7 ) / 255;
@@ -164,8 +165,8 @@ THREE.STLLoader.prototype = {
 
 			var geometry = new THREE.BufferGeometry();
 
-			var vertices = [];
-			var normals = [];
+			var vertices = new Float32Array( faces * 3 * 3 );
+			var normals = new Float32Array( faces * 3 * 3 );
 
 			for ( var face = 0; face < faces; face ++ ) {
 
@@ -199,16 +200,21 @@ THREE.STLLoader.prototype = {
 				for ( var i = 1; i <= 3; i ++ ) {
 
 					var vertexstart = start + i * 12;
+					var componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 );
+					
+					vertices[ componentIdx ] = reader.getFloat32( vertexstart, true );
+					vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true );
+					vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true );
 
-					vertices.push( reader.getFloat32( vertexstart, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 4, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 8, true ) );
-
-					normals.push( normalX, normalY, normalZ );
+					normals[ componentIdx ] = normalX;
+					normals[ componentIdx + 1 ] = normalY;
+					normals[ componentIdx + 2 ] = normalZ;
 
 					if ( hasColors ) {
 
-						colors.push( r, g, b );
+						colors[ componentIdx ] = r;
+						colors[ componentIdx + 1 ] = g;
+						colors[ componentIdx + 2 ] = b;
 
 					}
 
@@ -216,12 +222,12 @@ THREE.STLLoader.prototype = {
 
 			}
 
-			geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
-			geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+			geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+			geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
 
 			if ( hasColors ) {
 
-				geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
+				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
 				geometry.hasColors = true;
 				geometry.alpha = alpha;
 

+ 0 - 279
examples/js/loaders/ctm/CTMLoader.js

@@ -1,279 +0,0 @@
-/**
- * Loader for CTM encoded models generated by OpenCTM tools:
- *	http://openctm.sourceforge.net/
- *
- * Uses js-openctm library by Juan Mellado
- *	http://code.google.com/p/js-openctm/
- *
- * @author alteredq / http://alteredqualia.com/
- *
- * OpenCTM LICENSE:
- *
- * Copyright (c) 2009-2010 Marcus Geelnard
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- *     1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- *
- *    2. Altered source versions must be plainly marked as such, and must not
- *    be misrepresented as being the original software.
- *
- *    3. This notice may not be removed or altered from any source
- *    distribution.
- *
- */
-
-/* global CTM */
-
-THREE.CTMLoader = function () {
-
-	this.workerPath = null;
-
-};
-
-THREE.CTMLoader.prototype.constructor = THREE.CTMLoader;
-
-THREE.CTMLoader.prototype.setWorkerPath = function ( workerPath ) {
-
-	this.workerPath = workerPath;
-
-};
-
-// Load multiple CTM parts defined in JSON
-
-THREE.CTMLoader.prototype.loadParts = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var xhr = new XMLHttpRequest();
-
-	var basePath = parameters.basePath ? parameters.basePath : THREE.LoaderUtils.extractUrlBase( url );
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var jsonObject = JSON.parse( xhr.responseText );
-
-				var materials = [], geometries = [], counter = 0;
-
-				function callbackFinal( geometry ) {
-
-					counter += 1;
-
-					geometries.push( geometry );
-
-					if ( counter === jsonObject.offsets.length ) {
-
-						callback( geometries, materials );
-
-					}
-
-				}
-
-
-				// init materials
-
-				for ( var i = 0; i < jsonObject.materials.length; i ++ ) {
-
-					materials[ i ] = THREE.Loader.prototype.createMaterial( jsonObject.materials[ i ], basePath );
-
-				}
-
-				// load joined CTM file
-
-				var partUrl = basePath + jsonObject.data;
-				var parametersPart = { useWorker: parameters.useWorker, worker: parameters.worker, offsets: jsonObject.offsets };
-				scope.load( partUrl, callbackFinal, parametersPart );
-
-			}
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.setRequestHeader( "Content-Type", "text/plain" );
-	xhr.send( null );
-
-};
-
-// Load CTMLoader compressed models
-//	- parameters
-//		- url (required)
-//		- callback (required)
-
-THREE.CTMLoader.prototype.load = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var offsets = parameters.offsets !== undefined ? parameters.offsets : [ 0 ];
-
-	var xhr = new XMLHttpRequest(),
-		callbackProgress = null;
-
-	var length = 0;
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var binaryData = new Uint8Array( xhr.response );
-
-				var s = Date.now();
-
-				if ( parameters.useWorker ) {
-
-					var worker = parameters.worker || new Worker( scope.workerPath );
-
-					worker.onmessage = function ( event ) {
-
-						var files = event.data;
-
-						for ( var i = 0; i < files.length; i ++ ) {
-
-							var ctmFile = files[ i ];
-
-							var e1 = Date.now();
-							// console.log( "CTM data parse time [worker]: " + (e1-s) + " ms" );
-
-							scope._createGeometry( ctmFile, callback );
-
-							var e = Date.now();
-							console.log( "model load time [worker]: " + ( e - e1 ) + " ms, total: " + ( e - s ) );
-
-						}
-
-
-					};
-
-					worker.postMessage( { "data": binaryData, "offsets": offsets }, [ binaryData.buffer ] );
-
-				} else {
-
-					for ( var i = 0; i < offsets.length; i ++ ) {
-
-						var stream = new CTM.Stream( binaryData );
-						stream.offset = offsets[ i ];
-
-						var ctmFile = new CTM.File( stream );
-
-						scope._createGeometry( ctmFile, callback );
-
-					}
-
-					//var e = Date.now();
-					//console.log( "CTM data parse time [inline]: " + (e-s) + " ms" );
-
-				}
-
-			} else {
-
-				console.error( "Couldn't load [" + url + "] [" + xhr.status + "]" );
-
-			}
-
-		} else if ( xhr.readyState === 3 ) {
-
-			if ( callbackProgress ) {
-
-				if ( length === 0 ) {
-
-					length = xhr.getResponseHeader( "Content-Length" );
-
-				}
-
-				callbackProgress( { total: length, loaded: xhr.responseText.length } );
-
-			}
-
-		} else if ( xhr.readyState === 2 ) {
-
-			length = xhr.getResponseHeader( "Content-Length" );
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.responseType = "arraybuffer";
-
-	xhr.send( null );
-
-};
-
-
-THREE.CTMLoader.prototype._createGeometry = function ( file, callback ) {
-
-	var geometry = new THREE.BufferGeometry();
-
-	var indices = file.body.indices;
-	var positions = file.body.vertices;
-	var normals = file.body.normals;
-
-	var uvs, colors;
-
-	var uvMaps = file.body.uvMaps;
-
-	if ( uvMaps !== undefined && uvMaps.length > 0 ) {
-
-		uvs = uvMaps[ 0 ].uv;
-
-	}
-
-	var attrMaps = file.body.attrMaps;
-
-	if ( attrMaps !== undefined && attrMaps.length > 0 && attrMaps[ 0 ].name === 'Color' ) {
-
-		colors = attrMaps[ 0 ].attr;
-
-	}
-
-	geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
-	geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
-
-	if ( normals !== undefined ) {
-
-		geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
-
-	}
-
-	if ( uvs !== undefined ) {
-
-		geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
-
-	}
-
-	if ( colors !== undefined ) {
-
-		geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 4 ) );
-
-	}
-
-	// compute vertex normals if not present in the CTM model
-	if ( geometry.attributes.normal === undefined ) {
-
-		geometry.computeVertexNormals();
-
-	}
-
-	callback( geometry );
-
-};

+ 0 - 19
examples/js/loaders/ctm/CTMWorker.js

@@ -1,19 +0,0 @@
-importScripts( "../../libs/lzma.js", "../../libs/ctm.js" );
-
-self.onmessage = function ( event ) {
-
-	var files = [];
-
-	for ( var i = 0; i < event.data.offsets.length; i ++ ) {
-
-		var stream = new CTM.Stream( event.data.data );
-		stream.offset = event.data.offsets[ i ];
-
-		files[ i ] = new CTM.File( stream, [ event.data.data.buffer ] );
-
-	}
-
-	self.postMessage( files );
-	self.close();
-
-};

+ 2 - 162
examples/jsm/controls/OrbitControls.js

@@ -470,32 +470,24 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseDownRotate( event ) {
 
-		//console.log( 'handleMouseDownRotate' );
-
 		rotateStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownDolly( event ) {
 
-		//console.log( 'handleMouseDownDolly' );
-
 		dollyStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseDownPan( event ) {
 
-		//console.log( 'handleMouseDownPan' );
-
 		panStart.set( event.clientX, event.clientY );
 
 	}
 
 	function handleMouseMoveRotate( event ) {
 
-		//console.log( 'handleMouseMoveRotate' );
-
 		rotateEnd.set( event.clientX, event.clientY );
 
 		rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
@@ -514,8 +506,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMoveDolly( event ) {
 
-		//console.log( 'handleMouseMoveDolly' );
-
 		dollyEnd.set( event.clientX, event.clientY );
 
 		dollyDelta.subVectors( dollyEnd, dollyStart );
@@ -538,8 +528,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseMovePan( event ) {
 
-		//console.log( 'handleMouseMovePan' );
-
 		panEnd.set( event.clientX, event.clientY );
 
 		panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
@@ -554,14 +542,12 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleMouseUp( /*event*/ ) {
 
-		// console.log( 'handleMouseUp' );
+		// no-op
 
 	}
 
 	function handleMouseWheel( event ) {
 
-		// console.log( 'handleMouseWheel' );
-
 		if ( event.deltaY < 0 ) {
 
 			dollyOut( getZoomScale() );
@@ -578,8 +564,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleKeyDown( event ) {
 
-		// console.log( 'handleKeyDown' );
-
 		var needsUpdate = false;
 
 		switch ( event.keyCode ) {
@@ -620,8 +604,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartRotate( event ) {
 
-		//console.log( 'handleTouchStartRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -639,8 +621,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartPan( event ) {
 
-		//console.log( 'handleTouchStartPan' );
-
 		if ( event.touches.length == 1 ) {
 
 			panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -658,8 +638,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDolly( event ) {
 
-		//console.log( 'handleTouchStartDolly' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -671,8 +649,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyPan( event ) {
 
-		//console.log( 'handleTouchStartDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enablePan ) handleTouchStartPan( event );
@@ -681,8 +657,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchStartDollyRotate( event ) {
 
-		//console.log( 'handleTouchStartDollyRotate' );
-
 		if ( scope.enableZoom ) handleTouchStartDolly( event );
 
 		if ( scope.enableRotate ) handleTouchStartRotate( event );
@@ -691,8 +665,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveRotate( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -720,8 +692,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMovePan( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		if ( event.touches.length == 1 ) {
 
 			panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
@@ -745,8 +715,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDolly( event ) {
 
-		//console.log( 'handleTouchMoveRotate' );
-
 		var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
 		var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
 
@@ -764,8 +732,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyPan( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enablePan ) handleTouchMovePan( event );
@@ -774,8 +740,6 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchMoveDollyRotate( event ) {
 
-		//console.log( 'handleTouchMoveDollyPan' );
-
 		if ( scope.enableZoom ) handleTouchMoveDolly( event );
 
 		if ( scope.enableRotate ) handleTouchMoveRotate( event );
@@ -784,7 +748,7 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleTouchEnd( /*event*/ ) {
 
-		//console.log( 'handleTouchEnd' );
+		// no-op
 
 	}
 
@@ -1191,130 +1155,6 @@ var OrbitControls = function ( object, domElement ) {
 OrbitControls.prototype = Object.create( EventDispatcher.prototype );
 OrbitControls.prototype.constructor = OrbitControls;
 
-Object.defineProperties( OrbitControls.prototype, {
-
-	center: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
-			return this.target;
-
-		}
-
-	},
-
-	// backward compatibility
-
-	noZoom: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			return ! this.enableZoom;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
-			this.enableZoom = ! value;
-
-		}
-
-	},
-
-	noRotate: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			return ! this.enableRotate;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
-			this.enableRotate = ! value;
-
-		}
-
-	},
-
-	noPan: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			return ! this.enablePan;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
-			this.enablePan = ! value;
-
-		}
-
-	},
-
-	noKeys: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			return ! this.enableKeys;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
-			this.enableKeys = ! value;
-
-		}
-
-	},
-
-	staticMoving: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			return ! this.enableDamping;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
-			this.enableDamping = ! value;
-
-		}
-
-	},
-
-	dynamicDampingFactor: {
-
-		get: function () {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			return this.dampingFactor;
-
-		},
-
-		set: function ( value ) {
-
-			console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
-			this.dampingFactor = value;
-
-		}
-
-	}
-
-} );
 
 // This set of controls performs orbiting, dollying (zooming), and panning.
 // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).

+ 1 - 0
examples/jsm/loaders/GLTFLoader.js

@@ -2205,6 +2205,7 @@ var GLTFLoader = ( function () {
 				pointsMaterial.color.copy( material.color );
 				pointsMaterial.map = material.map;
 				pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
+				pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px
 
 				this.cache.add( cacheKey, pointsMaterial );
 

+ 18 - 12
examples/jsm/loaders/STLLoader.js

@@ -3,6 +3,7 @@
  * @author mrdoob / http://mrdoob.com/
  * @author gero3 / https://github.com/gero3
  * @author Mugen87 / https://github.com/Mugen87
+ * @author neverhood311 / https://github.com/neverhood311
  *
  * Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
  *
@@ -158,7 +159,7 @@ STLLoader.prototype = {
 					( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) {
 
 					hasColors = true;
-					colors = [];
+					colors = new Float32Array( faces * 3 * 3 );
 
 					defaultR = reader.getUint8( index + 6 ) / 255;
 					defaultG = reader.getUint8( index + 7 ) / 255;
@@ -174,8 +175,8 @@ STLLoader.prototype = {
 
 			var geometry = new BufferGeometry();
 
-			var vertices = [];
-			var normals = [];
+			var vertices = new Float32Array( faces * 3 * 3 );
+			var normals = new Float32Array( faces * 3 * 3 );
 
 			for ( var face = 0; face < faces; face ++ ) {
 
@@ -209,16 +210,21 @@ STLLoader.prototype = {
 				for ( var i = 1; i <= 3; i ++ ) {
 
 					var vertexstart = start + i * 12;
+					var componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 );
+					
+					vertices[ componentIdx ] = reader.getFloat32( vertexstart, true );
+					vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true );
+					vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true );
 
-					vertices.push( reader.getFloat32( vertexstart, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 4, true ) );
-					vertices.push( reader.getFloat32( vertexstart + 8, true ) );
-
-					normals.push( normalX, normalY, normalZ );
+					normals[ componentIdx ] = normalX;
+					normals[ componentIdx + 1 ] = normalY;
+					normals[ componentIdx + 2 ] = normalZ;
 
 					if ( hasColors ) {
 
-						colors.push( r, g, b );
+						colors[ componentIdx ] = r;
+						colors[ componentIdx + 1 ] = g;
+						colors[ componentIdx + 2 ] = b;
 
 					}
 
@@ -226,12 +232,12 @@ STLLoader.prototype = {
 
 			}
 
-			geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( vertices ), 3 ) );
-			geometry.addAttribute( 'normal', new BufferAttribute( new Float32Array( normals ), 3 ) );
+			geometry.addAttribute( 'position', new BufferAttribute( vertices, 3 ) );
+			geometry.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );
 
 			if ( hasColors ) {
 
-				geometry.addAttribute( 'color', new BufferAttribute( new Float32Array( colors ), 3 ) );
+				geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );
 				geometry.hasColors = true;
 				geometry.alpha = alpha;
 

+ 0 - 20
examples/jsm/loaders/ctm/CTMLoader.d.ts

@@ -1,20 +0,0 @@
-import {
-  BufferGeometry,
-  Material
-} from '../../../../src/Three';
-
-export interface CTMLoaderParameters {
-  basePath?: string;
-  offsets?: number[];
-  useWorker?: boolean;
-  worker?: object;
-}
-
-export class CTMLoader {
-  constructor();
-  workerPath: string;
-
-  load(url: string, onLoad: (geometry: BufferGeometry) => void, parameters: CTMLoaderParameters): void;
-  loadParts(url: string, onLoad: (geometries: BufferGeometry[], materials: Material[]) => void, parameters: CTMLoaderParameters): void;
-  setWorkerPath(value: string): this;
-}

+ 0 - 288
examples/jsm/loaders/ctm/CTMLoader.js

@@ -1,288 +0,0 @@
-/**
- * Loader for CTM encoded models generated by OpenCTM tools:
- *	http://openctm.sourceforge.net/
- *
- * Uses js-openctm library by Juan Mellado
- *	http://code.google.com/p/js-openctm/
- *
- * @author alteredq / http://alteredqualia.com/
- *
- * OpenCTM LICENSE:
- *
- * Copyright (c) 2009-2010 Marcus Geelnard
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- *     1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- *
- *    2. Altered source versions must be plainly marked as such, and must not
- *    be misrepresented as being the original software.
- *
- *    3. This notice may not be removed or altered from any source
- *    distribution.
- *
- */
-
-import {
-	BufferAttribute,
-	BufferGeometry,
-	Loader,
-	LoaderUtils
-} from "../../../../build/three.module.js";
-
-/* global CTM */
-
-var CTMLoader = function () {
-
-	this.workerPath = null;
-
-};
-
-CTMLoader.prototype.constructor = CTMLoader;
-
-CTMLoader.prototype.setWorkerPath = function ( workerPath ) {
-
-	this.workerPath = workerPath;
-
-};
-
-// Load multiple CTM parts defined in JSON
-
-CTMLoader.prototype.loadParts = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var xhr = new XMLHttpRequest();
-
-	var basePath = parameters.basePath ? parameters.basePath : LoaderUtils.extractUrlBase( url );
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var jsonObject = JSON.parse( xhr.responseText );
-
-				var materials = [], geometries = [], counter = 0;
-
-				function callbackFinal( geometry ) {
-
-					counter += 1;
-
-					geometries.push( geometry );
-
-					if ( counter === jsonObject.offsets.length ) {
-
-						callback( geometries, materials );
-
-					}
-
-				}
-
-
-				// init materials
-
-				for ( var i = 0; i < jsonObject.materials.length; i ++ ) {
-
-					materials[ i ] = Loader.prototype.createMaterial( jsonObject.materials[ i ], basePath );
-
-				}
-
-				// load joined CTM file
-
-				var partUrl = basePath + jsonObject.data;
-				var parametersPart = { useWorker: parameters.useWorker, worker: parameters.worker, offsets: jsonObject.offsets };
-				scope.load( partUrl, callbackFinal, parametersPart );
-
-			}
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.setRequestHeader( "Content-Type", "text/plain" );
-	xhr.send( null );
-
-};
-
-// Load CTMLoader compressed models
-//	- parameters
-//		- url (required)
-//		- callback (required)
-
-CTMLoader.prototype.load = function ( url, callback, parameters ) {
-
-	parameters = parameters || {};
-
-	var scope = this;
-
-	var offsets = parameters.offsets !== undefined ? parameters.offsets : [ 0 ];
-
-	var xhr = new XMLHttpRequest(),
-		callbackProgress = null;
-
-	var length = 0;
-
-	xhr.onreadystatechange = function () {
-
-		if ( xhr.readyState === 4 ) {
-
-			if ( xhr.status === 200 || xhr.status === 0 ) {
-
-				var binaryData = new Uint8Array( xhr.response );
-
-				var s = Date.now();
-
-				if ( parameters.useWorker ) {
-
-					var worker = parameters.worker || new Worker( scope.workerPath );
-
-					worker.onmessage = function ( event ) {
-
-						var files = event.data;
-
-						for ( var i = 0; i < files.length; i ++ ) {
-
-							var ctmFile = files[ i ];
-
-							var e1 = Date.now();
-							// console.log( "CTM data parse time [worker]: " + (e1-s) + " ms" );
-
-							scope._createGeometry( ctmFile, callback );
-
-							var e = Date.now();
-							console.log( "model load time [worker]: " + ( e - e1 ) + " ms, total: " + ( e - s ) );
-
-						}
-
-
-					};
-
-					worker.postMessage( { "data": binaryData, "offsets": offsets }, [ binaryData.buffer ] );
-
-				} else {
-
-					for ( var i = 0; i < offsets.length; i ++ ) {
-
-						var stream = new CTM.Stream( binaryData );
-						stream.offset = offsets[ i ];
-
-						var ctmFile = new CTM.File( stream );
-
-						scope._createGeometry( ctmFile, callback );
-
-					}
-
-					//var e = Date.now();
-					//console.log( "CTM data parse time [inline]: " + (e-s) + " ms" );
-
-				}
-
-			} else {
-
-				console.error( "Couldn't load [" + url + "] [" + xhr.status + "]" );
-
-			}
-
-		} else if ( xhr.readyState === 3 ) {
-
-			if ( callbackProgress ) {
-
-				if ( length === 0 ) {
-
-					length = xhr.getResponseHeader( "Content-Length" );
-
-				}
-
-				callbackProgress( { total: length, loaded: xhr.responseText.length } );
-
-			}
-
-		} else if ( xhr.readyState === 2 ) {
-
-			length = xhr.getResponseHeader( "Content-Length" );
-
-		}
-
-	};
-
-	xhr.open( "GET", url, true );
-	xhr.responseType = "arraybuffer";
-
-	xhr.send( null );
-
-};
-
-
-CTMLoader.prototype._createGeometry = function ( file, callback ) {
-
-	var geometry = new BufferGeometry();
-
-	var indices = file.body.indices;
-	var positions = file.body.vertices;
-	var normals = file.body.normals;
-
-	var uvs, colors;
-
-	var uvMaps = file.body.uvMaps;
-
-	if ( uvMaps !== undefined && uvMaps.length > 0 ) {
-
-		uvs = uvMaps[ 0 ].uv;
-
-	}
-
-	var attrMaps = file.body.attrMaps;
-
-	if ( attrMaps !== undefined && attrMaps.length > 0 && attrMaps[ 0 ].name === 'Color' ) {
-
-		colors = attrMaps[ 0 ].attr;
-
-	}
-
-	geometry.setIndex( new BufferAttribute( indices, 1 ) );
-	geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );
-
-	if ( normals !== undefined ) {
-
-		geometry.addAttribute( 'normal', new BufferAttribute( normals, 3 ) );
-
-	}
-
-	if ( uvs !== undefined ) {
-
-		geometry.addAttribute( 'uv', new BufferAttribute( uvs, 2 ) );
-
-	}
-
-	if ( colors !== undefined ) {
-
-		geometry.addAttribute( 'color', new BufferAttribute( colors, 4 ) );
-
-	}
-
-	// compute vertex normals if not present in the CTM model
-	if ( geometry.attributes.normal === undefined ) {
-
-		geometry.computeVertexNormals();
-
-	}
-
-	callback( geometry );
-
-};
-
-export { CTMLoader };

+ 9 - 2
examples/jsm/nodes/core/FunctionNode.js

@@ -12,6 +12,7 @@ var declarationRegexp = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i,
 function FunctionNode( src, includes, extensions, keywords, type ) {
 
 	this.isMethod = type === undefined;
+	this.isInterface = false;
 
 	TempNode.call( this, type );
 
@@ -139,7 +140,11 @@ FunctionNode.prototype.generate = function ( builder, output ) {
 
 	} else if ( this.isMethod ) {
 
-		builder.include( this, false, src );
+		if ( ! this.isInterface ) {
+
+			builder.include( this, false, src );
+
+		}
 
 		return this.name;
 
@@ -181,7 +186,7 @@ FunctionNode.prototype.parse = function ( src, includes, extensions, keywords )
 					var qualifier = inputs[ i ++ ];
 					var type, name;
 
-					if ( qualifier == 'in' || qualifier == 'out' || qualifier == 'inout' ) {
+					if ( qualifier === 'in' || qualifier === 'out' || qualifier === 'inout' ) {
 
 						type = inputs[ i ++ ];
 
@@ -204,6 +209,8 @@ FunctionNode.prototype.parse = function ( src, includes, extensions, keywords )
 
 			}
 
+			this.isInterface = this.src.indexOf('{') === -1;
+
 		} else {
 
 			this.type = '';

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

@@ -34,8 +34,6 @@ StandardNode.prototype.build = function ( builder ) {
 
 	builder.define( this.clearCoat || this.clearCoatRoughness ? 'PHYSICAL' : 'STANDARD' );
 
-	if ( this.energyPreservation ) builder.define( 'ENERGY_PRESERVATION' );
-
 	builder.requires.lights = true;
 
 	builder.extensions.shaderTextureLOD = true;

+ 5 - 3
examples/jsm/nodes/misc/TextureCubeNode.js

@@ -11,17 +11,19 @@ import { NormalNode } from '../accessors/NormalNode.js';
 import { ColorSpaceNode } from '../utils/ColorSpaceNode.js';
 import { BlinnExponentToRoughnessNode } from '../bsdfs/BlinnExponentToRoughnessNode.js';
 
-function TextureCubeNode( value, textureSize ) {
+function TextureCubeNode( value, textureSize, uv, bias ) {
 
 	TempNode.call( this, 'v4' );
 
 	this.value = value;
 	this.textureSize = textureSize || new FloatNode( 1024 );
+	this.uv = uv || new ReflectNode( ReflectNode.VECTOR );
+	this.bias = bias || new BlinnExponentToRoughnessNode();
 
 	this.radianceCache = { uv: new TextureCubeUVNode(
-		new ReflectNode( ReflectNode.VECTOR ),
+		this.uv,
 		this.textureSize,
-		new BlinnExponentToRoughnessNode()
+		this.bias
 	) };
 
 	this.irradianceCache = { uv: new TextureCubeUVNode(

BIN
examples/models/ctm/LeePerry.ctm


BIN
examples/models/ctm/WaltHead.ctm


BIN
examples/models/ctm/ben.ctm


BIN
examples/models/ctm/camaro/camaro.ctm


+ 0 - 113
examples/models/ctm/camaro/camaro.js

@@ -1,113 +0,0 @@
-{
-"data" : "camaro.ctm",
-
-"offsets": [ 0, 39262, 79223, 83542, 94677, 95890, 144902, 470461 ],
-
-"materials" :
-	[
-	{
-	"DbgColor" : 15658734,
-	"DbgIndex" : 0,
-	"DbgName" : "Body_car-ao",
-	"colorDiffuse" : [0.1816, 0.3264, 0.3704],
-	"colorSpecular" : [2.0, 2.0, 2.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 778.431373,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 15597568,
-	"DbgIndex" : 1,
-	"DbgName" : "tire_car-ao",
-	"colorDiffuse" : [0.2168, 0.2168, 0.2104],
-	"colorSpecular" : [0.1, 0.1, 0.1],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 15.686275,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 60928,
-	"DbgIndex" : 2,
-	"DbgName" : "black2_car-ao",
-	"colorDiffuse" : [0.0, 0.0, 0.0],
-	"colorSpecular" : [0.0, 0.0, 0.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 0.0,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 238,
-	"DbgIndex" : 3,
-	"DbgName" : "tireling_car-ao",
-	"colorDiffuse" : [0.4, 0.4, 0.4],
-	"colorSpecular" : [0.2, 0.2, 0.2],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 15.686275,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 15658496,
-	"DbgIndex" : 4,
-	"DbgName" : "glass_car-ao",
-	"colorDiffuse" : [0.16, 0.248, 0.2448],
-	"colorSpecular" : [2.0, 2.0, 2.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 778.431373,
-	"opacity" : 0.34
-	},
-
-	{
-	"DbgColor" : 61166,
-	"DbgIndex" : 5,
-	"DbgName" : "black_car-ao",
-	"colorDiffuse" : [0.0816, 0.0816, 0.0816],
-	"colorSpecular" : [0.2, 0.2, 0.2],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 3.921569,
-	"opacity" : 1.0
-	},
-
-	{
-	"DbgColor" : 15597806,
-	"DbgIndex" : 6,
-	"DbgName" : "mirror_car-ao",
-	"colorDiffuse" : [0.24, 0.24, 0.24],
-	"colorSpecular" : [2.0, 2.0, 2.0],
-	"illumination" : 2,
-	"mapDiffuse" : "car-ao.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 778.431373,
-	"opacity" : 1.0
-	},
-
-
-	{
-	"DbgColor" : 3744854,
-	"DbgIndex" : 8,
-	"DbgName" : "Material.001_plane-ao-256",
-	"colorDiffuse" : [0.798635, 0.776149, 0.8],
-	"colorSpecular" : [0.5, 0.5, 0.5],
-	"illumination" : 2,
-	"mapDiffuse" : "plane-ao-256.png",
-	"opticalDensity" : 1.0,
-	"specularCoef" : 96.078431,
-	"opacity" : 1.0
-	}
-	]
-}

BIN
examples/models/ctm/camaro/car-ao.png


BIN
examples/models/ctm/camaro/plane-ao-256.png


BIN
examples/models/ctm/hand.ctm


BIN
examples/textures/nvidia_tentacle/tentacle_object_space.png


BIN
examples/textures/nvidia_tentacle/tentacle_tangent_space.png


+ 1 - 0
examples/textures/pbr/Scratched_gold/Scratched_gold.txt

@@ -0,0 +1 @@
+https://www.cgbookcase.com/textures/scratched-gold-01

BIN
examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_AO.png


BIN
examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Base_Color.png


BIN
examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Height.png


BIN
examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Normal.png


BIN
examples/textures/pbr/Scratched_gold/Scratched_gold_01_1K_Roughness.png


+ 7 - 3
examples/webgl_furnace_test.html

@@ -60,18 +60,22 @@
 
 			function createObjects() {
 
-				var geo = new THREE.SphereBufferGeometry( 0.4, 32, 32 );
+				var geometry = new THREE.SphereBufferGeometry( 0.4, 32, 32 );
+
 				var count = 10;
+
 				for ( var x = 0; x <= count; x ++ ) {
 
-					var mesh = new THREE.Mesh( geo, new THREE.MeshPhysicalMaterial( {
+					var material = new THREE.MeshPhysicalMaterial( {
 						roughness: x / count,
 						metalness: 1,
 						color: 0xffffff,
 						envMap: radianceMap,
 						envMapIntensity: 1,
 						reflectivity: 1,
-					} ) );
+					} );
+
+					var mesh = new THREE.Mesh( geometry, material );
 					mesh.position.x = x - ( Math.floor( count / 2 ) );
 					scene.add( mesh );
 

+ 0 - 242
examples/webgl_loader_ctm_materials.html

@@ -1,242 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webgl - CTM loader materials</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<link type="text/css" rel="stylesheet" href="main.css">
-	</head>
-	<body>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl -
-			using <a href="https://github.com/jcmellado/js-openctm"  target="_blank" rel="noopener">js-openctm</a><br/>
-			camaro by <a href="http://www.turbosquid.com/3d-models/blender-camaro/411348" target="_blank" rel="noopener">dskfnwn</a> -
-			skybox by <a href="http://ict.debevec.org/~debevec/" target="_blank" rel="noopener">Paul Debevec</a>
-		</div>
-
-		<script type="module">
-
-			import * as THREE from '../build/three.module.js';
-
-			import Stats from './jsm/libs/stats.module.js';
-
-			import { CTMLoader } from './jsm/loaders/ctm/CTMLoader.js';
-			import { OrbitControls } from './jsm/controls/OrbitControls.js';
-
-			var SCREEN_WIDTH = window.innerWidth;
-			var SCREEN_HEIGHT = window.innerHeight;
-
-			var container, stats;
-
-			var camera, scene, controls;
-			var renderer;
-
-			var textureCube;
-
-			init();
-			animate();
-
-			function init() {
-
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
-				// CAMERA
-
-				camera = new THREE.PerspectiveCamera( 30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
-				camera.position.set( 185, 40, 170 );
-
-				// SCENE
-
-				var r = "textures/cube/pisa/";
-				var urls = [
-					r + "px.png", r + "nx.png",
-					r + "py.png", r + "ny.png",
-					r + "pz.png", r + "nz.png"
-				];
-
-				textureCube = new THREE.CubeTextureLoader().load( urls );
-
-				scene = new THREE.Scene();
-				scene.background = textureCube;
-
-				// LIGHTS
-
-				var light = new THREE.PointLight( 0xffffff, 1 );
-				light.position.set( 2, 5, 1 );
-				light.position.multiplyScalar( 30 );
-				scene.add( light );
-
-				var light = new THREE.PointLight( 0xffffff, 0.75 );
-				light.position.set( - 12, 4.6, 2.4 );
-				light.position.multiplyScalar( 30 );
-				scene.add( light );
-
-				scene.add( new THREE.AmbientLight( 0x050505 ) );
-
-				// RENDERER
-
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
-				renderer.gammaInput = true;
-				renderer.gammaOutput = true;
-				renderer.domElement.style.position = "relative";
-				container.appendChild( renderer.domElement );
-
-				controls = new OrbitControls( camera, renderer.domElement );
-				controls.maxPolarAngle = Math.PI / 2;
-				controls.minDistance = 150;
-				controls.maxDistance = 500;
-
-				// STATS
-
-				stats = new Stats();
-				container.appendChild( stats.dom );
-
-				// EVENTS
-
-				window.addEventListener( 'resize', onWindowResize, false );
-
-				// LOADER
-
-				var start = Date.now();
-
-				// new way via CTMLoader and separate parts
-
-				var position = new THREE.Vector3( - 105, - 78, - 30 );
-				var scale = new THREE.Vector3( 30, 30, 30 );
-
-				var loader = new CTMLoader();
-				loader.setWorkerPath( "js/loaders/ctm/CTMWorker.js" );
-
-				loader.loadParts( "models/ctm/camaro/camaro.js", function ( geometries, materials ) {
-
-					hackMaterials( materials );
-
-					for ( var i = 0; i < geometries.length; i ++ ) {
-
-						var mesh = new THREE.Mesh( geometries[ i ], materials[ i ] );
-						mesh.position.copy( position );
-						mesh.scale.copy( scale );
-						scene.add( mesh );
-
-					}
-
-					var end = Date.now();
-
-					console.log( "load time:", end - start, "ms" );
-
-				}, { useWorker: true } );
-
-			}
-
-			//
-
-			function hackMaterials( materials ) {
-
-				for ( var i = 0; i < materials.length; i ++ ) {
-
-					var m = materials[ i ];
-
-					if ( m.name.indexOf( "Body" ) !== - 1 ) {
-
-						var mm = new THREE.MeshStandardMaterial();
-
-						mm.color.setHex( 0x000000 );
-						mm.lightMap = m.map;
-						mm.envMap = textureCube;
-						mm.metalness = 0.5;
-						mm.roughness = 0.3;
-
-						materials[ i ] = mm;
-
-					} else if ( m.name.indexOf( "tire_car" ) !== - 1 ) {
-
-						var mm = new THREE.MeshStandardMaterial();
-
-						mm.color.setHex( 0x000000 );
-						mm.lightMap = m.map;
-						mm.metalness = 0.1;
-						mm.roughness = 0.9;
-
-						materials[ i ] = mm;
-
-					} else if ( m.name.indexOf( "mirror" ) !== - 1 ) {
-
-						var mm = new THREE.MeshStandardMaterial();
-
-						mm.color.setHex( 0x808080 );
-						mm.lightMap = m.map;
-						mm.envMap = textureCube;
-						mm.metalness = 0.9;
-						mm.roughness = 0.5;
-
-						materials[ i ] = mm;
-
-					} else if ( m.name.indexOf( "glass" ) !== - 1 ) {
-
-						var mm = new THREE.MeshStandardMaterial();
-
-						mm.color.copy( m.color );
-						mm.envMap = textureCube;
-						mm.metalness = 1;
-						mm.roughtness = 0.1;
-						mm.opacity = m.opacity;
-						mm.transparent = true;
-
-						materials[ i ] = mm;
-
-					} else if ( m.name.indexOf( "Material.001" ) !== - 1 ) {
-
-						var mm = new THREE.MeshPhongMaterial( { map: m.map } );
-
-						mm.specularMap = m.map;
-						mm.shininess = 30;
-						mm.color.setHex( 0x404040 );
-
-						materials[ i ] = mm;
-
-					}
-
-					materials[ i ].side = THREE.DoubleSide;
-
-				}
-
-			}
-
-			//
-
-			function onWindowResize() {
-
-				SCREEN_WIDTH = window.innerWidth;
-				SCREEN_HEIGHT = window.innerHeight;
-
-				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
-
-				camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
-				camera.updateProjectionMatrix();
-
-			}
-
-			//
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-
-	</body>
-</html>

+ 0 - 3
examples/webgl_loader_stl.html

@@ -181,9 +181,6 @@
 				directionalLight.shadow.camera.near = 1;
 				directionalLight.shadow.camera.far = 4;
 
-				directionalLight.shadow.mapSize.width = 1024;
-				directionalLight.shadow.mapSize.height = 1024;
-
 				directionalLight.shadow.bias = - 0.002;
 
 			}

+ 13 - 8
examples/webgl_materials_clearcoat_normalmap.html

@@ -85,9 +85,9 @@
 						normalMap.wrapS = THREE.RepeatWrapping;
 						normalMap.wrapT = THREE.RepeatWrapping;
 
-						var clearCoatNormaMap = textureLoader.load( "textures/waternormals.jpg" );
-						clearCoatNormaMap.wrapS = THREE.RepeatWrapping;
-						clearCoatNormaMap.wrapT = THREE.RepeatWrapping;
+						var normalMap2 = textureLoader.load( "textures/water/Water_1_M_Normal.jpg" );
+
+						var clearCoatNormaMap = textureLoader.load( "textures/pbr/Scratched_gold/Scratched_gold_01_1K_Normal.png" );
 
 						//
 
@@ -119,9 +119,11 @@
 
 						var material = new THREE.MeshPhysicalMaterial( {
 							clearCoat: 1.0,
+							metalness: 0.0,
+							color: 0xff0000,
 							envMap: hdrCubeRenderTarget.texture,
-							map: diffuse,
-							clearCoatNormalMap: clearCoatNormaMap
+							clearCoatNormalMap: clearCoatNormaMap,
+							clearCoatNormalScale: new THREE.Vector2( 2.0, 2.0 )
 						} );
 						var mesh = new THREE.Mesh( geometry, material );
 						mesh.position.x = - 100;
@@ -132,10 +134,13 @@
 
 						var material = new THREE.MeshPhysicalMaterial( {
 							clearCoat: 1.0,
+							metalness: 1.0,
+							color: 0xff0000,
 							envMap: hdrCubeRenderTarget.texture,
-							map: diffuse,
-							normalMap: normalMap,
-							clearCoatNormalMap: clearCoatNormaMap
+							normalMap: normalMap2,
+							normalScale: new THREE.Vector2( 0.15, 0.15 ),
+							clearCoatNormalMap: clearCoatNormaMap,
+							clearCoatNormalScale: new THREE.Vector2( 2.0, 2.0 )
 						} );
 						var mesh = new THREE.Mesh( geometry, material );
 						mesh.position.x = 100;

+ 139 - 69
examples/webgl_materials_nodes.html

@@ -71,63 +71,56 @@
 
 			}
 
-			var cubemap = function () {
+			var premTexture, pmremCube, pmremGenerator, pmremCubeUVPacker, premSize = 1024;
 
-				var path = "textures/cube/Park2/";
-				var format = '.jpg';
-				var urls = [
-					path + 'posx' + format, path + 'negx' + format,
-					path + 'posy' + format, path + 'negy' + format,
-					path + 'posz' + format, path + 'negz' + format
-				];
+			function updatePREM( textureCube ) {
 
-				var textureCube = new THREE.CubeTextureLoader().load( urls );
-				textureCube.format = THREE.RGBFormat;
+				pmremCube = pmremCube || textureCube;
 
-				library[ textureCube.uuid ] = textureCube;
+				if ( ! pmremCube || ! renderer ) return;
 
-				return textureCube;
+				var minFilter = pmremCube.minFilter;
+				var magFilter = pmremCube.magFilter;
+				var generateMipmaps = pmremCube.generateMipmaps;
 
-			}();
+				pmremGenerator = new PMREMGenerator( pmremCube, undefined, premSize / 4 );
+				pmremGenerator.update( renderer );
 
-			function generatePREM( cubeMap, textureSize ) {
+				pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
+				pmremCubeUVPacker.update( renderer );
 
-				textureSize = textureSize || 1024;
+				pmremCube.minFilter = minFilter;
+				pmremCube.magFilter = magFilter;
+				pmremCube.generateMipmaps = pmremCube.generateMipmaps;
+				pmremCube.needsUpdate = true;
 
-				var pmremGenerator = new PMREMGenerator( cubeMap, undefined, textureSize / 4 );
-				pmremGenerator.update( renderer );
+				premTexture = pmremCubeUVPacker.CubeUVRenderTarget.texture
 
-				var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
-				pmremCubeUVPacker.update( renderer );
+				library[ premTexture.uuid ] = premTexture;
 
 				pmremGenerator.dispose();
 				pmremCubeUVPacker.dispose();
 
-				return pmremCubeUVPacker.CubeUVRenderTarget.texture;
-
 			}
 
-			var premTexture;
-
-			function getPREM( callback, textureSize ) {
-
-				if ( premTexture ) return callback( premTexture );
-
-				var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
-				var hdrCubeMap = new HDRCubeTextureLoader()
-					.setPath( './textures/cube/pisaHDR/' )
-					.setDataType( THREE.UnsignedByteType )
-					.load( hdrUrls, function () {
+			var cubemap = function () {
 
-						premTexture = generatePREM( hdrCubeMap, textureSize );
+				var path = "textures/cube/Park2/";
+				var format = '.jpg';
+				var urls = [
+					path + 'posx' + format, path + 'negx' + format,
+					path + 'posy' + format, path + 'negy' + format,
+					path + 'posz' + format, path + 'negz' + format
+				];
 
-						library[ premTexture.uuid ] = premTexture;
+				var textureCube = new THREE.CubeTextureLoader().load( urls, updatePREM );
+				textureCube.format = THREE.RGBFormat;
 
-						callback( premTexture );
+				library[ textureCube.uuid ] = textureCube;
 
-					} );
+				return textureCube;
 
-			}
+			}();
 
 			window.addEventListener( 'load', init );
 
@@ -176,6 +169,8 @@
 				library[ camera.uuid ] = camera;
 				library[ mesh.uuid ] = mesh;
 
+				updatePREM();
+
 				window.addEventListener( 'resize', onWindowResize, false );
 
 				updateMaterial();
@@ -226,6 +221,7 @@
 					'adv / expression': 'expression',
 					'adv / sss': 'sss',
 					'adv / translucent': 'translucent',
+					'adv / bias': 'bias',
 					'node / position': 'node-position',
 					'node / normal': 'node-normal',
 					'node / reflect': 'node-reflect',
@@ -504,14 +500,8 @@
 						mtl.normal = new Nodes.NormalMapNode( new Nodes.TextureNode( getTexture( "grassNormal" ) ) );
 						mtl.normal.scale = normalMask;
 
-						getPREM(function(texture) {
-
-							var envNode = new Nodes.TextureCubeNode( new Nodes.TextureNode( texture ) );
-
-							mtl.environment = new Nodes.OperatorNode( envNode, intensity, Nodes.OperatorNode.MUL );
-							mtl.needsUpdate = true;
-
-						});
+						var envNode = new Nodes.TextureCubeNode( new Nodes.TextureNode( premTexture ) );
+						mtl.environment = new Nodes.OperatorNode( envNode, intensity, Nodes.OperatorNode.MUL );
 
 						// GUI
 
@@ -587,18 +577,13 @@
 						mtl.normal = new Nodes.NormalMapNode( new Nodes.TextureNode( getTexture( "grassNormal" ) ) );
 						mtl.normal.scale = normalScale;
 
-						getPREM(function(texture) {
+						var envNode = new Nodes.TextureCubeNode( new Nodes.TextureNode( premTexture ) );
 
-							var envNode = new Nodes.TextureCubeNode( new Nodes.TextureNode( texture ) );
-
-							var subSlotNode = new Nodes.SubSlotNode();
-							subSlotNode.slots['radiance'] = new Nodes.OperatorNode( radiance, envNode, Nodes.OperatorNode.MUL );
-							subSlotNode.slots['irradiance'] = new Nodes.OperatorNode( irradiance, envNode, Nodes.OperatorNode.MUL );
-
-							mtl.environment = subSlotNode;
-							mtl.needsUpdate = true;
+						var subSlotNode = new Nodes.SubSlotNode();
+						subSlotNode.slots['radiance'] = new Nodes.OperatorNode( radiance, envNode, Nodes.OperatorNode.MUL );
+						subSlotNode.slots['irradiance'] = new Nodes.OperatorNode( irradiance, envNode, Nodes.OperatorNode.MUL );
 
-						});
+						mtl.environment = subSlotNode
 
 						// GUI
 
@@ -2483,6 +2468,67 @@
 
 						break;
 
+					case 'bias':
+
+						// MATERIAL
+
+						var bias = new Nodes.FloatNode( .5 );
+						var maxMIPLevel = new Nodes.MaxMIPLevelNode( new Nodes.TextureCubeNode( cubemap ) );
+						var mipsBias = new Nodes.OperatorNode( bias, maxMIPLevel, Nodes.OperatorNode.MUL );
+
+						mtl = new Nodes.PhongNodeMaterial();
+						mtl.color.value.setHex( 0xFFFFFF );
+
+						function biasMode( val ) {
+
+							switch( val ) {
+
+								case 'prem':
+
+									mtl.color = new Nodes.TextureCubeNode( new Nodes.TextureNode( premTexture ), undefined, undefined, bias );
+
+									break;
+
+								case 'lod':
+
+									var textureCubeFunction = new Nodes.FunctionNode( 'vec4 textureCubeLodEXT( samplerCube texture, vec3 uv, float bias );', undefined, { shaderTextureLOD: true } 								);
+
+									mtl.color = new Nodes.FunctionCallNode( textureCubeFunction, [ new Nodes.CubeTextureNode( cubemap ), new Nodes.ReflectNode(), mipsBias ] );
+
+									break;
+
+								case 'basic':
+
+									var textureCubeFunction = new Nodes.FunctionNode( 'vec4 textureCube( samplerCube texture, vec3 uv, float bias );' );
+
+									mtl.color = new Nodes.FunctionCallNode( textureCubeFunction, [ new Nodes.CubeTextureNode( cubemap ), new Nodes.ReflectNode(), mipsBias ] );
+
+									break;
+
+							}
+
+							mtl.needsUpdate = true;
+
+						}
+
+						biasMode( 'prem' );
+
+						// GUI
+
+						addGui( 'scope', {
+							PREM: 'prem',
+							LOD: 'lod',
+							BASIC: 'basic'
+						}, biasMode );
+
+						addGui( 'bias', bias.value, function ( val ) {
+
+							bias.value = val;
+
+						}, false, 0, 1 );
+
+						break;
+
 					case 'node-position':
 
 						// MATERIAL
@@ -2534,28 +2580,52 @@
 
 					case 'node-reflect':
 
-						// MATERIAL
+							// MATERIAL
 
-						var node = new Nodes.ReflectNode();
+							var node = new Nodes.ReflectNode();
 
-						mtl = new Nodes.PhongNodeMaterial();
-						mtl.environment = new Nodes.CubeTextureNode( cubemap, node );
+							var nodeMaterial = new Nodes.StandardNodeMaterial();
+							nodeMaterial.environment = new Nodes.CubeTextureNode( cubemap, node );
+							nodeMaterial.roughness = new Nodes.FloatNode(0);
+							nodeMaterial.metalness = new Nodes.FloatNode(1);
 
-						// GUI
+							var standardMaterial = new THREE.MeshStandardMaterial( {
+								envMap: cubemap,
+								roughness: 0,
+								metalness: 1
+							} );
 
-						addGui( 'scope', {
-							vector: Nodes.ReflectNode.VECTOR,
-							cube: Nodes.ReflectNode.CUBE,
-							sphere: Nodes.ReflectNode.SPHERE
-						}, function ( val ) {
+							mtl = nodeMaterial;
 
-							node.scope = val;
+							// GUI
 
-							mtl.needsUpdate = true;
+							addGui( 'scope', {
+								vector: Nodes.ReflectNode.VECTOR,
+								cube: Nodes.ReflectNode.CUBE,
+								sphere: Nodes.ReflectNode.SPHERE
+							}, function ( val ) {
 
-						} );
+								node.scope = val;
 
-						break;
+								nodeMaterial.needsUpdate = true;
+
+							} );
+
+							addGui( 'node', true, function ( val ) {
+
+								mtl = val ? nodeMaterial : standardMaterial;
+								mesh.material = mtl;
+
+							} );
+
+							addGui( 'roughness', 0, function ( val ) {
+
+								nodeMaterial.roughness.value = val;
+								standardMaterial.roughness = val;
+
+							}, false, 0, 1 );
+
+							break;
 
 
 					case 'varying':

+ 3 - 10
src/Three.Legacy.js

@@ -594,17 +594,10 @@ Object.assign( Matrix4.prototype, {
 	},
 	getPosition: function () {
 
-		var v1;
+		console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
+		return new Vector3().setFromMatrixColumn( this, 3 );
 
-		return function getPosition() {
-
-			if ( v1 === undefined ) v1 = new Vector3();
-			console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
-			return v1.setFromMatrixColumn( this, 3 );
-
-		};
-
-	}(),
+	},
 	setRotationFromQuaternion: function ( q ) {
 
 		console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );

+ 66 - 63
src/animation/PropertyBinding.js

@@ -9,7 +9,10 @@
  */
 
 // Characters [].:/ are reserved for track binding syntax.
-var RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
+var _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
+
+var _reservedRe;
+var _trackRe, _supportedObjectNames;
 
 function Composite( targetGroup, path, optionalParsedPath ) {
 
@@ -109,101 +112,101 @@ Object.assign( PropertyBinding, {
 	 * @param {string} name Node name to be sanitized.
 	 * @return {string}
 	 */
-	sanitizeNodeName: ( function () {
+	sanitizeNodeName: function ( name ) {
 
-		var reservedRe = new RegExp( '[' + RESERVED_CHARS_RE + ']', 'g' );
+		if ( _reservedRe === undefined ) {
 
-		return function sanitizeNodeName( name ) {
+			_reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' );
 
-			return name.replace( /\s/g, '_' ).replace( reservedRe, '' );
+		}
 
-		};
+		return name.replace( /\s/g, '_' ).replace( _reservedRe, '' );
 
-	}() ),
+	},
 
-	parseTrackName: function () {
+	parseTrackName: function ( trackName ) {
 
-		// Attempts to allow node names from any language. ES5's `\w` regexp matches
-		// only latin characters, and the unicode \p{L} is not yet supported. So
-		// instead, we exclude reserved characters and match everything else.
-		var wordChar = '[^' + RESERVED_CHARS_RE + ']';
-		var wordCharOrDot = '[^' + RESERVED_CHARS_RE.replace( '\\.', '' ) + ']';
+		if ( _supportedObjectNames === undefined ) {
 
-		// Parent directories, delimited by '/' or ':'. Currently unused, but must
-		// be matched to parse the rest of the track name.
-		var directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', wordChar );
+			// Attempts to allow node names from any language. ES5's `\w` regexp matches
+			// only latin characters, and the unicode \p{L} is not yet supported. So
+			// instead, we exclude reserved characters and match everything else.
+			var wordChar = '[^' + _RESERVED_CHARS_RE + ']';
+			var wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']';
 
-		// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
-		var nodeRe = /(WCOD+)?/.source.replace( 'WCOD', wordCharOrDot );
+			// Parent directories, delimited by '/' or ':'. Currently unused, but must
+			// be matched to parse the rest of the track name.
+			var directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', wordChar );
 
-		// Object on target node, and accessor. May not contain reserved
-		// characters. Accessor may contain any character except closing bracket.
-		var objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', wordChar );
+			// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
+			var nodeRe = /(WCOD+)?/.source.replace( 'WCOD', wordCharOrDot );
 
-		// Property and accessor. May not contain reserved characters. Accessor may
-		// contain any non-bracket characters.
-		var propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', wordChar );
+			// Object on target node, and accessor. May not contain reserved
+			// characters. Accessor may contain any character except closing bracket.
+			var objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', wordChar );
 
-		var trackRe = new RegExp( ''
-			+ '^'
-			+ directoryRe
-			+ nodeRe
-			+ objectRe
-			+ propertyRe
-			+ '$'
-		);
+			// Property and accessor. May not contain reserved characters. Accessor may
+			// contain any non-bracket characters.
+			var propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', wordChar );
 
-		var supportedObjectNames = [ 'material', 'materials', 'bones' ];
+			_trackRe = new RegExp( ''
+				+ '^'
+				+ directoryRe
+				+ nodeRe
+				+ objectRe
+				+ propertyRe
+				+ '$'
+			);
 
-		return function parseTrackName( trackName ) {
+			_supportedObjectNames = [ 'material', 'materials', 'bones' ];
 
-			var matches = trackRe.exec( trackName );
+		}
 
-			if ( ! matches ) {
+		var matches = _trackRe.exec( trackName );
 
-				throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
+		if ( ! matches ) {
 
-			}
+			throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
 
-			var results = {
-				// directoryName: matches[ 1 ], // (tschw) currently unused
-				nodeName: matches[ 2 ],
-				objectName: matches[ 3 ],
-				objectIndex: matches[ 4 ],
-				propertyName: matches[ 5 ], // required
-				propertyIndex: matches[ 6 ]
-			};
+		}
 
-			var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
+		var results = {
+			// directoryName: matches[ 1 ], // (tschw) currently unused
+			nodeName: matches[ 2 ],
+			objectName: matches[ 3 ],
+			objectIndex: matches[ 4 ],
+			propertyName: matches[ 5 ], // required
+			propertyIndex: matches[ 6 ]
+		};
 
-			if ( lastDot !== undefined && lastDot !== - 1 ) {
+		var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
 
-				var objectName = results.nodeName.substring( lastDot + 1 );
+		if ( lastDot !== undefined && lastDot !== - 1 ) {
 
-				// Object names must be checked against a whitelist. Otherwise, there
-				// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
-				// 'bar' could be the objectName, or part of a nodeName (which can
-				// include '.' characters).
-				if ( supportedObjectNames.indexOf( objectName ) !== - 1 ) {
+			var objectName = results.nodeName.substring( lastDot + 1 );
 
-					results.nodeName = results.nodeName.substring( 0, lastDot );
-					results.objectName = objectName;
+			// Object names must be checked against a whitelist. Otherwise, there
+			// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
+			// 'bar' could be the objectName, or part of a nodeName (which can
+			// include '.' characters).
+			if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) {
 
-				}
+				results.nodeName = results.nodeName.substring( 0, lastDot );
+				results.objectName = objectName;
 
 			}
 
-			if ( results.propertyName === null || results.propertyName.length === 0 ) {
+		}
 
-				throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
+		if ( results.propertyName === null || results.propertyName.length === 0 ) {
 
-			}
+			throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
 
-			return results;
+		}
 
-		};
+		return results;
 
-	}(),
+	},
 
 	findNode: function ( root, nodeName ) {
 

+ 126 - 153
src/core/BufferGeometry.js

@@ -15,11 +15,14 @@ import { arrayMax } from '../utils.js';
  * @author mrdoob / http://mrdoob.com/
  */
 
-var bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id
+var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id
+var _m1, _obj, _offset;
+var _box, _boxMorphTargets;
+var _vector;
 
 function BufferGeometry() {
 
-	Object.defineProperty( this, 'id', { value: bufferGeometryId += 2 } );
+	Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } );
 
 	this.uuid = _Math.generateUUID();
 
@@ -182,129 +185,103 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
 	},
 
-	rotateX: function () {
+	rotateX: function ( angle ) {
 
 		// rotate geometry around world x-axis
 
-		var m1 = new Matrix4();
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-		return function rotateX( angle ) {
+		_m1.makeRotationX( angle );
 
-			m1.makeRotationX( angle );
+		this.applyMatrix( _m1 );
 
-			this.applyMatrix( m1 );
-
-			return this;
-
-		};
+		return this;
 
-	}(),
+	},
 
-	rotateY: function () {
+	rotateY: function ( angle ) {
 
 		// rotate geometry around world y-axis
 
-		var m1 = new Matrix4();
-
-		return function rotateY( angle ) {
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-			m1.makeRotationY( angle );
+		_m1.makeRotationY( angle );
 
-			this.applyMatrix( m1 );
+		this.applyMatrix( _m1 );
 
-			return this;
-
-		};
+		return this;
 
-	}(),
+	},
 
-	rotateZ: function () {
+	rotateZ: function ( angle ) {
 
 		// rotate geometry around world z-axis
 
-		var m1 = new Matrix4();
-
-		return function rotateZ( angle ) {
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-			m1.makeRotationZ( angle );
+		_m1.makeRotationZ( angle );
 
-			this.applyMatrix( m1 );
-
-			return this;
+		this.applyMatrix( _m1 );
 
-		};
+		return this;
 
-	}(),
+	},
 
-	translate: function () {
+	translate: function ( x, y, z ) {
 
 		// translate geometry
 
-		var m1 = new Matrix4();
-
-		return function translate( x, y, z ) {
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-			m1.makeTranslation( x, y, z );
+		_m1.makeTranslation( x, y, z );
 
-			this.applyMatrix( m1 );
+		this.applyMatrix( _m1 );
 
-			return this;
-
-		};
+		return this;
 
-	}(),
+	},
 
-	scale: function () {
+	scale: function ( x, y, z ) {
 
 		// scale geometry
 
-		var m1 = new Matrix4();
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-		return function scale( x, y, z ) {
+		_m1.makeScale( x, y, z );
 
-			m1.makeScale( x, y, z );
-
-			this.applyMatrix( m1 );
-
-			return this;
-
-		};
+		this.applyMatrix( _m1 );
 
-	}(),
+		return this;
 
-	lookAt: function () {
+	},
 
-		var obj = new Object3D();
+	lookAt: function ( vector ) {
 
-		return function lookAt( vector ) {
+		if ( _obj === undefined ) _obj = new Object3D();
 
-			obj.lookAt( vector );
+		_obj.lookAt( vector );
 
-			obj.updateMatrix();
+		_obj.updateMatrix();
 
-			this.applyMatrix( obj.matrix );
+		this.applyMatrix( _obj.matrix );
 
-		};
+		return this;
 
-	}(),
+	},
 
 	center: function () {
 
-		var offset = new Vector3();
+		if ( _offset === undefined ) _offset = new Vector3();
 
-		return function center() {
+		this.computeBoundingBox();
 
-			this.computeBoundingBox();
-
-			this.boundingBox.getCenter( offset ).negate();
+		this.boundingBox.getCenter( _offset ).negate();
 
-			this.translate( offset.x, offset.y, offset.z );
-
-			return this;
+		this.translate( _offset.x, _offset.y, _offset.z );
 
-		};
+		return this;
 
-	}(),
+	},
 
 	setFromObject: function ( object ) {
 
@@ -601,144 +578,144 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
 	computeBoundingBox: function () {
 
-		var box = new Box3();
+		if ( _box === undefined ) {
 
-		return function computeBoundingBox() {
+			_box = new Box3();
 
-			if ( this.boundingBox === null ) {
+		}
 
-				this.boundingBox = new Box3();
+		if ( this.boundingBox === null ) {
 
-			}
+			this.boundingBox = new Box3();
 
-			var position = this.attributes.position;
-			var morphAttributesPosition = this.morphAttributes.position;
+		}
 
-			if ( position !== undefined ) {
+		var position = this.attributes.position;
+		var morphAttributesPosition = this.morphAttributes.position;
 
-				this.boundingBox.setFromBufferAttribute( position );
+		if ( position !== undefined ) {
 
-				// process morph attributes if present
+			this.boundingBox.setFromBufferAttribute( position );
 
-				if ( morphAttributesPosition ) {
+			// process morph attributes if present
 
-					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
+			if ( morphAttributesPosition ) {
 
-						var morphAttribute = morphAttributesPosition[ i ];
-						box.setFromBufferAttribute( morphAttribute );
+				for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
 
-						this.boundingBox.expandByPoint( box.min );
-						this.boundingBox.expandByPoint( box.max );
+					var morphAttribute = morphAttributesPosition[ i ];
+					_box.setFromBufferAttribute( morphAttribute );
 
-					}
+					this.boundingBox.expandByPoint( _box.min );
+					this.boundingBox.expandByPoint( _box.max );
 
 				}
 
-			} else {
+			}
 
-				this.boundingBox.makeEmpty();
+		} else {
 
-			}
+			this.boundingBox.makeEmpty();
 
-			if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
+		}
 
-				console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
+		if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
 
-			}
+			console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
 
-		};
+		}
 
-	}(),
+	},
 
 	computeBoundingSphere: function () {
 
-		var box = new Box3();
-		var boxMorphTargets = new Box3();
-		var vector = new Vector3();
+		if ( _boxMorphTargets === undefined ) {
 
-		return function computeBoundingSphere() {
+			_box = new Box3();
+			_vector = new Vector3();
+			_boxMorphTargets = new Box3();
 
-			if ( this.boundingSphere === null ) {
+		}
 
-				this.boundingSphere = new Sphere();
+		if ( this.boundingSphere === null ) {
 
-			}
+			this.boundingSphere = new Sphere();
 
-			var position = this.attributes.position;
-			var morphAttributesPosition = this.morphAttributes.position;
+		}
 
-			if ( position ) {
+		var position = this.attributes.position;
+		var morphAttributesPosition = this.morphAttributes.position;
 
-				// first, find the center of the bounding sphere
+		if ( position ) {
 
-				var center = this.boundingSphere.center;
+			// first, find the center of the bounding sphere
 
-				box.setFromBufferAttribute( position );
+			var center = this.boundingSphere.center;
 
-				// process morph attributes if present
+			_box.setFromBufferAttribute( position );
 
-				if ( morphAttributesPosition ) {
+			// process morph attributes if present
 
-					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
+			if ( morphAttributesPosition ) {
 
-						var morphAttribute = morphAttributesPosition[ i ];
-						boxMorphTargets.setFromBufferAttribute( morphAttribute );
+				for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
 
-						box.expandByPoint( boxMorphTargets.min );
-						box.expandByPoint( boxMorphTargets.max );
+					var morphAttribute = morphAttributesPosition[ i ];
+					_boxMorphTargets.setFromBufferAttribute( morphAttribute );
 
-					}
+					_box.expandByPoint( _boxMorphTargets.min );
+					_box.expandByPoint( _boxMorphTargets.max );
 
 				}
 
-				box.getCenter( center );
+			}
 
-				// second, try to find a boundingSphere with a radius smaller than the
-				// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
+			_box.getCenter( center );
 
-				var maxRadiusSq = 0;
+			// second, try to find a boundingSphere with a radius smaller than the
+			// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
 
-				for ( var i = 0, il = position.count; i < il; i ++ ) {
+			var maxRadiusSq = 0;
 
-					vector.fromBufferAttribute( position, i );
+			for ( var i = 0, il = position.count; i < il; i ++ ) {
 
-					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+				_vector.fromBufferAttribute( position, i );
 
-				}
+				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
 
-				// process morph attributes if present
+			}
 
-				if ( morphAttributesPosition ) {
+			// process morph attributes if present
 
-					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
+			if ( morphAttributesPosition ) {
 
-						var morphAttribute = morphAttributesPosition[ i ];
+				for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
 
-						for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) {
+					var morphAttribute = morphAttributesPosition[ i ];
 
-							vector.fromBufferAttribute( morphAttribute, j );
+					for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) {
 
-							maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+						_vector.fromBufferAttribute( morphAttribute, j );
 
-						}
+						maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
 
 					}
 
 				}
 
-				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
+			}
 
-				if ( isNaN( this.boundingSphere.radius ) ) {
+			this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
 
-					console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
+			if ( isNaN( this.boundingSphere.radius ) ) {
 
-				}
+				console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
 
 			}
 
-		};
+		}
 
-	}(),
+	},
 
 	computeFaceNormals: function () {
 
@@ -900,27 +877,23 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
 	normalizeNormals: function () {
 
-		var vector = new Vector3();
+		if ( _vector === undefined ) _vector = new Vector3();
 
-		return function normalizeNormals() {
+		var normals = this.attributes.normal;
 
-			var normals = this.attributes.normal;
+		for ( var i = 0, il = normals.count; i < il; i ++ ) {
 
-			for ( var i = 0, il = normals.count; i < il; i ++ ) {
+			_vector.x = normals.getX( i );
+			_vector.y = normals.getY( i );
+			_vector.z = normals.getZ( i );
 
-				vector.x = normals.getX( i );
-				vector.y = normals.getY( i );
-				vector.z = normals.getZ( i );
+			_vector.normalize();
 
-				vector.normalize();
+			normals.setXYZ( i, _vector.x, _vector.y, _vector.z );
 
-				normals.setXYZ( i, vector.x, vector.y, vector.z );
-
-			}
-
-		};
+		}
 
-	}(),
+	},
 
 	toNonIndexed: function () {
 

+ 46 - 71
src/core/Geometry.js

@@ -19,11 +19,12 @@ import { _Math } from '../math/Math.js';
  * @author bhouston / http://clara.io
  */
 
-var geometryId = 0; // Geometry uses even numbers as Id
+var _geometryId = 0; // Geometry uses even numbers as Id
+var _m1, _obj, _offset;
 
 function Geometry() {
 
-	Object.defineProperty( this, 'id', { value: geometryId += 2 } );
+	Object.defineProperty( this, 'id', { value: _geometryId += 2 } );
 
 	this.uuid = _Math.generateUUID();
 
@@ -107,111 +108,89 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	},
 
-	rotateX: function () {
+	rotateX: function ( angle ) {
 
 		// rotate geometry around world x-axis
 
-		var m1 = new Matrix4();
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-		return function rotateX( angle ) {
+		_m1.makeRotationX( angle );
 
-			m1.makeRotationX( angle );
+		this.applyMatrix( _m1 );
 
-			this.applyMatrix( m1 );
-
-			return this;
-
-		};
+		return this;
 
-	}(),
+	},
 
-	rotateY: function () {
+	rotateY: function ( angle ) {
 
 		// rotate geometry around world y-axis
 
-		var m1 = new Matrix4();
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-		return function rotateY( angle ) {
+		_m1.makeRotationY( angle );
 
-			m1.makeRotationY( angle );
+		this.applyMatrix( _m1 );
 
-			this.applyMatrix( m1 );
-
-			return this;
-
-		};
+		return this;
 
-	}(),
+	},
 
-	rotateZ: function () {
+	rotateZ: function ( angle ) {
 
 		// rotate geometry around world z-axis
 
-		var m1 = new Matrix4();
-
-		return function rotateZ( angle ) {
-
-			m1.makeRotationZ( angle );
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-			this.applyMatrix( m1 );
+		_m1.makeRotationZ( angle );
 
-			return this;
+		this.applyMatrix( _m1 );
 
-		};
+		return this;
 
-	}(),
+	},
 
-	translate: function () {
+	translate: function ( x, y, z ) {
 
 		// translate geometry
 
-		var m1 = new Matrix4();
-
-		return function translate( x, y, z ) {
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-			m1.makeTranslation( x, y, z );
+		_m1.makeTranslation( x, y, z );
 
-			this.applyMatrix( m1 );
+		this.applyMatrix( _m1 );
 
-			return this;
-
-		};
+		return this;
 
-	}(),
+	},
 
-	scale: function () {
+	scale: function ( x, y, z ) {
 
 		// scale geometry
 
-		var m1 = new Matrix4();
-
-		return function scale( x, y, z ) {
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-			m1.makeScale( x, y, z );
+		_m1.makeScale( x, y, z );
 
-			this.applyMatrix( m1 );
+		this.applyMatrix( _m1 );
 
-			return this;
-
-		};
-
-	}(),
+		return this;
 
-	lookAt: function () {
+	},
 
-		var obj = new Object3D();
+	lookAt: function ( vector ) {
 
-		return function lookAt( vector ) {
+		if ( _obj === undefined ) _obj = new Object3D();
 
-			obj.lookAt( vector );
+		_obj.lookAt( vector );
 
-			obj.updateMatrix();
+		_obj.updateMatrix();
 
-			this.applyMatrix( obj.matrix );
+		this.applyMatrix( _obj.matrix );
 
-		};
+		return this;
 
-	}(),
+	},
 
 	fromBufferGeometry: function ( geometry ) {
 
@@ -348,21 +327,17 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	center: function () {
 
-		var offset = new Vector3();
-
-		return function center() {
-
-			this.computeBoundingBox();
+		if ( _offset === undefined ) _offset = new Vector3();
 
-			this.boundingBox.getCenter( offset ).negate();
+		this.computeBoundingBox();
 
-			this.translate( offset.x, offset.y, offset.z );
+		this.boundingBox.getCenter( _offset ).negate();
 
-			return this;
+		this.translate( _offset.x, _offset.y, _offset.z );
 
-		};
+		return this;
 
-	}(),
+	},
 
 	normalize: function () {
 

+ 121 - 160
src/core/Object3D.js

@@ -16,11 +16,16 @@ import { TrianglesDrawMode } from '../constants.js';
  * @author elephantatwork / www.elephantatwork.ch
  */
 
-var object3DId = 0;
+var _object3DId = 0;
+var _m1, _q1, _v1;
+var _xAxis, _yAxis, _zAxis;
+var _target, _position, _scale, _quaternion;
+var _addedEvent = { type: 'added' };
+var _removedEvent = { type: 'removed' };
 
 function Object3D() {
 
-	Object.defineProperty( this, 'id', { value: object3DId ++ } );
+	Object.defineProperty( this, 'id', { value: _object3DId ++ } );
 
 	this.uuid = _Math.generateUUID();
 
@@ -160,135 +165,99 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	},
 
-	rotateOnAxis: function () {
+	rotateOnAxis: function ( axis, angle ) {
 
 		// rotate object on axis in object space
 		// axis is assumed to be normalized
 
-		var q1 = new Quaternion();
+		if ( _q1 === undefined ) _q1 = new Quaternion();
 
-		return function rotateOnAxis( axis, angle ) {
+		_q1.setFromAxisAngle( axis, angle );
 
-			q1.setFromAxisAngle( axis, angle );
+		this.quaternion.multiply( _q1 );
 
-			this.quaternion.multiply( q1 );
-
-			return this;
-
-		};
+		return this;
 
-	}(),
+	},
 
-	rotateOnWorldAxis: function () {
+	rotateOnWorldAxis: function ( axis, angle ) {
 
 		// 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 () {
-
-		var v1 = new Vector3( 1, 0, 0 );
+		if ( _q1 === undefined ) _q1 = new Quaternion();
 
-		return function rotateX( angle ) {
+		_q1.setFromAxisAngle( axis, angle );
 
-			return this.rotateOnAxis( v1, angle );
+		this.quaternion.premultiply( _q1 );
 
-		};
+		return this;
 
-	}(),
+	},
 
-	rotateY: function () {
+	rotateX: function ( angle ) {
 
-		var v1 = new Vector3( 0, 1, 0 );
+		if ( _xAxis === undefined ) _xAxis = new Vector3( 1, 0, 0 );
 
-		return function rotateY( angle ) {
+		return this.rotateOnAxis( _xAxis, angle );
 
-			return this.rotateOnAxis( v1, angle );
+	},
 
-		};
+	rotateY: function ( angle ) {
 
-	}(),
+		if ( _yAxis === undefined ) _yAxis = new Vector3( 0, 1, 0 );
 
-	rotateZ: function () {
+		return this.rotateOnAxis( _yAxis, angle );
 
-		var v1 = new Vector3( 0, 0, 1 );
+	},
 
-		return function rotateZ( angle ) {
+	rotateZ: function ( angle ) {
 
-			return this.rotateOnAxis( v1, angle );
+		if ( _zAxis === undefined ) _zAxis = new Vector3( 0, 0, 1 );
 
-		};
+		return this.rotateOnAxis( _zAxis, angle );
 
-	}(),
+	},
 
-	translateOnAxis: function () {
+	translateOnAxis: function ( axis, distance ) {
 
 		// translate object by distance along axis in object space
 		// axis is assumed to be normalized
 
-		var v1 = new Vector3();
-
-		return function translateOnAxis( axis, distance ) {
-
-			v1.copy( axis ).applyQuaternion( this.quaternion );
-
-			this.position.add( v1.multiplyScalar( distance ) );
-
-			return this;
-
-		};
-
-	}(),
-
-	translateX: function () {
+		if ( _v1 === undefined ) _v1 = new Vector3();
 
-		var v1 = new Vector3( 1, 0, 0 );
+		_v1.copy( axis ).applyQuaternion( this.quaternion );
 
-		return function translateX( distance ) {
+		this.position.add( _v1.multiplyScalar( distance ) );
 
-			return this.translateOnAxis( v1, distance );
-
-		};
+		return this;
 
-	}(),
+	},
 
-	translateY: function () {
+	translateX: function ( distance ) {
 
-		var v1 = new Vector3( 0, 1, 0 );
+		if ( _xAxis === undefined ) _xAxis = new Vector3( 1, 0, 0 );
 
-		return function translateY( distance ) {
+		return this.translateOnAxis( _xAxis, distance );
 
-			return this.translateOnAxis( v1, distance );
+	},
 
-		};
+	translateY: function ( distance ) {
 
-	}(),
+		if ( _yAxis === undefined ) _yAxis = new Vector3( 0, 1, 0 );
 
-	translateZ: function () {
+		return this.translateOnAxis( _yAxis, distance );
 
-		var v1 = new Vector3( 0, 0, 1 );
+	},
 
-		return function translateZ( distance ) {
+	translateZ: function ( distance ) {
 
-			return this.translateOnAxis( v1, distance );
+		if ( _zAxis === undefined ) _zAxis = new Vector3( 0, 0, 1 );
 
-		};
+		return this.translateOnAxis( _zAxis, distance );
 
-	}(),
+	},
 
 	localToWorld: function ( vector ) {
 
@@ -296,68 +265,64 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	},
 
-	worldToLocal: function () {
-
-		var m1 = new Matrix4();
-
-		return function worldToLocal( vector ) {
+	worldToLocal: function ( vector ) {
 
-			return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-		};
+		return vector.applyMatrix4( _m1.getInverse( this.matrixWorld ) );
 
-	}(),
+	},
 
-	lookAt: function () {
+	lookAt: function ( x, y, z ) {
 
 		// This method does not support objects having non-uniformly-scaled parent(s)
 
-		var q1 = new Quaternion();
-		var m1 = new Matrix4();
-		var target = new Vector3();
-		var position = new Vector3();
+		if ( _position === undefined ) {
 
-		return function lookAt( x, y, z ) {
+			_q1 = new Quaternion();
+			_m1 = new Matrix4();
+			_target = new Vector3();
+			_position = new Vector3();
 
-			if ( x.isVector3 ) {
+		}
 
-				target.copy( x );
+		if ( x.isVector3 ) {
 
-			} else {
+			_target.copy( x );
 
-				target.set( x, y, z );
+		} else {
 
-			}
+			_target.set( x, y, z );
 
-			var parent = this.parent;
+		}
 
-			this.updateWorldMatrix( true, false );
+		var parent = this.parent;
 
-			position.setFromMatrixPosition( this.matrixWorld );
+		this.updateWorldMatrix( true, false );
 
-			if ( this.isCamera || this.isLight ) {
+		_position.setFromMatrixPosition( this.matrixWorld );
 
-				m1.lookAt( position, target, this.up );
+		if ( this.isCamera || this.isLight ) {
 
-			} else {
+			_m1.lookAt( _position, _target, this.up );
 
-				m1.lookAt( target, position, this.up );
+		} else {
 
-			}
+			_m1.lookAt( _target, _position, this.up );
 
-			this.quaternion.setFromRotationMatrix( m1 );
+		}
 
-			if ( parent ) {
+		this.quaternion.setFromRotationMatrix( _m1 );
 
-				m1.extractRotation( parent.matrixWorld );
-				q1.setFromRotationMatrix( m1 );
-				this.quaternion.premultiply( q1.inverse() );
+		if ( parent ) {
 
-			}
+			_m1.extractRotation( parent.matrixWorld );
+			_q1.setFromRotationMatrix( _m1 );
+			this.quaternion.premultiply( _q1.inverse() );
 
-		};
+		}
 
-	}(),
+	},
 
 	add: function ( object ) {
 
@@ -391,7 +356,7 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 			object.parent = this;
 			this.children.push( object );
 
-			object.dispatchEvent( { type: 'added' } );
+			object.dispatchEvent( _addedEvent );
 
 		} else {
 
@@ -424,7 +389,7 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 			object.parent = null;
 			this.children.splice( index, 1 );
 
-			object.dispatchEvent( { type: 'removed' } );
+			object.dispatchEvent( _removedEvent );
 
 		}
 
@@ -432,37 +397,33 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	},
 
-	attach: function () {
+	attach: function ( object ) {
 
 		// adds object as a child of this, while maintaining the object's world transform
 
-		var m = new Matrix4();
+		if ( _m1 === undefined ) _m1 = new Matrix4();
 
-		return function attach( object ) {
+		this.updateWorldMatrix( true, false );
 
-			this.updateWorldMatrix( true, false );
+		_m1.getInverse( this.matrixWorld );
 
-			m.getInverse( this.matrixWorld );
+		if ( object.parent !== null ) {
 
-			if ( object.parent !== null ) {
-
-				object.parent.updateWorldMatrix( true, false );
+			object.parent.updateWorldMatrix( true, false );
 
-				m.multiply( object.parent.matrixWorld );
-
-			}
+			_m1.multiply( object.parent.matrixWorld );
 
-			object.applyMatrix( m );
+		}
 
-			object.updateWorldMatrix( false, false );
+		object.applyMatrix( _m1 );
 
-			this.add( object );
+		object.updateWorldMatrix( false, false );
 
-			return this;
+		this.add( object );
 
-		};
+		return this;
 
-	}(),
+	},
 
 	getObjectById: function ( id ) {
 
@@ -512,53 +473,53 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 	},
 
-	getWorldQuaternion: function () {
+	getWorldQuaternion: function ( target ) {
 
-		var position = new Vector3();
-		var scale = new Vector3();
+		if ( _scale === undefined ) {
 
-		return function getWorldQuaternion( target ) {
+			_position = new Vector3();
+			_scale = new Vector3();
 
-			if ( target === undefined ) {
+		}
 
-				console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
-				target = new Quaternion();
+		if ( target === undefined ) {
 
-			}
+			console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
+			target = new Quaternion();
 
-			this.updateMatrixWorld( true );
+		}
 
-			this.matrixWorld.decompose( position, target, scale );
+		this.updateMatrixWorld( true );
 
-			return target;
+		this.matrixWorld.decompose( _position, target, _scale );
 
-		};
+		return target;
 
-	}(),
+	},
 
-	getWorldScale: function () {
+	getWorldScale: function ( target ) {
 
-		var position = new Vector3();
-		var quaternion = new Quaternion();
+		if ( _quaternion === undefined ) {
 
-		return function getWorldScale( target ) {
+			_position = new Vector3();
+			_quaternion = new Quaternion();
 
-			if ( target === undefined ) {
+		}
 
-				console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
-				target = new Vector3();
+		if ( target === undefined ) {
 
-			}
+			console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
+			target = new Vector3();
 
-			this.updateMatrixWorld( true );
+		}
 
-			this.matrixWorld.decompose( position, quaternion, target );
+		this.updateMatrixWorld( true );
 
-			return target;
+		this.matrixWorld.decompose( _position, _quaternion, target );
 
-		};
+		return target;
 
-	}(),
+	},
 
 	getWorldDirection: function ( target ) {
 

+ 215 - 213
src/loaders/Loader.js

@@ -24,6 +24,8 @@ import { Color } from '../math/Color.js';
  * @author alteredq / http://alteredqualia.com/
  */
 
+var _BlendingMode, _color, _textureLoader, _materialLoader;
+
 function Loader() {}
 
 Loader.Handlers = {
@@ -83,260 +85,260 @@ Object.assign( Loader.prototype, {
 
 	},
 
-	createMaterial: ( function () {
+	createMaterial: function ( m, texturePath, crossOrigin ) {
 
-		var BlendingMode = {
-			NoBlending: NoBlending,
-			NormalBlending: NormalBlending,
-			AdditiveBlending: AdditiveBlending,
-			SubtractiveBlending: SubtractiveBlending,
-			MultiplyBlending: MultiplyBlending,
-			CustomBlending: CustomBlending
-		};
+		if ( _materialLoader === undefined ) {
 
-		var color = new Color();
-		var textureLoader = new TextureLoader();
-		var materialLoader = new MaterialLoader();
+			_BlendingMode = {
+				NoBlending: NoBlending,
+				NormalBlending: NormalBlending,
+				AdditiveBlending: AdditiveBlending,
+				SubtractiveBlending: SubtractiveBlending,
+				MultiplyBlending: MultiplyBlending,
+				CustomBlending: CustomBlending
+			};
 
-		return function createMaterial( m, texturePath, crossOrigin ) {
+			_color = new Color();
+			_textureLoader = new TextureLoader();
+			_materialLoader = new MaterialLoader();
+
+		}
 
-			// convert from old material format
+		// convert from old material format
 
-			var textures = {};
+		var textures = {};
 
-			function loadTexture( path, repeat, offset, wrap, anisotropy ) {
+		//
 
-				var fullPath = texturePath + path;
-				var loader = Loader.Handlers.get( fullPath );
+		var json = {
+			uuid: _Math.generateUUID(),
+			type: 'MeshLambertMaterial'
+		};
 
-				var texture;
+		for ( var name in m ) {
+
+			var value = m[ name ];
+
+			switch ( name ) {
+
+				case 'DbgColor':
+				case 'DbgIndex':
+				case 'opticalDensity':
+				case 'illumination':
+					break;
+				case 'DbgName':
+					json.name = value;
+					break;
+				case 'blending':
+					json.blending = _BlendingMode[ value ];
+					break;
+				case 'colorAmbient':
+				case 'mapAmbient':
+					console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );
+					break;
+				case 'colorDiffuse':
+					json.color = _color.fromArray( value ).getHex();
+					break;
+				case 'colorSpecular':
+					json.specular = _color.fromArray( value ).getHex();
+					break;
+				case 'colorEmissive':
+					json.emissive = _color.fromArray( value ).getHex();
+					break;
+				case 'specularCoef':
+					json.shininess = value;
+					break;
+				case 'shading':
+					if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';
+					if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';
+					if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';
+					break;
+				case 'mapDiffuse':
+					json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapDiffuseRepeat':
+				case 'mapDiffuseOffset':
+				case 'mapDiffuseWrap':
+				case 'mapDiffuseAnisotropy':
+					break;
+				case 'mapEmissive':
+					json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapEmissiveRepeat':
+				case 'mapEmissiveOffset':
+				case 'mapEmissiveWrap':
+				case 'mapEmissiveAnisotropy':
+					break;
+				case 'mapLight':
+					json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapLightRepeat':
+				case 'mapLightOffset':
+				case 'mapLightWrap':
+				case 'mapLightAnisotropy':
+					break;
+				case 'mapAO':
+					json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapAORepeat':
+				case 'mapAOOffset':
+				case 'mapAOWrap':
+				case 'mapAOAnisotropy':
+					break;
+				case 'mapBump':
+					json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapBumpScale':
+					json.bumpScale = value;
+					break;
+				case 'mapBumpRepeat':
+				case 'mapBumpOffset':
+				case 'mapBumpWrap':
+				case 'mapBumpAnisotropy':
+					break;
+				case 'mapNormal':
+					json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapNormalFactor':
+					json.normalScale = value;
+					break;
+				case 'mapNormalRepeat':
+				case 'mapNormalOffset':
+				case 'mapNormalWrap':
+				case 'mapNormalAnisotropy':
+					break;
+				case 'mapSpecular':
+					json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapSpecularRepeat':
+				case 'mapSpecularOffset':
+				case 'mapSpecularWrap':
+				case 'mapSpecularAnisotropy':
+					break;
+				case 'mapMetalness':
+					json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapMetalnessRepeat':
+				case 'mapMetalnessOffset':
+				case 'mapMetalnessWrap':
+				case 'mapMetalnessAnisotropy':
+					break;
+				case 'mapRoughness':
+					json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapRoughnessRepeat':
+				case 'mapRoughnessOffset':
+				case 'mapRoughnessWrap':
+				case 'mapRoughnessAnisotropy':
+					break;
+				case 'mapAlpha':
+					json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy, textures, texturePath, crossOrigin );
+					break;
+				case 'mapAlphaRepeat':
+				case 'mapAlphaOffset':
+				case 'mapAlphaWrap':
+				case 'mapAlphaAnisotropy':
+					break;
+				case 'flipSided':
+					json.side = BackSide;
+					break;
+				case 'doubleSided':
+					json.side = DoubleSide;
+					break;
+				case 'transparency':
+					console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );
+					json.opacity = value;
+					break;
+				case 'depthTest':
+				case 'depthWrite':
+				case 'colorWrite':
+				case 'opacity':
+				case 'reflectivity':
+				case 'transparent':
+				case 'visible':
+				case 'wireframe':
+					json[ name ] = value;
+					break;
+				case 'vertexColors':
+					if ( value === true ) json.vertexColors = VertexColors;
+					if ( value === 'face' ) json.vertexColors = FaceColors;
+					break;
+				default:
+					console.error( 'THREE.Loader.createMaterial: Unsupported', name, value );
+					break;
 
-				if ( loader !== null ) {
+			}
 
-					texture = loader.load( fullPath );
+		}
 
-				} else {
+		if ( json.type === 'MeshBasicMaterial' ) delete json.emissive;
+		if ( json.type !== 'MeshPhongMaterial' ) delete json.specular;
 
-					textureLoader.setCrossOrigin( crossOrigin );
-					texture = textureLoader.load( fullPath );
+		if ( json.opacity < 1 ) json.transparent = true;
 
-				}
+		_materialLoader.setTextures( textures );
 
-				if ( repeat !== undefined ) {
+		return _materialLoader.parse( json );
 
-					texture.repeat.fromArray( repeat );
+	}
 
-					if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;
-					if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;
+} );
 
-				}
+function loadTexture( path, repeat, offset, wrap, anisotropy, textures, texturePath, crossOrigin ) {
 
-				if ( offset !== undefined ) {
+	var fullPath = texturePath + path;
+	var loader = Loader.Handlers.get( fullPath );
 
-					texture.offset.fromArray( offset );
+	var texture;
 
-				}
+	if ( loader !== null ) {
 
-				if ( wrap !== undefined ) {
+		texture = loader.load( fullPath );
 
-					if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;
-					if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;
+	} else {
 
-					if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;
-					if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;
+		_textureLoader.setCrossOrigin( crossOrigin );
+		texture = _textureLoader.load( fullPath );
 
-				}
+	}
 
-				if ( anisotropy !== undefined ) {
+	if ( repeat !== undefined ) {
 
-					texture.anisotropy = anisotropy;
+		texture.repeat.fromArray( repeat );
 
-				}
+		if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;
+		if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;
 
-				var uuid = _Math.generateUUID();
+	}
 
-				textures[ uuid ] = texture;
+	if ( offset !== undefined ) {
 
-				return uuid;
+		texture.offset.fromArray( offset );
 
-			}
+	}
 
-			//
+	if ( wrap !== undefined ) {
 
-			var json = {
-				uuid: _Math.generateUUID(),
-				type: 'MeshLambertMaterial'
-			};
+		if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;
+		if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;
 
-			for ( var name in m ) {
-
-				var value = m[ name ];
-
-				switch ( name ) {
-
-					case 'DbgColor':
-					case 'DbgIndex':
-					case 'opticalDensity':
-					case 'illumination':
-						break;
-					case 'DbgName':
-						json.name = value;
-						break;
-					case 'blending':
-						json.blending = BlendingMode[ value ];
-						break;
-					case 'colorAmbient':
-					case 'mapAmbient':
-						console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );
-						break;
-					case 'colorDiffuse':
-						json.color = color.fromArray( value ).getHex();
-						break;
-					case 'colorSpecular':
-						json.specular = color.fromArray( value ).getHex();
-						break;
-					case 'colorEmissive':
-						json.emissive = color.fromArray( value ).getHex();
-						break;
-					case 'specularCoef':
-						json.shininess = value;
-						break;
-					case 'shading':
-						if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';
-						if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';
-						if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';
-						break;
-					case 'mapDiffuse':
-						json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
-						break;
-					case 'mapDiffuseRepeat':
-					case 'mapDiffuseOffset':
-					case 'mapDiffuseWrap':
-					case 'mapDiffuseAnisotropy':
-						break;
-					case 'mapEmissive':
-						json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );
-						break;
-					case 'mapEmissiveRepeat':
-					case 'mapEmissiveOffset':
-					case 'mapEmissiveWrap':
-					case 'mapEmissiveAnisotropy':
-						break;
-					case 'mapLight':
-						json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
-						break;
-					case 'mapLightRepeat':
-					case 'mapLightOffset':
-					case 'mapLightWrap':
-					case 'mapLightAnisotropy':
-						break;
-					case 'mapAO':
-						json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );
-						break;
-					case 'mapAORepeat':
-					case 'mapAOOffset':
-					case 'mapAOWrap':
-					case 'mapAOAnisotropy':
-						break;
-					case 'mapBump':
-						json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
-						break;
-					case 'mapBumpScale':
-						json.bumpScale = value;
-						break;
-					case 'mapBumpRepeat':
-					case 'mapBumpOffset':
-					case 'mapBumpWrap':
-					case 'mapBumpAnisotropy':
-						break;
-					case 'mapNormal':
-						json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
-						break;
-					case 'mapNormalFactor':
-						json.normalScale = value;
-						break;
-					case 'mapNormalRepeat':
-					case 'mapNormalOffset':
-					case 'mapNormalWrap':
-					case 'mapNormalAnisotropy':
-						break;
-					case 'mapSpecular':
-						json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
-						break;
-					case 'mapSpecularRepeat':
-					case 'mapSpecularOffset':
-					case 'mapSpecularWrap':
-					case 'mapSpecularAnisotropy':
-						break;
-					case 'mapMetalness':
-						json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );
-						break;
-					case 'mapMetalnessRepeat':
-					case 'mapMetalnessOffset':
-					case 'mapMetalnessWrap':
-					case 'mapMetalnessAnisotropy':
-						break;
-					case 'mapRoughness':
-						json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );
-						break;
-					case 'mapRoughnessRepeat':
-					case 'mapRoughnessOffset':
-					case 'mapRoughnessWrap':
-					case 'mapRoughnessAnisotropy':
-						break;
-					case 'mapAlpha':
-						json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );
-						break;
-					case 'mapAlphaRepeat':
-					case 'mapAlphaOffset':
-					case 'mapAlphaWrap':
-					case 'mapAlphaAnisotropy':
-						break;
-					case 'flipSided':
-						json.side = BackSide;
-						break;
-					case 'doubleSided':
-						json.side = DoubleSide;
-						break;
-					case 'transparency':
-						console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );
-						json.opacity = value;
-						break;
-					case 'depthTest':
-					case 'depthWrite':
-					case 'colorWrite':
-					case 'opacity':
-					case 'reflectivity':
-					case 'transparent':
-					case 'visible':
-					case 'wireframe':
-						json[ name ] = value;
-						break;
-					case 'vertexColors':
-						if ( value === true ) json.vertexColors = VertexColors;
-						if ( value === 'face' ) json.vertexColors = FaceColors;
-						break;
-					default:
-						console.error( 'THREE.Loader.createMaterial: Unsupported', name, value );
-						break;
-
-				}
+		if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;
+		if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;
 
-			}
+	}
 
-			if ( json.type === 'MeshBasicMaterial' ) delete json.emissive;
-			if ( json.type !== 'MeshPhongMaterial' ) delete json.specular;
+	if ( anisotropy !== undefined ) {
 
-			if ( json.opacity < 1 ) json.transparent = true;
+		texture.anisotropy = anisotropy;
 
-			materialLoader.setTextures( textures );
+	}
 
-			return materialLoader.parse( json );
+	var uuid = _Math.generateUUID();
 
-		};
+	textures[ uuid ] = texture;
 
-	} )()
+	return uuid;
 
-} );
+}
 
 export { Loader };

+ 3 - 0
src/loaders/MaterialLoader.js

@@ -229,6 +229,9 @@ Object.assign( MaterialLoader.prototype, {
 
 		if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );
 
+		if ( json.clearCoatNormalMap !== undefined ) material.clearCoatNormalMap = getTexture( json.clearCoatNormalMap );
+		if ( json.clearCoatNormalScale !== undefined ) material.clearCoatNormalScale = new Vector2().fromArray( json.clearCoatNormalScale );
+
 		return material;
 
 	},

+ 7 - 0
src/materials/Material.js

@@ -175,6 +175,13 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 		if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;
 		if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;
 
+		if ( this.clearCoatNormalMap && this.clearCoatNormalMap.isTexture ) {
+
+			data.clearCoatNormalMap = this.clearCoatNormalMap.toJSON( meta ).uuid;
+			data.clearCoatNormalScale = this.clearCoatNormalScale.toArray();
+
+		}
+
 		if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
 		if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid;
 		if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;

+ 37 - 37
src/objects/Points.js

@@ -10,7 +10,7 @@ import { BufferGeometry } from '../core/BufferGeometry.js';
  * @author alteredq / http://alteredqualia.com/
  */
 
-var _inverseMatrix, _ray, _sphere;
+var _inverseMatrix, _ray, _sphere, _position;
 
 function Points( geometry, material ) {
 
@@ -38,10 +38,10 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 			_inverseMatrix = new Matrix4();
 			_ray = new Ray();
 			_sphere = new Sphere();
+			_position = new Vector3();
 
 		}
 
-		var object = this;
 		var geometry = this.geometry;
 		var matrixWorld = this.matrixWorld;
 		var threshold = raycaster.params.Points.threshold;
@@ -63,36 +63,6 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
 		var localThresholdSq = localThreshold * localThreshold;
-		var position = new Vector3();
-		var intersectPoint = new Vector3();
-
-		function testPoint( point, index ) {
-
-			var rayPointDistanceSq = _ray.distanceSqToPoint( point );
-
-			if ( rayPointDistanceSq < localThresholdSq ) {
-
-				_ray.closestPointToPoint( point, intersectPoint );
-				intersectPoint.applyMatrix4( matrixWorld );
-
-				var distance = raycaster.ray.origin.distanceTo( intersectPoint );
-
-				if ( distance < raycaster.near || distance > raycaster.far ) return;
-
-				intersects.push( {
-
-					distance: distance,
-					distanceToRay: Math.sqrt( rayPointDistanceSq ),
-					point: intersectPoint.clone(),
-					index: index,
-					face: null,
-					object: object
-
-				} );
-
-			}
-
-		}
 
 		if ( geometry.isBufferGeometry ) {
 
@@ -108,9 +78,9 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 					var a = indices[ i ];
 
-					position.fromArray( positions, a * 3 );
+					_position.fromArray( positions, a * 3 );
 
-					testPoint( position, a );
+					testPoint( _position, a, localThresholdSq, matrixWorld, raycaster, intersects, this );
 
 				}
 
@@ -118,9 +88,9 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 				for ( var i = 0, l = positions.length / 3; i < l; i ++ ) {
 
-					position.fromArray( positions, i * 3 );
+					_position.fromArray( positions, i * 3 );
 
-					testPoint( position, i );
+					testPoint( _position, i, localThresholdSq, matrixWorld, raycaster, intersects, this );
 
 				}
 
@@ -132,7 +102,7 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 			for ( var i = 0, l = vertices.length; i < l; i ++ ) {
 
-				testPoint( vertices[ i ], i );
+				testPoint( vertices[ i ], i, localThresholdSq, matrixWorld, raycaster, intersects, this );
 
 			}
 
@@ -194,4 +164,34 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 } );
 
+function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
+
+	var rayPointDistanceSq = _ray.distanceSqToPoint( point );
+
+	if ( rayPointDistanceSq < localThresholdSq ) {
+
+		var intersectPoint = new Vector3();
+
+		_ray.closestPointToPoint( point, intersectPoint );
+		intersectPoint.applyMatrix4( matrixWorld );
+
+		var distance = raycaster.ray.origin.distanceTo( intersectPoint );
+
+		if ( distance < raycaster.near || distance > raycaster.far ) return;
+
+		intersects.push( {
+
+			distance: distance,
+			distanceToRay: Math.sqrt( rayPointDistanceSq ),
+			point: intersectPoint,
+			index: index,
+			face: null,
+			object: object
+
+		} );
+
+	}
+
+}
+
 export { Points };

+ 15 - 19
src/polyfills.js

@@ -55,33 +55,29 @@ if ( Object.assign === undefined ) {
 	// Missing in IE
 	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
 
-	( function () {
+	Object.assign = function ( target ) {
 
-		Object.assign = function ( target ) {
+		'use strict';
 
-			'use strict';
+		if ( target === undefined || target === null ) {
 
-			if ( target === undefined || target === null ) {
+			throw new TypeError( 'Cannot convert undefined or null to object' );
 
-				throw new TypeError( 'Cannot convert undefined or null to object' );
-
-			}
-
-			var output = Object( target );
+		}
 
-			for ( var index = 1; index < arguments.length; index ++ ) {
+		var output = Object( target );
 
-				var source = arguments[ index ];
+		for ( var index = 1; index < arguments.length; index ++ ) {
 
-				if ( source !== undefined && source !== null ) {
+			var source = arguments[ index ];
 
-					for ( var nextKey in source ) {
+			if ( source !== undefined && source !== null ) {
 
-						if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
+				for ( var nextKey in source ) {
 
-							output[ nextKey ] = source[ nextKey ];
+					if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
 
-						}
+						output[ nextKey ] = source[ nextKey ];
 
 					}
 
@@ -89,10 +85,10 @@ if ( Object.assign === undefined ) {
 
 			}
 
-			return output;
+		}
 
-		};
+		return output;
 
-	} )();
+	};
 
 }

+ 1 - 1
src/renderers/shaders/ShaderChunk/dithering_fragment.glsl.js

@@ -1,5 +1,5 @@
 export default /* glsl */`
-#if defined( DITHERING )
+#ifdef DITHERING
 
 	gl_FragColor.rgb = dithering( gl_FragColor.rgb );
 

+ 1 - 1
src/renderers/shaders/ShaderChunk/dithering_pars_fragment.glsl.js

@@ -1,5 +1,5 @@
 export default /* glsl */`
-#if defined( DITHERING )
+#ifdef DITHERING
 
 	// based on https://www.shadertoy.com/view/MslGR8
 	vec3 dithering( vec3 color ) {

+ 1 - 1
src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js

@@ -25,7 +25,7 @@ export default /* glsl */`
 
 #if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )
 
-  radiance += getLightProbeIndirectRadiance( /*specularLightProbe,*/ geometry.viewDir, geometry.normal, Material_BlinnShininessExponent( material ), maxMipLevel );
+	radiance += getLightProbeIndirectRadiance( /*specularLightProbe,*/ geometry.viewDir, geometry.normal, Material_BlinnShininessExponent( material ), maxMipLevel );
 
 	#ifndef STANDARD
 

+ 1 - 1
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js

@@ -41,7 +41,7 @@ export default /* glsl */`
 		const vec2 offset = vec2( 0.0, 1.0 );
 
 		vec2 texelSize = vec2( 1.0 ) / size;
-		vec2 centroidUV = floor( uv * size + 0.5 ) / size;
+		vec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;
 
 		float lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );
 		float lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );

+ 1 - 1
src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js

@@ -1,5 +1,5 @@
 export default /* glsl */`
-#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
+#ifdef USE_UV
 
 	varying vec2 vUv;
 

+ 1 - 1
src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js

@@ -1,5 +1,5 @@
 export default /* glsl */`
-#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
+#ifdef USE_UV
 
 	varying vec2 vUv;
 	uniform mat3 uvTransform;

+ 1 - 1
src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js

@@ -1,5 +1,5 @@
 export default /* glsl */`
-#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )  || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
+#ifdef USE_UV
 
 	vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
 

+ 3 - 1
src/renderers/webgl/WebGLProgram.js

@@ -400,6 +400,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
 
 			parameters.vertexTangents ? '#define USE_TANGENT' : '',
 			parameters.vertexColors ? '#define USE_COLOR' : '',
+			parameters.vertexUvs ? '#define USE_UV' : '',
 
 			parameters.flatShading ? '#define FLAT_SHADED' : '',
 
@@ -516,6 +517,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
 
 			parameters.vertexTangents ? '#define USE_TANGENT' : '',
 			parameters.vertexColors ? '#define USE_COLOR' : '',
+			parameters.vertexUvs ? '#define USE_UV' : '',
 
 			parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
 
@@ -534,7 +536,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
 			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
 			parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
 
-			parameters.envMap && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',
+			( ( material.extensions ? material.extensions.shaderTextureLOD : false ) || parameters.envMap ) && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',
 
 			'uniform mat4 viewMatrix;',
 			'uniform vec3 cameraPosition;',

+ 1 - 0
src/renderers/webgl/WebGLPrograms.js

@@ -166,6 +166,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 
 			vertexTangents: ( material.normalMap && material.vertexTangents ),
 			vertexColors: material.vertexColors,
+			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearCoatNormalMap,
 
 			fog: !! fog,
 			useFog: material.fog,

+ 0 - 1
utils/modularize.js

@@ -71,7 +71,6 @@ var files = [
 	{ path: 'lines/Wireframe.js', dependencies: [ { name: 'LineSegmentsGeometry', path: 'lines/LineSegmentsGeometry.js' }, { name: 'LineMaterial', path: 'lines/LineMaterial.js' } ], ignoreList: [] },
 	{ path: 'lines/WireframeGeometry2.js', dependencies: [ { name: 'LineSegmentsGeometry', path: 'lines/LineSegmentsGeometry.js' } ], ignoreList: [] },
 
-	{ path: 'loaders/ctm/CTMLoader.js', dependencies: [], ignoreList: [] },
 	{ path: 'loaders/deprecated/LegacyGLTFLoader.js', dependencies: [], ignoreList: [ 'AnimationMixer' ] },
 	{ path: 'loaders/deprecated/LegacyJSONLoader.js', dependencies: [], ignoreList: [ 'ObjectLoader' ] },
 	{ path: 'loaders/3MFLoader.js', dependencies: [], ignoreList: [] },

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません