瀏覽代碼

Updated examples builds.

Mr.doob 2 年之前
父節點
當前提交
46ccd684a0
共有 100 個文件被更改,包括 2282 次插入4259 次删除
  1. 0 8
      examples/js/animation/AnimationClipCreator.js
  2. 28 67
      examples/js/animation/CCDIKSolver.js
  3. 66 137
      examples/js/animation/MMDAnimationHelper.js
  4. 50 138
      examples/js/animation/MMDPhysics.js
  5. 33 22
      examples/js/cameras/CinematicCamera.js
  6. 55 183
      examples/js/controls/ArcballControls.js
  7. 8 33
      examples/js/controls/DragControls.js
  8. 12 34
      examples/js/controls/FirstPersonControls.js
  9. 13 39
      examples/js/controls/FlyControls.js
  10. 85 95
      examples/js/controls/OrbitControls.js
  11. 5 14
      examples/js/controls/PointerLockControls.js
  12. 23 88
      examples/js/controls/TrackballControls.js
  13. 84 169
      examples/js/controls/TransformControls.js
  14. 3 39
      examples/js/csm/CSM.js
  15. 3 9
      examples/js/csm/CSMFrustum.js
  16. 0 6
      examples/js/csm/CSMHelper.js
  17. 2 6
      examples/js/csm/CSMShader.js
  18. 27 27
      examples/js/curves/CurveExtras.js
  19. 4 16
      examples/js/curves/NURBSCurve.js
  20. 3 9
      examples/js/curves/NURBSSurface.js
  21. 8 45
      examples/js/curves/NURBSUtils.js
  22. 4 18
      examples/js/effects/AnaglyphEffect.js
  23. 32 31
      examples/js/effects/AsciiEffect.js
  24. 26 30
      examples/js/effects/OutlineEffect.js
  25. 0 13
      examples/js/effects/ParallaxBarrierEffect.js
  26. 12 39
      examples/js/effects/PeppersGhostEffect.js
  27. 0 4
      examples/js/effects/StereoEffect.js
  28. 12 10
      examples/js/environments/RoomEnvironment.js
  29. 48 65
      examples/js/exporters/ColladaExporter.js
  30. 22 22
      examples/js/exporters/DRACOExporter.js
  31. 15 18
      examples/js/exporters/EXRExporter.js
  32. 100 143
      examples/js/exporters/GLTFExporter.js
  33. 5 12
      examples/js/exporters/MMDExporter.js
  34. 42 33
      examples/js/exporters/OBJExporter.js
  35. 38 33
      examples/js/exporters/PLYExporter.js
  36. 5 7
      examples/js/exporters/STLExporter.js
  37. 14 24
      examples/js/exporters/USDZExporter.js
  38. 0 1
      examples/js/geometries/BoxLineGeometry.js
  39. 11 6
      examples/js/geometries/ConvexGeometry.js
  40. 53 20
      examples/js/geometries/DecalGeometry.js
  41. 54 67
      examples/js/geometries/LightningStrike.js
  42. 8 7
      examples/js/geometries/ParametricGeometries.js
  43. 25 12
      examples/js/geometries/ParametricGeometry.js
  44. 21 19
      examples/js/geometries/RoundedBoxGeometry.js
  45. 6 12
      examples/js/geometries/TeapotGeometry.js
  46. 6 4
      examples/js/geometries/TextGeometry.js
  47. 1 2
      examples/js/helpers/LightProbeHelper.js
  48. 0 12
      examples/js/helpers/OctreeHelper.js
  49. 8 6
      examples/js/helpers/PositionalAudioHelper.js
  50. 6 7
      examples/js/helpers/RectAreaLightHelper.js
  51. 9 14
      examples/js/helpers/VertexNormalsHelper.js
  52. 9 10
      examples/js/helpers/VertexTangentsHelper.js
  53. 10 16
      examples/js/helpers/ViewHelper.js
  54. 21 33
      examples/js/interactive/HTMLMesh.js
  55. 6 12
      examples/js/interactive/InteractiveGroup.js
  56. 3 70
      examples/js/interactive/SelectionBox.js
  57. 0 8
      examples/js/interactive/SelectionHelper.js
  58. 32 39
      examples/js/lights/LightProbeGenerator.js
  59. 2 0
      examples/js/lights/RectAreaLightUniformsLib.js
  60. 3 5
      examples/js/lines/LineGeometry.js
  61. 4 11
      examples/js/lines/LineMaterial.js
  62. 38 89
      examples/js/lines/LineSegments2.js
  63. 7 28
      examples/js/lines/LineSegmentsGeometry.js
  64. 2 7
      examples/js/lines/Wireframe.js
  65. 3 1
      examples/js/lines/WireframeGeometry2.js
  66. 57 154
      examples/js/loaders/3DMLoader.js
  67. 72 106
      examples/js/loaders/3MFLoader.js
  68. 0 25
      examples/js/loaders/AMFLoader.js
  69. 44 43
      examples/js/loaders/BVHLoader.js
  70. 16 46
      examples/js/loaders/BasisTextureLoader.js
  71. 81 141
      examples/js/loaders/ColladaLoader.js
  72. 24 25
      examples/js/loaders/DDSLoader.js
  73. 29 66
      examples/js/loaders/DRACOLoader.js
  74. 67 162
      examples/js/loaders/EXRLoader.js
  75. 87 164
      examples/js/loaders/FBXLoader.js
  76. 6 15
      examples/js/loaders/FontLoader.js
  77. 15 16
      examples/js/loaders/GCodeLoader.js
  78. 50 147
      examples/js/loaders/GLTFLoader.js
  79. 0 6
      examples/js/loaders/HDRCubeTextureLoader.js
  80. 3 7
      examples/js/loaders/KMZLoader.js
  81. 12 30
      examples/js/loaders/KTXLoader.js
  82. 108 171
      examples/js/loaders/LDrawLoader.js
  83. 7 11
      examples/js/loaders/LUT3dlLoader.js
  84. 0 8
      examples/js/loaders/LUTCubeLoader.js
  85. 59 124
      examples/js/loaders/LWOLoader.js
  86. 27 77
      examples/js/loaders/LogLuvLoader.js
  87. 3 3
      examples/js/loaders/LottieLoader.js
  88. 0 0
      examples/js/loaders/MD2Loader.js
  89. 6 10
      examples/js/loaders/MDDLoader.js
  90. 22 35
      examples/js/loaders/MMDLoader.js
  91. 18 47
      examples/js/loaders/MTLLoader.js
  92. 44 84
      examples/js/loaders/NRRDLoader.js
  93. 50 65
      examples/js/loaders/OBJLoader.js
  94. 34 29
      examples/js/loaders/PCDLoader.js
  95. 17 13
      examples/js/loaders/PDBLoader.js
  96. 9 39
      examples/js/loaders/PLYLoader.js
  97. 11 22
      examples/js/loaders/PRWMLoader.js
  98. 7 16
      examples/js/loaders/PVRLoader.js
  99. 36 61
      examples/js/loaders/RGBELoader.js
  100. 26 87
      examples/js/loaders/RGBMLoader.js

+ 0 - 8
examples/js/animation/AnimationClipCreator.js

@@ -11,7 +11,6 @@
 			return new THREE.AnimationClip( null, period, [ track ] );
 			return new THREE.AnimationClip( null, period, [ track ] );
 
 
 		}
 		}
-
 		static CreateScaleAxisAnimation( period, axis = 'x' ) {
 		static CreateScaleAxisAnimation( period, axis = 'x' ) {
 
 
 			const times = [ 0, period ],
 			const times = [ 0, period ],
@@ -21,13 +20,11 @@
 			return new THREE.AnimationClip( null, period, [ track ] );
 			return new THREE.AnimationClip( null, period, [ track ] );
 
 
 		}
 		}
-
 		static CreateShakeAnimation( duration, shakeScale ) {
 		static CreateShakeAnimation( duration, shakeScale ) {
 
 
 			const times = [],
 			const times = [],
 				values = [],
 				values = [],
 				tmp = new THREE.Vector3();
 				tmp = new THREE.Vector3();
-
 			for ( let i = 0; i < duration * 10; i ++ ) {
 			for ( let i = 0; i < duration * 10; i ++ ) {
 
 
 				times.push( i / 10 );
 				times.push( i / 10 );
@@ -40,13 +37,11 @@
 			return new THREE.AnimationClip( null, duration, [ track ] );
 			return new THREE.AnimationClip( null, duration, [ track ] );
 
 
 		}
 		}
-
 		static CreatePulsationAnimation( duration, pulseScale ) {
 		static CreatePulsationAnimation( duration, pulseScale ) {
 
 
 			const times = [],
 			const times = [],
 				values = [],
 				values = [],
 				tmp = new THREE.Vector3();
 				tmp = new THREE.Vector3();
-
 			for ( let i = 0; i < duration * 10; i ++ ) {
 			for ( let i = 0; i < duration * 10; i ++ ) {
 
 
 				times.push( i / 10 );
 				times.push( i / 10 );
@@ -60,7 +55,6 @@
 			return new THREE.AnimationClip( null, duration, [ track ] );
 			return new THREE.AnimationClip( null, duration, [ track ] );
 
 
 		}
 		}
-
 		static CreateVisibilityAnimation( duration ) {
 		static CreateVisibilityAnimation( duration ) {
 
 
 			const times = [ 0, duration / 2, duration ],
 			const times = [ 0, duration / 2, duration ],
@@ -70,13 +64,11 @@
 			return new THREE.AnimationClip( null, duration, [ track ] );
 			return new THREE.AnimationClip( null, duration, [ track ] );
 
 
 		}
 		}
-
 		static CreateMaterialColorAnimation( duration, colors ) {
 		static CreateMaterialColorAnimation( duration, colors ) {
 
 
 			const times = [],
 			const times = [],
 				values = [],
 				values = [],
 				timeStep = duration / colors.length;
 				timeStep = duration / colors.length;
-
 			for ( let i = 0; i <= colors.length; i ++ ) {
 			for ( let i = 0; i <= colors.length; i ++ ) {
 
 
 				times.push( i * timeStep );
 				times.push( i * timeStep );

+ 28 - 67
examples/js/animation/CCDIKSolver.js

@@ -1,26 +1,17 @@
 ( function () {
 ( function () {
 
 
 	const _q = new THREE.Quaternion();
 	const _q = new THREE.Quaternion();
-
 	const _targetPos = new THREE.Vector3();
 	const _targetPos = new THREE.Vector3();
-
 	const _targetVec = new THREE.Vector3();
 	const _targetVec = new THREE.Vector3();
-
 	const _effectorPos = new THREE.Vector3();
 	const _effectorPos = new THREE.Vector3();
-
 	const _effectorVec = new THREE.Vector3();
 	const _effectorVec = new THREE.Vector3();
-
 	const _linkPos = new THREE.Vector3();
 	const _linkPos = new THREE.Vector3();
-
 	const _invLinkQ = new THREE.Quaternion();
 	const _invLinkQ = new THREE.Quaternion();
-
 	const _linkScale = new THREE.Vector3();
 	const _linkScale = new THREE.Vector3();
-
 	const _axis = new THREE.Vector3();
 	const _axis = new THREE.Vector3();
-
 	const _vector = new THREE.Vector3();
 	const _vector = new THREE.Vector3();
-
 	const _matrix = new THREE.Matrix4();
 	const _matrix = new THREE.Matrix4();
+
 	/**
 	/**
  * CCD Algorithm
  * CCD Algorithm
  *  - https://sites.google.com/site/auraliusproject/ccd-algorithm
  *  - https://sites.google.com/site/auraliusproject/ccd-algorithm
@@ -41,7 +32,6 @@
  * } ];
  * } ];
  */
  */
 
 
-
 	class CCDIKSolver {
 	class CCDIKSolver {
 
 
 		/**
 		/**
@@ -52,21 +42,18 @@
 
 
 			this.mesh = mesh;
 			this.mesh = mesh;
 			this.iks = iks;
 			this.iks = iks;
-
 			this._valid();
 			this._valid();
 
 
 		}
 		}
+
 		/**
 		/**
    * Update all IK bones.
    * Update all IK bones.
    *
    *
    * @return {CCDIKSolver}
    * @return {CCDIKSolver}
    */
    */
-
-
 		update() {
 		update() {
 
 
 			const iks = this.iks;
 			const iks = this.iks;
-
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 
 				this.updateOne( iks[ i ] );
 				this.updateOne( iks[ i ] );
@@ -76,64 +63,55 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Update one IK bone
    * Update one IK bone
    *
    *
    * @param {Object} ik parameter
    * @param {Object} ik parameter
    * @return {CCDIKSolver}
    * @return {CCDIKSolver}
    */
    */
-
-
 		updateOne( ik ) {
 		updateOne( ik ) {
 
 
-			const bones = this.mesh.skeleton.bones; // for reference overhead reduction in loop
+			const bones = this.mesh.skeleton.bones;
 
 
+			// for reference overhead reduction in loop
 			const math = Math;
 			const math = Math;
 			const effector = bones[ ik.effector ];
 			const effector = bones[ ik.effector ];
-			const target = bones[ ik.target ]; // don't use getWorldPosition() here for the performance
-			// because it calls updateMatrixWorld( true ) inside.
+			const target = bones[ ik.target ];
 
 
+			// don't use getWorldPosition() here for the performance
+			// because it calls updateMatrixWorld( true ) inside.
 			_targetPos.setFromMatrixPosition( target.matrixWorld );
 			_targetPos.setFromMatrixPosition( target.matrixWorld );
-
 			const links = ik.links;
 			const links = ik.links;
 			const iteration = ik.iteration !== undefined ? ik.iteration : 1;
 			const iteration = ik.iteration !== undefined ? ik.iteration : 1;
-
 			for ( let i = 0; i < iteration; i ++ ) {
 			for ( let i = 0; i < iteration; i ++ ) {
 
 
 				let rotated = false;
 				let rotated = false;
-
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 
 
-					const link = bones[ links[ j ].index ]; // skip this link and following links.
-					// this skip is used for MMD performance optimization.
+					const link = bones[ links[ j ].index ];
 
 
+					// skip this link and following links.
+					// this skip is used for MMD performance optimization.
 					if ( links[ j ].enabled === false ) break;
 					if ( links[ j ].enabled === false ) break;
 					const limitation = links[ j ].limitation;
 					const limitation = links[ j ].limitation;
 					const rotationMin = links[ j ].rotationMin;
 					const rotationMin = links[ j ].rotationMin;
-					const rotationMax = links[ j ].rotationMax; // don't use getWorldPosition/Quaternion() here for the performance
-					// because they call updateMatrixWorld( true ) inside.
+					const rotationMax = links[ j ].rotationMax;
 
 
+					// don't use getWorldPosition/Quaternion() here for the performance
+					// because they call updateMatrixWorld( true ) inside.
 					link.matrixWorld.decompose( _linkPos, _invLinkQ, _linkScale );
 					link.matrixWorld.decompose( _linkPos, _invLinkQ, _linkScale );
-
 					_invLinkQ.invert();
 					_invLinkQ.invert();
+					_effectorPos.setFromMatrixPosition( effector.matrixWorld );
 
 
-					_effectorPos.setFromMatrixPosition( effector.matrixWorld ); // work in link world
-
-
+					// work in link world
 					_effectorVec.subVectors( _effectorPos, _linkPos );
 					_effectorVec.subVectors( _effectorPos, _linkPos );
-
 					_effectorVec.applyQuaternion( _invLinkQ );
 					_effectorVec.applyQuaternion( _invLinkQ );
-
 					_effectorVec.normalize();
 					_effectorVec.normalize();
-
 					_targetVec.subVectors( _targetPos, _linkPos );
 					_targetVec.subVectors( _targetPos, _linkPos );
-
 					_targetVec.applyQuaternion( _invLinkQ );
 					_targetVec.applyQuaternion( _invLinkQ );
-
 					_targetVec.normalize();
 					_targetVec.normalize();
-
 					let angle = _targetVec.dot( _effectorVec );
 					let angle = _targetVec.dot( _effectorVec );
-
 					if ( angle > 1.0 ) {
 					if ( angle > 1.0 ) {
 
 
 						angle = 1.0;
 						angle = 1.0;
@@ -144,10 +122,10 @@
 
 
 					}
 					}
 
 
-					angle = math.acos( angle ); // skip if changing angle is too small to prevent vibration of bone
+					angle = math.acos( angle );
 
 
+					// skip if changing angle is too small to prevent vibration of bone
 					if ( angle < 1e-5 ) continue;
 					if ( angle < 1e-5 ) continue;
-
 					if ( ik.minAngle !== undefined && angle < ik.minAngle ) {
 					if ( ik.minAngle !== undefined && angle < ik.minAngle ) {
 
 
 						angle = ik.minAngle;
 						angle = ik.minAngle;
@@ -161,13 +139,11 @@
 					}
 					}
 
 
 					_axis.crossVectors( _effectorVec, _targetVec );
 					_axis.crossVectors( _effectorVec, _targetVec );
-
 					_axis.normalize();
 					_axis.normalize();
-
 					_q.setFromAxisAngle( _axis, angle );
 					_q.setFromAxisAngle( _axis, angle );
+					link.quaternion.multiply( _q );
 
 
-					link.quaternion.multiply( _q ); // TODO: re-consider the limitation specification
-
+					// TODO: re-consider the limitation specification
 					if ( limitation !== undefined ) {
 					if ( limitation !== undefined ) {
 
 
 						let c = link.quaternion.w;
 						let c = link.quaternion.w;
@@ -201,25 +177,24 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Creates Helper
    * Creates Helper
    *
    *
    * @return {CCDIKHelper}
    * @return {CCDIKHelper}
    */
    */
-
-
 		createHelper() {
 		createHelper() {
 
 
 			return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks );
 			return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks );
 
 
-		} // private methods
+		}
 
 
+		// private methods
 
 
 		_valid() {
 		_valid() {
 
 
 			const iks = this.iks;
 			const iks = this.iks;
 			const bones = this.mesh.skeleton.bones;
 			const bones = this.mesh.skeleton.bones;
-
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 
 				const ik = iks[ i ];
 				const ik = iks[ i ];
@@ -227,11 +202,9 @@
 				const links = ik.links;
 				const links = ik.links;
 				let link0, link1;
 				let link0, link1;
 				link0 = effector;
 				link0 = effector;
-
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 
 
 					link1 = bones[ links[ j ].index ];
 					link1 = bones[ links[ j ].index ];
-
 					if ( link0.parent !== link1 ) {
 					if ( link0.parent !== link1 ) {
 
 
 						console.warn( 'THREE.CCDIKSolver: bone ' + link0.name + ' is not the child of bone ' + link1.name );
 						console.warn( 'THREE.CCDIKSolver: bone ' + link0.name + ' is not the child of bone ' + link1.name );
@@ -247,7 +220,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function getPosition( bone, matrixWorldInv ) {
 	function getPosition( bone, matrixWorldInv ) {
 
 
 		return _vector.setFromMatrixPosition( bone.matrixWorld ).applyMatrix4( matrixWorldInv );
 		return _vector.setFromMatrixPosition( bone.matrixWorld ).applyMatrix4( matrixWorldInv );
@@ -262,14 +234,13 @@
 		array[ index * 3 + 2 ] = v.z;
 		array[ index * 3 + 2 ] = v.z;
 
 
 	}
 	}
+
 	/**
 	/**
  * Visualize IK bones
  * Visualize IK bones
  *
  *
  * @param {SkinnedMesh} mesh
  * @param {SkinnedMesh} mesh
  * @param {Array<Object>} iks
  * @param {Array<Object>} iks
  */
  */
-
-
 	class CCDIKHelper extends THREE.Object3D {
 	class CCDIKHelper extends THREE.Object3D {
 
 
 		constructor( mesh, iks = [], sphereSize = 0.25 ) {
 		constructor( mesh, iks = [], sphereSize = 0.25 ) {
@@ -304,27 +275,22 @@
 				depthWrite: false,
 				depthWrite: false,
 				transparent: true
 				transparent: true
 			} );
 			} );
-
 			this._init();
 			this._init();
 
 
 		}
 		}
+
 		/**
 		/**
    * Updates IK bones visualization.
    * Updates IK bones visualization.
    */
    */
-
-
 		updateMatrixWorld( force ) {
 		updateMatrixWorld( force ) {
 
 
 			const mesh = this.root;
 			const mesh = this.root;
-
 			if ( this.visible ) {
 			if ( this.visible ) {
 
 
 				let offset = 0;
 				let offset = 0;
 				const iks = this.iks;
 				const iks = this.iks;
 				const bones = mesh.skeleton.bones;
 				const bones = mesh.skeleton.bones;
-
 				_matrix.copy( mesh.matrixWorld ).invert();
 				_matrix.copy( mesh.matrixWorld ).invert();
-
 				for ( let i = 0, il = iks.length; i < il; i ++ ) {
 				for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 
 					const ik = iks[ i ];
 					const ik = iks[ i ];
@@ -334,7 +300,6 @@
 					const effectorMesh = this.children[ offset ++ ];
 					const effectorMesh = this.children[ offset ++ ];
 					targetMesh.position.copy( getPosition( targetBone, _matrix ) );
 					targetMesh.position.copy( getPosition( targetBone, _matrix ) );
 					effectorMesh.position.copy( getPosition( effectorBone, _matrix ) );
 					effectorMesh.position.copy( getPosition( effectorBone, _matrix ) );
-
 					for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 					for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 
 
 						const link = ik.links[ j ];
 						const link = ik.links[ j ];
@@ -348,7 +313,6 @@
 					const array = line.geometry.attributes.position.array;
 					const array = line.geometry.attributes.position.array;
 					setPositionOfBoneToAttributeArray( array, 0, targetBone, _matrix );
 					setPositionOfBoneToAttributeArray( array, 0, targetBone, _matrix );
 					setPositionOfBoneToAttributeArray( array, 1, effectorBone, _matrix );
 					setPositionOfBoneToAttributeArray( array, 1, effectorBone, _matrix );
-
 					for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 					for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 
 
 						const link = ik.links[ j ];
 						const link = ik.links[ j ];
@@ -367,11 +331,10 @@
 			super.updateMatrixWorld( force );
 			super.updateMatrixWorld( force );
 
 
 		}
 		}
+
 		/**
 		/**
    * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.
    * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.
    */
    */
-
-
 		dispose() {
 		dispose() {
 
 
 			this.sphereGeometry.dispose();
 			this.sphereGeometry.dispose();
@@ -380,7 +343,6 @@
 			this.linkSphereMaterial.dispose();
 			this.linkSphereMaterial.dispose();
 			this.lineMaterial.dispose();
 			this.lineMaterial.dispose();
 			const children = this.children;
 			const children = this.children;
-
 			for ( let i = 0; i < children.length; i ++ ) {
 			for ( let i = 0; i < children.length; i ++ ) {
 
 
 				const child = children[ i ];
 				const child = children[ i ];
@@ -388,14 +350,14 @@
 
 
 			}
 			}
 
 
-		} // private method
+		}
 
 
+		// private method
 
 
 		_init() {
 		_init() {
 
 
 			const scope = this;
 			const scope = this;
 			const iks = this.iks;
 			const iks = this.iks;
-
 			function createLineGeometry( ik ) {
 			function createLineGeometry( ik ) {
 
 
 				const geometry = new THREE.BufferGeometry();
 				const geometry = new THREE.BufferGeometry();
@@ -434,7 +396,6 @@
 				const ik = iks[ i ];
 				const ik = iks[ i ];
 				this.add( createTargetMesh() );
 				this.add( createTargetMesh() );
 				this.add( createEffectorMesh() );
 				this.add( createEffectorMesh() );
-
 				for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 				for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 
 
 					this.add( createLinkMesh() );
 					this.add( createLinkMesh() );

+ 66 - 137
examples/js/animation/MMDAnimationHelper.js

@@ -12,7 +12,6 @@
  * TODO
  * TODO
  *  - more precise grant skinning support.
  *  - more precise grant skinning support.
  */
  */
-
 	class MMDAnimationHelper {
 	class MMDAnimationHelper {
 
 
 		/**
 		/**
@@ -43,16 +42,14 @@
 				physics: true,
 				physics: true,
 				cameraAnimation: true
 				cameraAnimation: true
 			};
 			};
+			this.onBeforePhysics = function /* mesh */ () {};
 
 
-			this.onBeforePhysics = function
-			/* mesh */
-			() {}; // experimental
-
-
+			// experimental
 			this.sharedPhysics = false;
 			this.sharedPhysics = false;
 			this.masterPhysics = null;
 			this.masterPhysics = null;
 
 
 		}
 		}
+
 		/**
 		/**
    * Adds an Three.js Object to helper and setups animation.
    * Adds an Three.js Object to helper and setups animation.
    * The anmation durations of added objects are synched
    * The anmation durations of added objects are synched
@@ -69,8 +66,6 @@
    * @param {Number} params.delayTime - Only for THREE.Audio. Default is 0.0.
    * @param {Number} params.delayTime - Only for THREE.Audio. Default is 0.0.
    * @return {MMDAnimationHelper}
    * @return {MMDAnimationHelper}
    */
    */
-
-
 		add( object, params = {} ) {
 		add( object, params = {} ) {
 
 
 			if ( object.isSkinnedMesh ) {
 			if ( object.isSkinnedMesh ) {
@@ -95,14 +90,13 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Removes an Three.js Object from helper.
    * Removes an Three.js Object from helper.
    *
    *
    * @param {THREE.SkinnedMesh|THREE.Camera|THREE.Audio} object
    * @param {THREE.SkinnedMesh|THREE.Camera|THREE.Audio} object
    * @return {MMDAnimationHelper}
    * @return {MMDAnimationHelper}
    */
    */
-
-
 		remove( object ) {
 		remove( object ) {
 
 
 			if ( object.isSkinnedMesh ) {
 			if ( object.isSkinnedMesh ) {
@@ -127,18 +121,16 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Updates the animation.
    * Updates the animation.
    *
    *
    * @param {Number} delta
    * @param {Number} delta
    * @return {MMDAnimationHelper}
    * @return {MMDAnimationHelper}
    */
    */
-
-
 		update( delta ) {
 		update( delta ) {
 
 
 			if ( this.audioManager !== null ) this.audioManager.control( delta );
 			if ( this.audioManager !== null ) this.audioManager.control( delta );
-
 			for ( let i = 0; i < this.meshes.length; i ++ ) {
 			for ( let i = 0; i < this.meshes.length; i ++ ) {
 
 
 				this._animateMesh( this.meshes[ i ], delta );
 				this._animateMesh( this.meshes[ i ], delta );
@@ -150,6 +142,7 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Changes the pose of SkinnedMesh as VPD specifies.
    * Changes the pose of SkinnedMesh as VPD specifies.
    *
    *
@@ -161,15 +154,12 @@
    * @param {boolean} params.grant - Default is true.
    * @param {boolean} params.grant - Default is true.
    * @return {MMDAnimationHelper}
    * @return {MMDAnimationHelper}
    */
    */
-
-
 		pose( mesh, vpd, params = {} ) {
 		pose( mesh, vpd, params = {} ) {
 
 
 			if ( params.resetPose !== false ) mesh.pose();
 			if ( params.resetPose !== false ) mesh.pose();
 			const bones = mesh.skeleton.bones;
 			const bones = mesh.skeleton.bones;
 			const boneParams = vpd.bones;
 			const boneParams = vpd.bones;
 			const boneNameDictionary = {};
 			const boneNameDictionary = {};
-
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
 
 				boneNameDictionary[ bones[ i ].name ] = i;
 				boneNameDictionary[ bones[ i ].name ] = i;
@@ -178,7 +168,6 @@
 
 
 			const vector = new THREE.Vector3();
 			const vector = new THREE.Vector3();
 			const quaternion = new THREE.Quaternion();
 			const quaternion = new THREE.Quaternion();
-
 			for ( let i = 0, il = boneParams.length; i < il; i ++ ) {
 			for ( let i = 0, il = boneParams.length; i < il; i ++ ) {
 
 
 				const boneParam = boneParams[ i ];
 				const boneParam = boneParams[ i ];
@@ -190,15 +179,14 @@
 
 
 			}
 			}
 
 
-			mesh.updateMatrixWorld( true ); // PMX animation system special path
+			mesh.updateMatrixWorld( true );
 
 
+			// PMX animation system special path
 			if ( this.configuration.pmxAnimation && mesh.geometry.userData.MMD && mesh.geometry.userData.MMD.format === 'pmx' ) {
 			if ( this.configuration.pmxAnimation && mesh.geometry.userData.MMD && mesh.geometry.userData.MMD.format === 'pmx' ) {
 
 
 				const sortedBonesData = this._sortBoneDataArray( mesh.geometry.userData.MMD.bones.slice() );
 				const sortedBonesData = this._sortBoneDataArray( mesh.geometry.userData.MMD.bones.slice() );
-
 				const ikSolver = params.ik !== false ? this._createCCDIKSolver( mesh ) : null;
 				const ikSolver = params.ik !== false ? this._createCCDIKSolver( mesh ) : null;
 				const grantSolver = params.grant !== false ? this.createGrantSolver( mesh ) : null;
 				const grantSolver = params.grant !== false ? this.createGrantSolver( mesh ) : null;
-
 				this._animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver );
 				this._animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver );
 
 
 			} else {
 			} else {
@@ -220,6 +208,7 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Enabes/Disables an animation feature.
    * Enabes/Disables an animation feature.
    *
    *
@@ -227,8 +216,6 @@
    * @param {boolean} enabled
    * @param {boolean} enabled
    * @return {MMDAnimationHelper}
    * @return {MMDAnimationHelper}
    */
    */
-
-
 		enable( key, enabled ) {
 		enable( key, enabled ) {
 
 
 			if ( this.enabled[ key ] === undefined ) {
 			if ( this.enabled[ key ] === undefined ) {
@@ -238,7 +225,6 @@
 			}
 			}
 
 
 			this.enabled[ key ] = enabled;
 			this.enabled[ key ] = enabled;
-
 			if ( key === 'physics' ) {
 			if ( key === 'physics' ) {
 
 
 				for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 				for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
@@ -252,20 +238,20 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Creates an GrantSolver instance.
    * Creates an GrantSolver instance.
    *
    *
    * @param {THREE.SkinnedMesh} mesh
    * @param {THREE.SkinnedMesh} mesh
    * @return {GrantSolver}
    * @return {GrantSolver}
    */
    */
-
-
 		createGrantSolver( mesh ) {
 		createGrantSolver( mesh ) {
 
 
 			return new GrantSolver( mesh, mesh.geometry.userData.MMD.grants );
 			return new GrantSolver( mesh, mesh.geometry.userData.MMD.grants );
 
 
-		} // private methods
+		}
 
 
+		// private methods
 
 
 		_addMesh( mesh, params ) {
 		_addMesh( mesh, params ) {
 
 
@@ -279,9 +265,7 @@
 			this.objects.set( mesh, {
 			this.objects.set( mesh, {
 				looped: false
 				looped: false
 			} );
 			} );
-
 			this._setupMeshAnimation( mesh, params.animation );
 			this._setupMeshAnimation( mesh, params.animation );
-
 			if ( params.physics !== false ) {
 			if ( params.physics !== false ) {
 
 
 				this._setupMeshPhysics( mesh, params );
 				this._setupMeshPhysics( mesh, params );
@@ -291,7 +275,6 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_setupCamera( camera, params ) {
 		_setupCamera( camera, params ) {
 
 
 			if ( this.camera === camera ) {
 			if ( this.camera === camera ) {
@@ -304,7 +287,6 @@
 			this.camera = camera;
 			this.camera = camera;
 			camera.add( this.cameraTarget );
 			camera.add( this.cameraTarget );
 			this.objects.set( camera, {} );
 			this.objects.set( camera, {} );
-
 			if ( params.animation !== undefined ) {
 			if ( params.animation !== undefined ) {
 
 
 				this._setupCameraAnimation( camera, params.animation );
 				this._setupCameraAnimation( camera, params.animation );
@@ -314,7 +296,6 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_setupAudio( audio, params ) {
 		_setupAudio( audio, params ) {
 
 
 			if ( this.audio === audio ) {
 			if ( this.audio === audio ) {
@@ -332,12 +313,10 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_removeMesh( mesh ) {
 		_removeMesh( mesh ) {
 
 
 			let found = false;
 			let found = false;
 			let writeIndex = 0;
 			let writeIndex = 0;
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 
 				if ( this.meshes[ i ] === mesh ) {
 				if ( this.meshes[ i ] === mesh ) {
@@ -362,7 +341,6 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_clearCamera( camera ) {
 		_clearCamera( camera ) {
 
 
 			if ( camera !== this.camera ) {
 			if ( camera !== this.camera ) {
@@ -377,7 +355,6 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_clearAudio( audio ) {
 		_clearAudio( audio ) {
 
 
 			if ( audio !== this.audio ) {
 			if ( audio !== this.audio ) {
@@ -392,23 +369,20 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_setupMeshAnimation( mesh, animation ) {
 		_setupMeshAnimation( mesh, animation ) {
 
 
 			const objects = this.objects.get( mesh );
 			const objects = this.objects.get( mesh );
-
 			if ( animation !== undefined ) {
 			if ( animation !== undefined ) {
 
 
 				const animations = Array.isArray( animation ) ? animation : [ animation ];
 				const animations = Array.isArray( animation ) ? animation : [ animation ];
 				objects.mixer = new THREE.AnimationMixer( mesh );
 				objects.mixer = new THREE.AnimationMixer( mesh );
-
 				for ( let i = 0, il = animations.length; i < il; i ++ ) {
 				for ( let i = 0, il = animations.length; i < il; i ++ ) {
 
 
 					objects.mixer.clipAction( animations[ i ] ).play();
 					objects.mixer.clipAction( animations[ i ] ).play();
 
 
-				} // TODO: find a workaround not to access ._clip looking like a private property
-
+				}
 
 
+				// TODO: find a workaround not to access ._clip looking like a private property
 				objects.mixer.addEventListener( 'loop', function ( event ) {
 				objects.mixer.addEventListener( 'loop', function ( event ) {
 
 
 					const tracks = event.action._clip.tracks;
 					const tracks = event.action._clip.tracks;
@@ -424,13 +398,11 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_setupCameraAnimation( camera, animation ) {
 		_setupCameraAnimation( camera, animation ) {
 
 
 			const animations = Array.isArray( animation ) ? animation : [ animation ];
 			const animations = Array.isArray( animation ) ? animation : [ animation ];
 			const objects = this.objects.get( camera );
 			const objects = this.objects.get( camera );
 			objects.mixer = new THREE.AnimationMixer( camera );
 			objects.mixer = new THREE.AnimationMixer( camera );
-
 			for ( let i = 0, il = animations.length; i < il; i ++ ) {
 			for ( let i = 0, il = animations.length; i < il; i ++ ) {
 
 
 				objects.mixer.clipAction( animations[ i ] ).play();
 				objects.mixer.clipAction( animations[ i ] ).play();
@@ -438,35 +410,31 @@
 			}
 			}
 
 
 		}
 		}
-
 		_setupMeshPhysics( mesh, params ) {
 		_setupMeshPhysics( mesh, params ) {
 
 
-			const objects = this.objects.get( mesh ); // shared physics is experimental
+			const objects = this.objects.get( mesh );
+
+			// shared physics is experimental
 
 
 			if ( params.world === undefined && this.sharedPhysics ) {
 			if ( params.world === undefined && this.sharedPhysics ) {
 
 
 				const masterPhysics = this._getMasterPhysics();
 				const masterPhysics = this._getMasterPhysics();
-
 				if ( masterPhysics !== null ) world = masterPhysics.world; // eslint-disable-line no-undef
 				if ( masterPhysics !== null ) world = masterPhysics.world; // eslint-disable-line no-undef
 
 
 			}
 			}
 
 
 			objects.physics = this._createMMDPhysics( mesh, params );
 			objects.physics = this._createMMDPhysics( mesh, params );
-
 			if ( objects.mixer && params.animationWarmup !== false ) {
 			if ( objects.mixer && params.animationWarmup !== false ) {
 
 
 				this._animateMesh( mesh, 0 );
 				this._animateMesh( mesh, 0 );
-
 				objects.physics.reset();
 				objects.physics.reset();
 
 
 			}
 			}
 
 
 			objects.physics.warmup( params.warmup !== undefined ? params.warmup : 60 );
 			objects.physics.warmup( params.warmup !== undefined ? params.warmup : 60 );
-
 			this._optimizeIK( mesh, true );
 			this._optimizeIK( mesh, true );
 
 
 		}
 		}
-
 		_animateMesh( mesh, delta ) {
 		_animateMesh( mesh, delta ) {
 
 
 			const objects = this.objects.get( mesh );
 			const objects = this.objects.get( mesh );
@@ -475,23 +443,20 @@
 			const grantSolver = objects.grantSolver;
 			const grantSolver = objects.grantSolver;
 			const physics = objects.physics;
 			const physics = objects.physics;
 			const looped = objects.looped;
 			const looped = objects.looped;
-
 			if ( mixer && this.enabled.animation ) {
 			if ( mixer && this.enabled.animation ) {
 
 
 				// alternate solution to save/restore bones but less performant?
 				// alternate solution to save/restore bones but less performant?
 				//mesh.pose();
 				//mesh.pose();
 				//this._updatePropertyMixersBuffer( mesh );
 				//this._updatePropertyMixersBuffer( mesh );
-				this._restoreBones( mesh );
 
 
+				this._restoreBones( mesh );
 				mixer.update( delta );
 				mixer.update( delta );
+				this._saveBones( mesh );
 
 
-				this._saveBones( mesh ); // PMX animation system special path
-
-
+				// PMX animation system special path
 				if ( this.configuration.pmxAnimation && mesh.geometry.userData.MMD && mesh.geometry.userData.MMD.format === 'pmx' ) {
 				if ( this.configuration.pmxAnimation && mesh.geometry.userData.MMD && mesh.geometry.userData.MMD.format === 'pmx' ) {
 
 
 					if ( ! objects.sortedBonesData ) objects.sortedBonesData = this._sortBoneDataArray( mesh.geometry.userData.MMD.bones.slice() );
 					if ( ! objects.sortedBonesData ) objects.sortedBonesData = this._sortBoneDataArray( mesh.geometry.userData.MMD.bones.slice() );
-
 					this._animatePMXMesh( mesh, objects.sortedBonesData, ikSolver && this.enabled.ik ? ikSolver : null, grantSolver && this.enabled.grant ? grantSolver : null );
 					this._animatePMXMesh( mesh, objects.sortedBonesData, ikSolver && this.enabled.ik ? ikSolver : null, grantSolver && this.enabled.grant ? grantSolver : null );
 
 
 				} else {
 				} else {
@@ -527,11 +492,11 @@
 
 
 			}
 			}
 
 
-		} // Sort bones in order by 1. transformationClass and 2. bone index.
+		}
+
+		// Sort bones in order by 1. transformationClass and 2. bone index.
 		// In PMX animation system, bone transformations should be processed
 		// In PMX animation system, bone transformations should be processed
 		// in this order.
 		// in this order.
-
-
 		_sortBoneDataArray( boneDataArray ) {
 		_sortBoneDataArray( boneDataArray ) {
 
 
 			return boneDataArray.sort( function ( a, b ) {
 			return boneDataArray.sort( function ( a, b ) {
@@ -548,21 +513,19 @@
 
 
 			} );
 			} );
 
 
-		} // PMX Animation system is a bit too complex and doesn't great match to
+		}
+
+		// PMX Animation system is a bit too complex and doesn't great match to
 		// Three.js Animation system. This method attempts to simulate it as much as
 		// Three.js Animation system. This method attempts to simulate it as much as
 		// possible but doesn't perfectly simulate.
 		// possible but doesn't perfectly simulate.
 		// This method is more costly than the regular one so
 		// This method is more costly than the regular one so
 		// you are recommended to set constructor parameter "pmxAnimation: true"
 		// you are recommended to set constructor parameter "pmxAnimation: true"
 		// only if your PMX model animation doesn't work well.
 		// only if your PMX model animation doesn't work well.
 		// If you need better method you would be required to write your own.
 		// If you need better method you would be required to write your own.
-
-
 		_animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver ) {
 		_animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver ) {
 
 
 			_quaternionIndex = 0;
 			_quaternionIndex = 0;
-
 			_grantResultMap.clear();
 			_grantResultMap.clear();
-
 			for ( let i = 0, il = sortedBonesData.length; i < il; i ++ ) {
 			for ( let i = 0, il = sortedBonesData.length; i < il; i ++ ) {
 
 
 				updateOne( mesh, sortedBonesData[ i ].index, ikSolver, grantSolver );
 				updateOne( mesh, sortedBonesData[ i ].index, ikSolver, grantSolver );
@@ -573,11 +536,9 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_animateCamera( camera, delta ) {
 		_animateCamera( camera, delta ) {
 
 
 			const mixer = this.objects.get( camera ).mixer;
 			const mixer = this.objects.get( camera ).mixer;
-
 			if ( mixer && this.enabled.cameraAnimation ) {
 			if ( mixer && this.enabled.cameraAnimation ) {
 
 
 				mixer.update( delta );
 				mixer.update( delta );
@@ -589,21 +550,17 @@
 			}
 			}
 
 
 		}
 		}
-
 		_optimizeIK( mesh, physicsEnabled ) {
 		_optimizeIK( mesh, physicsEnabled ) {
 
 
 			const iks = mesh.geometry.userData.MMD.iks;
 			const iks = mesh.geometry.userData.MMD.iks;
 			const bones = mesh.geometry.userData.MMD.bones;
 			const bones = mesh.geometry.userData.MMD.bones;
-
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 
 				const ik = iks[ i ];
 				const ik = iks[ i ];
 				const links = ik.links;
 				const links = ik.links;
-
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 
 
 					const link = links[ j ];
 					const link = links[ j ];
-
 					if ( physicsEnabled === true ) {
 					if ( physicsEnabled === true ) {
 
 
 						// disable IK of the bone the corresponding rigidBody type of which is 1 or 2
 						// disable IK of the bone the corresponding rigidBody type of which is 1 or 2
@@ -621,7 +578,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		_createCCDIKSolver( mesh ) {
 		_createCCDIKSolver( mesh ) {
 
 
 			if ( THREE.CCDIKSolver === undefined ) {
 			if ( THREE.CCDIKSolver === undefined ) {
@@ -633,7 +589,6 @@
 			return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks );
 			return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks );
 
 
 		}
 		}
-
 		_createMMDPhysics( mesh, params ) {
 		_createMMDPhysics( mesh, params ) {
 
 
 			if ( THREE.MMDPhysics === undefined ) {
 			if ( THREE.MMDPhysics === undefined ) {
@@ -645,29 +600,28 @@
 			return new THREE.MMDPhysics( mesh, mesh.geometry.userData.MMD.rigidBodies, mesh.geometry.userData.MMD.constraints, params );
 			return new THREE.MMDPhysics( mesh, mesh.geometry.userData.MMD.rigidBodies, mesh.geometry.userData.MMD.constraints, params );
 
 
 		}
 		}
+
 		/*
 		/*
    * Detects the longest duration and then sets it to them to sync.
    * Detects the longest duration and then sets it to them to sync.
    * TODO: Not to access private properties ( ._actions and ._clip )
    * TODO: Not to access private properties ( ._actions and ._clip )
    */
    */
-
-
 		_syncDuration() {
 		_syncDuration() {
 
 
 			let max = 0.0;
 			let max = 0.0;
 			const objects = this.objects;
 			const objects = this.objects;
 			const meshes = this.meshes;
 			const meshes = this.meshes;
 			const camera = this.camera;
 			const camera = this.camera;
-			const audioManager = this.audioManager; // get the longest duration
+			const audioManager = this.audioManager;
+
+			// get the longest duration
 
 
 			for ( let i = 0, il = meshes.length; i < il; i ++ ) {
 			for ( let i = 0, il = meshes.length; i < il; i ++ ) {
 
 
 				const mixer = this.objects.get( meshes[ i ] ).mixer;
 				const mixer = this.objects.get( meshes[ i ] ).mixer;
 				if ( mixer === undefined ) continue;
 				if ( mixer === undefined ) continue;
-
 				for ( let j = 0; j < mixer._actions.length; j ++ ) {
 				for ( let j = 0; j < mixer._actions.length; j ++ ) {
 
 
 					const clip = mixer._actions[ j ]._clip;
 					const clip = mixer._actions[ j ]._clip;
-
 					if ( ! objects.has( clip ) ) {
 					if ( ! objects.has( clip ) ) {
 
 
 						objects.set( clip, {
 						objects.set( clip, {
@@ -685,13 +639,11 @@
 			if ( camera !== null ) {
 			if ( camera !== null ) {
 
 
 				const mixer = this.objects.get( camera ).mixer;
 				const mixer = this.objects.get( camera ).mixer;
-
 				if ( mixer !== undefined ) {
 				if ( mixer !== undefined ) {
 
 
 					for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) {
 					for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) {
 
 
 						const clip = mixer._actions[ i ]._clip;
 						const clip = mixer._actions[ i ]._clip;
-
 						if ( ! objects.has( clip ) ) {
 						if ( ! objects.has( clip ) ) {
 
 
 							objects.set( clip, {
 							objects.set( clip, {
@@ -714,13 +666,14 @@
 
 
 			}
 			}
 
 
-			max += this.configuration.afterglow; // update the duration
+			max += this.configuration.afterglow;
+
+			// update the duration
 
 
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 
 				const mixer = this.objects.get( this.meshes[ i ] ).mixer;
 				const mixer = this.objects.get( this.meshes[ i ] ).mixer;
 				if ( mixer === undefined ) continue;
 				if ( mixer === undefined ) continue;
-
 				for ( let j = 0, jl = mixer._actions.length; j < jl; j ++ ) {
 				for ( let j = 0, jl = mixer._actions.length; j < jl; j ++ ) {
 
 
 					mixer._actions[ j ]._clip.duration = max;
 					mixer._actions[ j ]._clip.duration = max;
@@ -732,7 +685,6 @@
 			if ( camera !== null ) {
 			if ( camera !== null ) {
 
 
 				const mixer = this.objects.get( camera ).mixer;
 				const mixer = this.objects.get( camera ).mixer;
-
 				if ( mixer !== undefined ) {
 				if ( mixer !== undefined ) {
 
 
 					for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) {
 					for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) {
@@ -751,15 +703,15 @@
 
 
 			}
 			}
 
 
-		} // workaround
+		}
 
 
+		// workaround
 
 
 		_updatePropertyMixersBuffer( mesh ) {
 		_updatePropertyMixersBuffer( mesh ) {
 
 
 			const mixer = this.objects.get( mesh ).mixer;
 			const mixer = this.objects.get( mesh ).mixer;
 			const propertyMixers = mixer._bindings;
 			const propertyMixers = mixer._bindings;
 			const accuIndex = mixer._accuIndex;
 			const accuIndex = mixer._accuIndex;
-
 			for ( let i = 0, il = propertyMixers.length; i < il; i ++ ) {
 			for ( let i = 0, il = propertyMixers.length; i < il; i ++ ) {
 
 
 				const propertyMixer = propertyMixers[ i ];
 				const propertyMixer = propertyMixers[ i ];
@@ -771,6 +723,7 @@
 			}
 			}
 
 
 		}
 		}
+
 		/*
 		/*
    * Avoiding these two issues by restore/save bones before/after mixer animation.
    * Avoiding these two issues by restore/save bones before/after mixer animation.
    *
    *
@@ -780,14 +733,11 @@
    *
    *
    * 2. Applying Grant two or more times without reset the posing breaks model.
    * 2. Applying Grant two or more times without reset the posing breaks model.
    */
    */
-
-
 		_saveBones( mesh ) {
 		_saveBones( mesh ) {
 
 
 			const objects = this.objects.get( mesh );
 			const objects = this.objects.get( mesh );
 			const bones = mesh.skeleton.bones;
 			const bones = mesh.skeleton.bones;
 			let backupBones = objects.backupBones;
 			let backupBones = objects.backupBones;
-
 			if ( backupBones === undefined ) {
 			if ( backupBones === undefined ) {
 
 
 				backupBones = new Float32Array( bones.length * 7 );
 				backupBones = new Float32Array( bones.length * 7 );
@@ -804,14 +754,12 @@
 			}
 			}
 
 
 		}
 		}
-
 		_restoreBones( mesh ) {
 		_restoreBones( mesh ) {
 
 
 			const objects = this.objects.get( mesh );
 			const objects = this.objects.get( mesh );
 			const backupBones = objects.backupBones;
 			const backupBones = objects.backupBones;
 			if ( backupBones === undefined ) return;
 			if ( backupBones === undefined ) return;
 			const bones = mesh.skeleton.bones;
 			const bones = mesh.skeleton.bones;
-
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
 
 				const bone = bones[ i ];
 				const bone = bones[ i ];
@@ -820,17 +768,16 @@
 
 
 			}
 			}
 
 
-		} // experimental
+		}
 
 
+		// experimental
 
 
 		_getMasterPhysics() {
 		_getMasterPhysics() {
 
 
 			if ( this.masterPhysics !== null ) return this.masterPhysics;
 			if ( this.masterPhysics !== null ) return this.masterPhysics;
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 
 				const physics = this.meshes[ i ].physics;
 				const physics = this.meshes[ i ].physics;
-
 				if ( physics !== undefined && physics !== null ) {
 				if ( physics !== undefined && physics !== null ) {
 
 
 					this.masterPhysics = physics;
 					this.masterPhysics = physics;
@@ -843,19 +790,14 @@
 			return null;
 			return null;
 
 
 		}
 		}
-
 		_updateSharedPhysics( delta ) {
 		_updateSharedPhysics( delta ) {
 
 
 			if ( this.meshes.length === 0 || ! this.enabled.physics || ! this.sharedPhysics ) return;
 			if ( this.meshes.length === 0 || ! this.enabled.physics || ! this.sharedPhysics ) return;
-
 			const physics = this._getMasterPhysics();
 			const physics = this._getMasterPhysics();
-
 			if ( physics === null ) return;
 			if ( physics === null ) return;
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 
 				const p = this.meshes[ i ].physics;
 				const p = this.meshes[ i ].physics;
-
 				if ( p !== null && p !== undefined ) {
 				if ( p !== null && p !== undefined ) {
 
 
 					p.updateRigidBodies();
 					p.updateRigidBodies();
@@ -865,11 +807,9 @@
 			}
 			}
 
 
 			physics.stepSimulation( delta );
 			physics.stepSimulation( delta );
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 
 				const p = this.meshes[ i ].physics;
 				const p = this.meshes[ i ].physics;
-
 				if ( p !== null && p !== undefined ) {
 				if ( p !== null && p !== undefined ) {
 
 
 					p.updateBones();
 					p.updateBones();
@@ -880,12 +820,11 @@
 
 
 		}
 		}
 
 
-	} // Keep working quaternions for less GC
-
+	}
 
 
+	// Keep working quaternions for less GC
 	const _quaternions = [];
 	const _quaternions = [];
 	let _quaternionIndex = 0;
 	let _quaternionIndex = 0;
-
 	function getQuaternion() {
 	function getQuaternion() {
 
 
 		if ( _quaternionIndex >= _quaternions.length ) {
 		if ( _quaternionIndex >= _quaternions.length ) {
@@ -896,33 +835,33 @@
 
 
 		return _quaternions[ _quaternionIndex ++ ];
 		return _quaternions[ _quaternionIndex ++ ];
 
 
-	} // Save rotation whose grant and IK are already applied
-	// used by grant children
-
+	}
 
 
+	// Save rotation whose grant and IK are already applied
+	// used by grant children
 	const _grantResultMap = new Map();
 	const _grantResultMap = new Map();
-
 	function updateOne( mesh, boneIndex, ikSolver, grantSolver ) {
 	function updateOne( mesh, boneIndex, ikSolver, grantSolver ) {
 
 
 		const bones = mesh.skeleton.bones;
 		const bones = mesh.skeleton.bones;
 		const bonesData = mesh.geometry.userData.MMD.bones;
 		const bonesData = mesh.geometry.userData.MMD.bones;
 		const boneData = bonesData[ boneIndex ];
 		const boneData = bonesData[ boneIndex ];
-		const bone = bones[ boneIndex ]; // Return if already updated by being referred as a grant parent.
+		const bone = bones[ boneIndex ];
 
 
+		// Return if already updated by being referred as a grant parent.
 		if ( _grantResultMap.has( boneIndex ) ) return;
 		if ( _grantResultMap.has( boneIndex ) ) return;
-		const quaternion = getQuaternion(); // Initialize grant result here to prevent infinite loop.
+		const quaternion = getQuaternion();
+
+		// Initialize grant result here to prevent infinite loop.
 		// If it's referred before updating with actual result later
 		// If it's referred before updating with actual result later
 		// result without applyting IK or grant is gotten
 		// result without applyting IK or grant is gotten
 		// but better than composing of infinite loop.
 		// but better than composing of infinite loop.
+		_grantResultMap.set( boneIndex, quaternion.copy( bone.quaternion ) );
 
 
-		_grantResultMap.set( boneIndex, quaternion.copy( bone.quaternion ) ); // @TODO: Support global grant and grant position
-
-
+		// @TODO: Support global grant and grant position
 		if ( grantSolver && boneData.grant && ! boneData.grant.isLocal && boneData.grant.affectRotation ) {
 		if ( grantSolver && boneData.grant && ! boneData.grant.isLocal && boneData.grant.affectRotation ) {
 
 
 			const parentIndex = boneData.grant.parentIndex;
 			const parentIndex = boneData.grant.parentIndex;
 			const ratio = boneData.grant.ratio;
 			const ratio = boneData.grant.ratio;
-
 			if ( ! _grantResultMap.has( parentIndex ) ) {
 			if ( ! _grantResultMap.has( parentIndex ) ) {
 
 
 				updateOne( mesh, parentIndex, ikSolver, grantSolver );
 				updateOne( mesh, parentIndex, ikSolver, grantSolver );
@@ -938,16 +877,15 @@
 			// @TODO: Updating world matrices every time solving an IK bone is
 			// @TODO: Updating world matrices every time solving an IK bone is
 			// costly. Optimize if possible.
 			// costly. Optimize if possible.
 			mesh.updateMatrixWorld( true );
 			mesh.updateMatrixWorld( true );
-			ikSolver.updateOne( boneData.ik ); // No confident, but it seems the grant results with ik links should be updated?
+			ikSolver.updateOne( boneData.ik );
 
 
+			// No confident, but it seems the grant results with ik links should be updated?
 			const links = boneData.ik.links;
 			const links = boneData.ik.links;
-
 			for ( let i = 0, il = links.length; i < il; i ++ ) {
 			for ( let i = 0, il = links.length; i < il; i ++ ) {
 
 
 				const link = links[ i ];
 				const link = links[ i ];
 				if ( link.enabled === false ) continue;
 				if ( link.enabled === false ) continue;
 				const linkIndex = link.index;
 				const linkIndex = link.index;
-
 				if ( _grantResultMap.has( linkIndex ) ) {
 				if ( _grantResultMap.has( linkIndex ) ) {
 
 
 					_grantResultMap.set( linkIndex, _grantResultMap.get( linkIndex ).copy( bones[ linkIndex ].quaternion ) );
 					_grantResultMap.set( linkIndex, _grantResultMap.get( linkIndex ).copy( bones[ linkIndex ].quaternion ) );
@@ -956,13 +894,14 @@
 
 
 			}
 			}
 
 
-		} // Update with the actual result here
-
+		}
 
 
+		// Update with the actual result here
 		quaternion.copy( bone.quaternion );
 		quaternion.copy( bone.quaternion );
 
 
-	} //
+	}
 
 
+	//
 
 
 	class AudioManager {
 	class AudioManager {
 
 
@@ -981,12 +920,11 @@
 			this.duration = this.audioDuration + this.delayTime;
 			this.duration = this.audioDuration + this.delayTime;
 
 
 		}
 		}
+
 		/**
 		/**
    * @param {Number} delta
    * @param {Number} delta
    * @return {AudioManager}
    * @return {AudioManager}
    */
    */
-
-
 		control( delta ) {
 		control( delta ) {
 
 
 			this.elapsed += delta;
 			this.elapsed += delta;
@@ -995,26 +933,26 @@
 			if ( this._shouldStartAudio() ) this.audio.play();
 			if ( this._shouldStartAudio() ) this.audio.play();
 			return this;
 			return this;
 
 
-		} // private methods
+		}
 
 
+		// private methods
 
 
 		_shouldStartAudio() {
 		_shouldStartAudio() {
 
 
 			if ( this.audio.isPlaying ) return false;
 			if ( this.audio.isPlaying ) return false;
-
 			while ( this.currentTime >= this.duration ) {
 			while ( this.currentTime >= this.duration ) {
 
 
 				this.currentTime -= this.duration;
 				this.currentTime -= this.duration;
 
 
 			}
 			}
 
 
-			if ( this.currentTime < this.delayTime ) return false; // 'duration' can be bigger than 'audioDuration + delayTime' because of sync configuration
+			if ( this.currentTime < this.delayTime ) return false;
 
 
+			// 'duration' can be bigger than 'audioDuration + delayTime' because of sync configuration
 			if ( this.currentTime - this.delayTime > this.audioDuration ) return false;
 			if ( this.currentTime - this.delayTime > this.audioDuration ) return false;
 			return true;
 			return true;
 
 
 		}
 		}
-
 		_shouldStopAudio() {
 		_shouldStopAudio() {
 
 
 			return this.audio.isPlaying && this.currentTime >= this.duration;
 			return this.audio.isPlaying && this.currentTime >= this.duration;
@@ -1022,8 +960,8 @@
 		}
 		}
 
 
 	}
 	}
-
 	const _q = new THREE.Quaternion();
 	const _q = new THREE.Quaternion();
+
 	/**
 	/**
  * Solver for Grant (Fuyo in Japanese. I just google translated because
  * Solver for Grant (Fuyo in Japanese. I just google translated because
  * Fuyo may be MMD specific term and may not be common word in 3D CG terms.)
  * Fuyo may be MMD specific term and may not be common word in 3D CG terms.)
@@ -1032,8 +970,6 @@
  * @param {THREE.SkinnedMesh} mesh
  * @param {THREE.SkinnedMesh} mesh
  * @param {Array<Object>} grants
  * @param {Array<Object>} grants
  */
  */
-
-
 	class GrantSolver {
 	class GrantSolver {
 
 
 		constructor( mesh, grants = [] ) {
 		constructor( mesh, grants = [] ) {
@@ -1042,16 +978,14 @@
 			this.grants = grants;
 			this.grants = grants;
 
 
 		}
 		}
+
 		/**
 		/**
    * Solve all the grant bones
    * Solve all the grant bones
    * @return {GrantSolver}
    * @return {GrantSolver}
    */
    */
-
-
 		update() {
 		update() {
 
 
 			const grants = this.grants;
 			const grants = this.grants;
-
 			for ( let i = 0, il = grants.length; i < il; i ++ ) {
 			for ( let i = 0, il = grants.length; i < il; i ++ ) {
 
 
 				this.updateOne( grants[ i ] );
 				this.updateOne( grants[ i ] );
@@ -1061,25 +995,23 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Solve a grant bone
    * Solve a grant bone
    * @param {Object} grant - grant parameter
    * @param {Object} grant - grant parameter
    * @return {GrantSolver}
    * @return {GrantSolver}
    */
    */
-
-
 		updateOne( grant ) {
 		updateOne( grant ) {
 
 
 			const bones = this.mesh.skeleton.bones;
 			const bones = this.mesh.skeleton.bones;
 			const bone = bones[ grant.index ];
 			const bone = bones[ grant.index ];
 			const parentBone = bones[ grant.parentIndex ];
 			const parentBone = bones[ grant.parentIndex ];
-
 			if ( grant.isLocal ) {
 			if ( grant.isLocal ) {
 
 
 				// TODO: implement
 				// TODO: implement
-				if ( grant.affectPosition ) {} // TODO: implement
-
+				if ( grant.affectPosition ) {}
 
 
+				// TODO: implement
 				if ( grant.affectRotation ) {}
 				if ( grant.affectRotation ) {}
 
 
 			} else {
 			} else {
@@ -1098,13 +1030,10 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		addGrantRotation( bone, q, ratio ) {
 		addGrantRotation( bone, q, ratio ) {
 
 
 			_q.set( 0, 0, 0, 1 );
 			_q.set( 0, 0, 0, 1 );
-
 			_q.slerp( q, ratio );
 			_q.slerp( q, ratio );
-
 			bone.quaternion.multiply( _q );
 			bone.quaternion.multiply( _q );
 			return this;
 			return this;
 
 

+ 50 - 138
examples/js/animation/MMDPhysics.js

@@ -34,13 +34,13 @@
 
 
 			this.manager = new ResourceManager();
 			this.manager = new ResourceManager();
 			this.mesh = mesh;
 			this.mesh = mesh;
+
 			/*
 			/*
      * I don't know why but 1/60 unitStep easily breaks models
      * I don't know why but 1/60 unitStep easily breaks models
      * so I set it 1/65 so far.
      * so I set it 1/65 so far.
      * Don't set too small unitStep because
      * Don't set too small unitStep because
      * the smaller unitStep can make the performance worse.
      * the smaller unitStep can make the performance worse.
      */
      */
-
 			this.unitStep = params.unitStep !== undefined ? params.unitStep : 1 / 65;
 			this.unitStep = params.unitStep !== undefined ? params.unitStep : 1 / 65;
 			this.maxStepNum = params.maxStepNum !== undefined ? params.maxStepNum : 3;
 			this.maxStepNum = params.maxStepNum !== undefined ? params.maxStepNum : 3;
 			this.gravity = new THREE.Vector3( 0, - 9.8 * 10, 0 );
 			this.gravity = new THREE.Vector3( 0, - 9.8 * 10, 0 );
@@ -49,22 +49,22 @@
 
 
 			this.bodies = [];
 			this.bodies = [];
 			this.constraints = [];
 			this.constraints = [];
-
 			this._init( mesh, rigidBodyParams, constraintParams );
 			this._init( mesh, rigidBodyParams, constraintParams );
 
 
 		}
 		}
+
 		/**
 		/**
    * Advances Physics calculation and updates bones.
    * Advances Physics calculation and updates bones.
    *
    *
    * @param {Number} delta - time in second
    * @param {Number} delta - time in second
    * @return {MMDPhysics}
    * @return {MMDPhysics}
    */
    */
-
-
 		update( delta ) {
 		update( delta ) {
 
 
 			const manager = this.manager;
 			const manager = this.manager;
-			const mesh = this.mesh; // rigid bodies and constrains are for
+			const mesh = this.mesh;
+
+			// rigid bodies and constrains are for
 			// mesh's world scale (1, 1, 1).
 			// mesh's world scale (1, 1, 1).
 			// Convert to (1, 1, 1) if it isn't.
 			// Convert to (1, 1, 1) if it isn't.
 
 
@@ -73,7 +73,6 @@
 			const quaternion = manager.allocThreeQuaternion();
 			const quaternion = manager.allocThreeQuaternion();
 			const scale = manager.allocThreeVector3();
 			const scale = manager.allocThreeVector3();
 			mesh.matrixWorld.decompose( position, quaternion, scale );
 			mesh.matrixWorld.decompose( position, quaternion, scale );
-
 			if ( scale.x !== 1 || scale.y !== 1 || scale.z !== 1 ) {
 			if ( scale.x !== 1 || scale.y !== 1 || scale.z !== 1 ) {
 
 
 				isNonDefaultScale = true;
 				isNonDefaultScale = true;
@@ -81,7 +80,6 @@
 			}
 			}
 
 
 			let parent;
 			let parent;
-
 			if ( isNonDefaultScale ) {
 			if ( isNonDefaultScale ) {
 
 
 				parent = mesh.parent;
 				parent = mesh.parent;
@@ -90,15 +88,15 @@
 				mesh.scale.set( 1, 1, 1 );
 				mesh.scale.set( 1, 1, 1 );
 				mesh.updateMatrixWorld( true );
 				mesh.updateMatrixWorld( true );
 
 
-			} // calculate physics and update bones
+			}
 
 
+			// calculate physics and update bones
 
 
 			this._updateRigidBodies();
 			this._updateRigidBodies();
-
 			this._stepSimulation( delta );
 			this._stepSimulation( delta );
+			this._updateBones();
 
 
-			this._updateBones(); // restore mesh if converted above
-
+			// restore mesh if converted above
 
 
 			if ( isNonDefaultScale ) {
 			if ( isNonDefaultScale ) {
 
 
@@ -113,13 +111,12 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Resets rigid bodies transorm to current bone's.
    * Resets rigid bodies transorm to current bone's.
    *
    *
    * @return {MMDPhysics}
    * @return {MMDPhysics}
    */
    */
-
-
 		reset() {
 		reset() {
 
 
 			for ( let i = 0, il = this.bodies.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.bodies.length; i < il; i ++ ) {
@@ -131,14 +128,13 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Warm ups Rigid bodies. Calculates cycles steps.
    * Warm ups Rigid bodies. Calculates cycles steps.
    *
    *
    * @param {Integer} cycles
    * @param {Integer} cycles
    * @return {MMDPhysics}
    * @return {MMDPhysics}
    */
    */
-
-
 		warmup( cycles ) {
 		warmup( cycles ) {
 
 
 			for ( let i = 0; i < cycles; i ++ ) {
 			for ( let i = 0; i < cycles; i ++ ) {
@@ -150,14 +146,13 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Sets gravity.
    * Sets gravity.
    *
    *
    * @param {Vector3} gravity
    * @param {Vector3} gravity
    * @return {MMDPhysicsHelper}
    * @return {MMDPhysicsHelper}
    */
    */
-
-
 		setGravity( gravity ) {
 		setGravity( gravity ) {
 
 
 			this.world.setGravity( new Ammo.btVector3( gravity.x, gravity.y, gravity.z ) );
 			this.world.setGravity( new Ammo.btVector3( gravity.x, gravity.y, gravity.z ) );
@@ -165,23 +160,25 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Creates MMDPhysicsHelper
    * Creates MMDPhysicsHelper
    *
    *
    * @return {MMDPhysicsHelper}
    * @return {MMDPhysicsHelper}
    */
    */
-
-
 		createHelper() {
 		createHelper() {
 
 
 			return new MMDPhysicsHelper( this.mesh, this );
 			return new MMDPhysicsHelper( this.mesh, this );
 
 
-		} // private methods
+		}
 
 
+		// private methods
 
 
 		_init( mesh, rigidBodyParams, constraintParams ) {
 		_init( mesh, rigidBodyParams, constraintParams ) {
 
 
-			const manager = this.manager; // rigid body/constraint parameters are for
+			const manager = this.manager;
+
+			// rigid body/constraint parameters are for
 			// mesh's default world transform as position(0, 0, 0),
 			// mesh's default world transform as position(0, 0, 0),
 			// quaternion(0, 0, 0, 1) and scale(0, 0, 0)
 			// quaternion(0, 0, 0, 1) and scale(0, 0, 0)
 
 
@@ -197,7 +194,6 @@
 			mesh.quaternion.set( 0, 0, 0, 1 );
 			mesh.quaternion.set( 0, 0, 0, 1 );
 			mesh.scale.set( 1, 1, 1 );
 			mesh.scale.set( 1, 1, 1 );
 			mesh.updateMatrixWorld( true );
 			mesh.updateMatrixWorld( true );
-
 			if ( this.world === null ) {
 			if ( this.world === null ) {
 
 
 				this.world = this._createWorld();
 				this.world = this._createWorld();
@@ -206,9 +202,7 @@
 			}
 			}
 
 
 			this._initRigidBodies( rigidBodyParams );
 			this._initRigidBodies( rigidBodyParams );
-
 			this._initConstraints( constraintParams );
 			this._initConstraints( constraintParams );
-
 			if ( parent !== null ) mesh.parent = parent;
 			if ( parent !== null ) mesh.parent = parent;
 			mesh.position.copy( currentPosition );
 			mesh.position.copy( currentPosition );
 			mesh.quaternion.copy( currentQuaternion );
 			mesh.quaternion.copy( currentQuaternion );
@@ -220,7 +214,6 @@
 			manager.freeThreeVector3( currentScale );
 			manager.freeThreeVector3( currentScale );
 
 
 		}
 		}
-
 		_createWorld() {
 		_createWorld() {
 
 
 			const config = new Ammo.btDefaultCollisionConfiguration();
 			const config = new Ammo.btDefaultCollisionConfiguration();
@@ -231,7 +224,6 @@
 			return world;
 			return world;
 
 
 		}
 		}
-
 		_initRigidBodies( rigidBodies ) {
 		_initRigidBodies( rigidBodies ) {
 
 
 			for ( let i = 0, il = rigidBodies.length; i < il; i ++ ) {
 			for ( let i = 0, il = rigidBodies.length; i < il; i ++ ) {
@@ -241,7 +233,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		_initConstraints( constraints ) {
 		_initConstraints( constraints ) {
 
 
 			for ( let i = 0, il = constraints.length; i < il; i ++ ) {
 			for ( let i = 0, il = constraints.length; i < il; i ++ ) {
@@ -254,13 +245,11 @@
 			}
 			}
 
 
 		}
 		}
-
 		_stepSimulation( delta ) {
 		_stepSimulation( delta ) {
 
 
 			const unitStep = this.unitStep;
 			const unitStep = this.unitStep;
 			let stepTime = delta;
 			let stepTime = delta;
 			let maxStepNum = ( delta / unitStep | 0 ) + 1;
 			let maxStepNum = ( delta / unitStep | 0 ) + 1;
-
 			if ( stepTime < unitStep ) {
 			if ( stepTime < unitStep ) {
 
 
 				stepTime = unitStep;
 				stepTime = unitStep;
@@ -277,7 +266,6 @@
 			this.world.stepSimulation( stepTime, maxStepNum, unitStep );
 			this.world.stepSimulation( stepTime, maxStepNum, unitStep );
 
 
 		}
 		}
-
 		_updateRigidBodies() {
 		_updateRigidBodies() {
 
 
 			for ( let i = 0, il = this.bodies.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.bodies.length; i < il; i ++ ) {
@@ -287,7 +275,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		_updateBones() {
 		_updateBones() {
 
 
 			for ( let i = 0, il = this.bodies.length; i < il; i ++ ) {
 			for ( let i = 0, il = this.bodies.length; i < il; i ++ ) {
@@ -299,6 +286,7 @@
 		}
 		}
 
 
 	}
 	}
+
 	/**
 	/**
  * This manager's responsibilies are
  * This manager's responsibilies are
  *
  *
@@ -308,8 +296,6 @@
  *
  *
  * 2. provide simple Ammo object operations.
  * 2. provide simple Ammo object operations.
  */
  */
-
-
 	class ResourceManager {
 	class ResourceManager {
 
 
 		constructor() {
 		constructor() {
@@ -318,104 +304,89 @@
 			this.threeVector3s = [];
 			this.threeVector3s = [];
 			this.threeMatrix4s = [];
 			this.threeMatrix4s = [];
 			this.threeQuaternions = [];
 			this.threeQuaternions = [];
-			this.threeEulers = []; // for Ammo.js
+			this.threeEulers = [];
 
 
+			// for Ammo.js
 			this.transforms = [];
 			this.transforms = [];
 			this.quaternions = [];
 			this.quaternions = [];
 			this.vector3s = [];
 			this.vector3s = [];
 
 
 		}
 		}
-
 		allocThreeVector3() {
 		allocThreeVector3() {
 
 
 			return this.threeVector3s.length > 0 ? this.threeVector3s.pop() : new THREE.Vector3();
 			return this.threeVector3s.length > 0 ? this.threeVector3s.pop() : new THREE.Vector3();
 
 
 		}
 		}
-
 		freeThreeVector3( v ) {
 		freeThreeVector3( v ) {
 
 
 			this.threeVector3s.push( v );
 			this.threeVector3s.push( v );
 
 
 		}
 		}
-
 		allocThreeMatrix4() {
 		allocThreeMatrix4() {
 
 
 			return this.threeMatrix4s.length > 0 ? this.threeMatrix4s.pop() : new THREE.Matrix4();
 			return this.threeMatrix4s.length > 0 ? this.threeMatrix4s.pop() : new THREE.Matrix4();
 
 
 		}
 		}
-
 		freeThreeMatrix4( m ) {
 		freeThreeMatrix4( m ) {
 
 
 			this.threeMatrix4s.push( m );
 			this.threeMatrix4s.push( m );
 
 
 		}
 		}
-
 		allocThreeQuaternion() {
 		allocThreeQuaternion() {
 
 
 			return this.threeQuaternions.length > 0 ? this.threeQuaternions.pop() : new THREE.Quaternion();
 			return this.threeQuaternions.length > 0 ? this.threeQuaternions.pop() : new THREE.Quaternion();
 
 
 		}
 		}
-
 		freeThreeQuaternion( q ) {
 		freeThreeQuaternion( q ) {
 
 
 			this.threeQuaternions.push( q );
 			this.threeQuaternions.push( q );
 
 
 		}
 		}
-
 		allocThreeEuler() {
 		allocThreeEuler() {
 
 
 			return this.threeEulers.length > 0 ? this.threeEulers.pop() : new THREE.Euler();
 			return this.threeEulers.length > 0 ? this.threeEulers.pop() : new THREE.Euler();
 
 
 		}
 		}
-
 		freeThreeEuler( e ) {
 		freeThreeEuler( e ) {
 
 
 			this.threeEulers.push( e );
 			this.threeEulers.push( e );
 
 
 		}
 		}
-
 		allocTransform() {
 		allocTransform() {
 
 
 			return this.transforms.length > 0 ? this.transforms.pop() : new Ammo.btTransform();
 			return this.transforms.length > 0 ? this.transforms.pop() : new Ammo.btTransform();
 
 
 		}
 		}
-
 		freeTransform( t ) {
 		freeTransform( t ) {
 
 
 			this.transforms.push( t );
 			this.transforms.push( t );
 
 
 		}
 		}
-
 		allocQuaternion() {
 		allocQuaternion() {
 
 
 			return this.quaternions.length > 0 ? this.quaternions.pop() : new Ammo.btQuaternion();
 			return this.quaternions.length > 0 ? this.quaternions.pop() : new Ammo.btQuaternion();
 
 
 		}
 		}
-
 		freeQuaternion( q ) {
 		freeQuaternion( q ) {
 
 
 			this.quaternions.push( q );
 			this.quaternions.push( q );
 
 
 		}
 		}
-
 		allocVector3() {
 		allocVector3() {
 
 
 			return this.vector3s.length > 0 ? this.vector3s.pop() : new Ammo.btVector3();
 			return this.vector3s.length > 0 ? this.vector3s.pop() : new Ammo.btVector3();
 
 
 		}
 		}
-
 		freeVector3( v ) {
 		freeVector3( v ) {
 
 
 			this.vector3s.push( v );
 			this.vector3s.push( v );
 
 
 		}
 		}
-
 		setIdentity( t ) {
 		setIdentity( t ) {
 
 
 			t.setIdentity();
 			t.setIdentity();
 
 
 		}
 		}
-
 		getBasis( t ) {
 		getBasis( t ) {
 
 
 			var q = this.allocQuaternion();
 			var q = this.allocQuaternion();
@@ -423,7 +394,6 @@
 			return q;
 			return q;
 
 
 		}
 		}
-
 		getBasisAsMatrix3( t ) {
 		getBasisAsMatrix3( t ) {
 
 
 			var q = this.getBasis( t );
 			var q = this.getBasis( t );
@@ -432,32 +402,27 @@
 			return m;
 			return m;
 
 
 		}
 		}
-
 		getOrigin( t ) {
 		getOrigin( t ) {
 
 
 			return t.getOrigin();
 			return t.getOrigin();
 
 
 		}
 		}
-
 		setOrigin( t, v ) {
 		setOrigin( t, v ) {
 
 
 			t.getOrigin().setValue( v.x(), v.y(), v.z() );
 			t.getOrigin().setValue( v.x(), v.y(), v.z() );
 
 
 		}
 		}
-
 		copyOrigin( t1, t2 ) {
 		copyOrigin( t1, t2 ) {
 
 
 			var o = t2.getOrigin();
 			var o = t2.getOrigin();
 			this.setOrigin( t1, o );
 			this.setOrigin( t1, o );
 
 
 		}
 		}
-
 		setBasis( t, q ) {
 		setBasis( t, q ) {
 
 
 			t.setRotation( q );
 			t.setRotation( q );
 
 
 		}
 		}
-
 		setBasisFromMatrix3( t, m ) {
 		setBasisFromMatrix3( t, m ) {
 
 
 			var q = this.matrix3ToQuaternion( m );
 			var q = this.matrix3ToQuaternion( m );
@@ -465,19 +430,16 @@
 			this.freeQuaternion( q );
 			this.freeQuaternion( q );
 
 
 		}
 		}
-
 		setOriginFromArray3( t, a ) {
 		setOriginFromArray3( t, a ) {
 
 
 			t.getOrigin().setValue( a[ 0 ], a[ 1 ], a[ 2 ] );
 			t.getOrigin().setValue( a[ 0 ], a[ 1 ], a[ 2 ] );
 
 
 		}
 		}
-
 		setOriginFromThreeVector3( t, v ) {
 		setOriginFromThreeVector3( t, v ) {
 
 
 			t.getOrigin().setValue( v.x, v.y, v.z );
 			t.getOrigin().setValue( v.x, v.y, v.z );
 
 
 		}
 		}
-
 		setBasisFromArray3( t, a ) {
 		setBasisFromArray3( t, a ) {
 
 
 			var thQ = this.allocThreeQuaternion();
 			var thQ = this.allocThreeQuaternion();
@@ -488,7 +450,6 @@
 			this.freeThreeQuaternion( thQ );
 			this.freeThreeQuaternion( thQ );
 
 
 		}
 		}
-
 		setBasisFromThreeQuaternion( t, a ) {
 		setBasisFromThreeQuaternion( t, a ) {
 
 
 			var q = this.allocQuaternion();
 			var q = this.allocQuaternion();
@@ -500,7 +461,6 @@
 			this.freeQuaternion( q );
 			this.freeQuaternion( q );
 
 
 		}
 		}
-
 		multiplyTransforms( t1, t2 ) {
 		multiplyTransforms( t1, t2 ) {
 
 
 			var t = this.allocTransform();
 			var t = this.allocTransform();
@@ -519,7 +479,6 @@
 			return t;
 			return t;
 
 
 		}
 		}
-
 		inverseTransform( t ) {
 		inverseTransform( t ) {
 
 
 			var t2 = this.allocTransform();
 			var t2 = this.allocTransform();
@@ -535,7 +494,6 @@
 			return t2;
 			return t2;
 
 
 		}
 		}
-
 		multiplyMatrices3( m1, m2 ) {
 		multiplyMatrices3( m1, m2 ) {
 
 
 			var m3 = [];
 			var m3 = [];
@@ -563,7 +521,6 @@
 			return m3;
 			return m3;
 
 
 		}
 		}
-
 		addVector3( v1, v2 ) {
 		addVector3( v1, v2 ) {
 
 
 			var v = this.allocVector3();
 			var v = this.allocVector3();
@@ -571,13 +528,11 @@
 			return v;
 			return v;
 
 
 		}
 		}
-
 		dotVectors3( v1, v2 ) {
 		dotVectors3( v1, v2 ) {
 
 
 			return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
 			return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
 
 
 		}
 		}
-
 		rowOfMatrix3( m, i ) {
 		rowOfMatrix3( m, i ) {
 
 
 			var v = this.allocVector3();
 			var v = this.allocVector3();
@@ -585,7 +540,6 @@
 			return v;
 			return v;
 
 
 		}
 		}
-
 		columnOfMatrix3( m, i ) {
 		columnOfMatrix3( m, i ) {
 
 
 			var v = this.allocVector3();
 			var v = this.allocVector3();
@@ -593,7 +547,6 @@
 			return v;
 			return v;
 
 
 		}
 		}
-
 		negativeVector3( v ) {
 		negativeVector3( v ) {
 
 
 			var v2 = this.allocVector3();
 			var v2 = this.allocVector3();
@@ -601,7 +554,6 @@
 			return v2;
 			return v2;
 
 
 		}
 		}
-
 		multiplyMatrix3ByVector3( m, v ) {
 		multiplyMatrix3ByVector3( m, v ) {
 
 
 			var v4 = this.allocVector3();
 			var v4 = this.allocVector3();
@@ -618,7 +570,6 @@
 			return v4;
 			return v4;
 
 
 		}
 		}
-
 		transposeMatrix3( m ) {
 		transposeMatrix3( m ) {
 
 
 			var m2 = [];
 			var m2 = [];
@@ -634,7 +585,6 @@
 			return m2;
 			return m2;
 
 
 		}
 		}
-
 		quaternionToMatrix3( q ) {
 		quaternionToMatrix3( q ) {
 
 
 			var m = [];
 			var m = [];
@@ -663,12 +613,10 @@
 			return m;
 			return m;
 
 
 		}
 		}
-
 		matrix3ToQuaternion( m ) {
 		matrix3ToQuaternion( m ) {
 
 
 			var t = m[ 0 ] + m[ 4 ] + m[ 8 ];
 			var t = m[ 0 ] + m[ 4 ] + m[ 8 ];
 			var s, x, y, z, w;
 			var s, x, y, z, w;
-
 			if ( t > 0 ) {
 			if ( t > 0 ) {
 
 
 				s = Math.sqrt( t + 1.0 ) * 2;
 				s = Math.sqrt( t + 1.0 ) * 2;
@@ -713,14 +661,13 @@
 		}
 		}
 
 
 	}
 	}
+
 	/**
 	/**
  * @param {THREE.SkinnedMesh} mesh
  * @param {THREE.SkinnedMesh} mesh
  * @param {Ammo.btDiscreteDynamicsWorld} world
  * @param {Ammo.btDiscreteDynamicsWorld} world
  * @param {Object} params
  * @param {Object} params
  * @param {ResourceManager} manager
  * @param {ResourceManager} manager
  */
  */
-
-
 	class RigidBody {
 	class RigidBody {
 
 
 		constructor( mesh, world, params, manager ) {
 		constructor( mesh, world, params, manager ) {
@@ -733,31 +680,27 @@
 			this.bone = null;
 			this.bone = null;
 			this.boneOffsetForm = null;
 			this.boneOffsetForm = null;
 			this.boneOffsetFormInverse = null;
 			this.boneOffsetFormInverse = null;
-
 			this._init();
 			this._init();
 
 
 		}
 		}
+
 		/**
 		/**
    * Resets rigid body transform to the current bone's.
    * Resets rigid body transform to the current bone's.
    *
    *
    * @return {RigidBody}
    * @return {RigidBody}
    */
    */
-
-
 		reset() {
 		reset() {
 
 
 			this._setTransformFromBone();
 			this._setTransformFromBone();
-
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Updates rigid body's transform from the current bone.
    * Updates rigid body's transform from the current bone.
    *
    *
    * @return {RidigBody}
    * @return {RidigBody}
    */
    */
-
-
 		updateFromBone() {
 		updateFromBone() {
 
 
 			if ( this.params.boneIndex !== - 1 && this.params.type === 0 ) {
 			if ( this.params.boneIndex !== - 1 && this.params.type === 0 ) {
@@ -769,13 +712,12 @@
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Updates bone from the current ridid body's transform.
    * Updates bone from the current ridid body's transform.
    *
    *
    * @return {RidigBody}
    * @return {RidigBody}
    */
    */
-
-
 		updateBone() {
 		updateBone() {
 
 
 			if ( this.params.type === 0 || this.params.boneIndex === - 1 ) {
 			if ( this.params.type === 0 || this.params.boneIndex === - 1 ) {
@@ -785,7 +727,6 @@
 			}
 			}
 
 
 			this._updateBoneRotation();
 			this._updateBoneRotation();
-
 			if ( this.params.type === 1 ) {
 			if ( this.params.type === 1 ) {
 
 
 				this._updateBonePosition();
 				this._updateBonePosition();
@@ -793,7 +734,6 @@
 			}
 			}
 
 
 			this.bone.updateMatrixWorld( true );
 			this.bone.updateMatrixWorld( true );
-
 			if ( this.params.type === 2 ) {
 			if ( this.params.type === 2 ) {
 
 
 				this._setPositionFromBone();
 				this._setPositionFromBone();
@@ -802,8 +742,9 @@
 
 
 			return this;
 			return this;
 
 
-		} // private methods
+		}
 
 
+		// private methods
 
 
 		_init() {
 		_init() {
 
 
@@ -813,13 +754,10 @@
 
 
 					case 0:
 					case 0:
 						return new Ammo.btSphereShape( p.width );
 						return new Ammo.btSphereShape( p.width );
-
 					case 1:
 					case 1:
 						return new Ammo.btBoxShape( new Ammo.btVector3( p.width, p.height, p.depth ) );
 						return new Ammo.btBoxShape( new Ammo.btVector3( p.width, p.height, p.depth ) );
-
 					case 2:
 					case 2:
 						return new Ammo.btCapsuleShape( p.width, p.height );
 						return new Ammo.btCapsuleShape( p.width, p.height );
-
 					default:
 					default:
 						throw new Error( 'unknown shape type ' + p.shapeType );
 						throw new Error( 'unknown shape type ' + p.shapeType );
 
 
@@ -835,7 +773,6 @@
 			const weight = params.type === 0 ? 0 : params.weight;
 			const weight = params.type === 0 ? 0 : params.weight;
 			const localInertia = manager.allocVector3();
 			const localInertia = manager.allocVector3();
 			localInertia.setValue( 0, 0, 0 );
 			localInertia.setValue( 0, 0, 0 );
-
 			if ( weight !== 0 ) {
 			if ( weight !== 0 ) {
 
 
 				shape.calculateLocalInertia( weight, localInertia );
 				shape.calculateLocalInertia( weight, localInertia );
@@ -856,16 +793,15 @@
 			info.set_m_friction( params.friction );
 			info.set_m_friction( params.friction );
 			info.set_m_restitution( params.restitution );
 			info.set_m_restitution( params.restitution );
 			const body = new Ammo.btRigidBody( info );
 			const body = new Ammo.btRigidBody( info );
-
 			if ( params.type === 0 ) {
 			if ( params.type === 0 ) {
 
 
 				body.setCollisionFlags( body.getCollisionFlags() | 2 );
 				body.setCollisionFlags( body.getCollisionFlags() | 2 );
+
 				/*
 				/*
        * It'd be better to comment out this line though in general I should call this method
        * It'd be better to comment out this line though in general I should call this method
        * because I'm not sure why but physics will be more like MMD's
        * because I'm not sure why but physics will be more like MMD's
        * if I comment out.
        * if I comment out.
        */
        */
-
 				body.setActivationState( 4 );
 				body.setActivationState( 4 );
 
 
 			}
 			}
@@ -883,7 +819,6 @@
 			manager.freeThreeVector3( vector );
 			manager.freeThreeVector3( vector );
 
 
 		}
 		}
-
 		_getBoneTransform() {
 		_getBoneTransform() {
 
 
 			const manager = this.manager;
 			const manager = this.manager;
@@ -902,7 +837,6 @@
 			return form;
 			return form;
 
 
 		}
 		}
-
 		_getWorldTransformForBone() {
 		_getWorldTransformForBone() {
 
 
 			const manager = this.manager;
 			const manager = this.manager;
@@ -910,45 +844,38 @@
 			return manager.multiplyTransforms( tr, this.boneOffsetFormInverse );
 			return manager.multiplyTransforms( tr, this.boneOffsetFormInverse );
 
 
 		}
 		}
-
 		_setTransformFromBone() {
 		_setTransformFromBone() {
 
 
 			const manager = this.manager;
 			const manager = this.manager;
+			const form = this._getBoneTransform();
 
 
-			const form = this._getBoneTransform(); // TODO: check the most appropriate way to set
+			// TODO: check the most appropriate way to set
 			//this.body.setWorldTransform( form );
 			//this.body.setWorldTransform( form );
-
-
 			this.body.setCenterOfMassTransform( form );
 			this.body.setCenterOfMassTransform( form );
 			this.body.getMotionState().setWorldTransform( form );
 			this.body.getMotionState().setWorldTransform( form );
 			manager.freeTransform( form );
 			manager.freeTransform( form );
 
 
 		}
 		}
-
 		_setPositionFromBone() {
 		_setPositionFromBone() {
 
 
 			const manager = this.manager;
 			const manager = this.manager;
-
 			const form = this._getBoneTransform();
 			const form = this._getBoneTransform();
-
 			const tr = manager.allocTransform();
 			const tr = manager.allocTransform();
 			this.body.getMotionState().getWorldTransform( tr );
 			this.body.getMotionState().getWorldTransform( tr );
-			manager.copyOrigin( tr, form ); // TODO: check the most appropriate way to set
-			//this.body.setWorldTransform( tr );
+			manager.copyOrigin( tr, form );
 
 
+			// TODO: check the most appropriate way to set
+			//this.body.setWorldTransform( tr );
 			this.body.setCenterOfMassTransform( tr );
 			this.body.setCenterOfMassTransform( tr );
 			this.body.getMotionState().setWorldTransform( tr );
 			this.body.getMotionState().setWorldTransform( tr );
 			manager.freeTransform( tr );
 			manager.freeTransform( tr );
 			manager.freeTransform( form );
 			manager.freeTransform( form );
 
 
 		}
 		}
-
 		_updateBoneRotation() {
 		_updateBoneRotation() {
 
 
 			const manager = this.manager;
 			const manager = this.manager;
-
 			const tr = this._getWorldTransformForBone();
 			const tr = this._getWorldTransformForBone();
-
 			const q = manager.getBasis( tr );
 			const q = manager.getBasis( tr );
 			const thQ = manager.allocThreeQuaternion();
 			const thQ = manager.allocThreeQuaternion();
 			const thQ2 = manager.allocThreeQuaternion();
 			const thQ2 = manager.allocThreeQuaternion();
@@ -956,12 +883,15 @@
 			thQ.set( q.x(), q.y(), q.z(), q.w() );
 			thQ.set( q.x(), q.y(), q.z(), q.w() );
 			thQ2.setFromRotationMatrix( this.bone.matrixWorld );
 			thQ2.setFromRotationMatrix( this.bone.matrixWorld );
 			thQ2.conjugate();
 			thQ2.conjugate();
-			thQ2.multiply( thQ ); //this.bone.quaternion.multiply( thQ2 );
+			thQ2.multiply( thQ );
+
+			//this.bone.quaternion.multiply( thQ2 );
+
+			thQ3.setFromRotationMatrix( this.bone.matrix );
 
 
-			thQ3.setFromRotationMatrix( this.bone.matrix ); // Renormalizing quaternion here because repeatedly transforming
+			// Renormalizing quaternion here because repeatedly transforming
 			// quaternion continuously accumulates floating point error and
 			// quaternion continuously accumulates floating point error and
 			// can end up being overflow. See #15335
 			// can end up being overflow. See #15335
-
 			this.bone.quaternion.copy( thQ2.multiply( thQ3 ).normalize() );
 			this.bone.quaternion.copy( thQ2.multiply( thQ3 ).normalize() );
 			manager.freeThreeQuaternion( thQ );
 			manager.freeThreeQuaternion( thQ );
 			manager.freeThreeQuaternion( thQ2 );
 			manager.freeThreeQuaternion( thQ2 );
@@ -970,17 +900,13 @@
 			manager.freeTransform( tr );
 			manager.freeTransform( tr );
 
 
 		}
 		}
-
 		_updateBonePosition() {
 		_updateBonePosition() {
 
 
 			const manager = this.manager;
 			const manager = this.manager;
-
 			const tr = this._getWorldTransformForBone();
 			const tr = this._getWorldTransformForBone();
-
 			const thV = manager.allocThreeVector3();
 			const thV = manager.allocThreeVector3();
 			const o = manager.getOrigin( tr );
 			const o = manager.getOrigin( tr );
 			thV.set( o.x(), o.y(), o.z() );
 			thV.set( o.x(), o.y(), o.z() );
-
 			if ( this.bone.parent ) {
 			if ( this.bone.parent ) {
 
 
 				this.bone.parent.worldToLocal( thV );
 				this.bone.parent.worldToLocal( thV );
@@ -993,8 +919,9 @@
 
 
 		}
 		}
 
 
-	} //
+	}
 
 
+	//
 
 
 	class Constraint {
 	class Constraint {
 
 
@@ -1015,11 +942,11 @@
 			this.params = params;
 			this.params = params;
 			this.manager = manager;
 			this.manager = manager;
 			this.constraint = null;
 			this.constraint = null;
-
 			this._init();
 			this._init();
 
 
-		} // private method
+		}
 
 
+		// private method
 
 
 		_init() {
 		_init() {
 
 
@@ -1052,7 +979,6 @@
 			constraint.setLinearUpperLimit( lul );
 			constraint.setLinearUpperLimit( lul );
 			constraint.setAngularLowerLimit( all );
 			constraint.setAngularLowerLimit( all );
 			constraint.setAngularUpperLimit( aul );
 			constraint.setAngularUpperLimit( aul );
-
 			for ( let i = 0; i < 3; i ++ ) {
 			for ( let i = 0; i < 3; i ++ ) {
 
 
 				if ( params.springPosition[ i ] !== 0 ) {
 				if ( params.springPosition[ i ] !== 0 ) {
@@ -1074,14 +1000,13 @@
 				}
 				}
 
 
 			}
 			}
+
 			/*
 			/*
      * Currently(10/31/2016) official ammo.js doesn't support
      * Currently(10/31/2016) official ammo.js doesn't support
      * btGeneric6DofSpringConstraint.setParam method.
      * btGeneric6DofSpringConstraint.setParam method.
      * You need custom ammo.js (add the method into idl) if you wanna use.
      * You need custom ammo.js (add the method into idl) if you wanna use.
      * By setting this parameter, physics will be more like MMD's
      * By setting this parameter, physics will be more like MMD's
      */
      */
-
-
 			if ( constraint.setParam !== undefined ) {
 			if ( constraint.setParam !== undefined ) {
 
 
 				for ( let i = 0; i < 6; i ++ ) {
 				for ( let i = 0; i < 6; i ++ ) {
@@ -1108,17 +1033,14 @@
 
 
 		}
 		}
 
 
-	} //
+	}
 
 
+	//
 
 
 	const _position = new THREE.Vector3();
 	const _position = new THREE.Vector3();
-
 	const _quaternion = new THREE.Quaternion();
 	const _quaternion = new THREE.Quaternion();
-
 	const _scale = new THREE.Vector3();
 	const _scale = new THREE.Vector3();
-
 	const _matrixWorldInv = new THREE.Matrix4();
 	const _matrixWorldInv = new THREE.Matrix4();
-
 	class MMDPhysicsHelper extends THREE.Object3D {
 	class MMDPhysicsHelper extends THREE.Object3D {
 
 
 		/**
 		/**
@@ -1159,20 +1081,17 @@
 				opacity: 0.25,
 				opacity: 0.25,
 				transparent: true
 				transparent: true
 			} ) );
 			} ) );
-
 			this._init();
 			this._init();
 
 
 		}
 		}
+
 		/**
 		/**
    * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.
    * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.
    */
    */
-
-
 		dispose() {
 		dispose() {
 
 
 			const materials = this.materials;
 			const materials = this.materials;
 			const children = this.children;
 			const children = this.children;
-
 			for ( let i = 0; i < materials.length; i ++ ) {
 			for ( let i = 0; i < materials.length; i ++ ) {
 
 
 				materials[ i ].dispose();
 				materials[ i ].dispose();
@@ -1187,21 +1106,17 @@
 			}
 			}
 
 
 		}
 		}
+
 		/**
 		/**
    * Updates Rigid Bodies visualization.
    * Updates Rigid Bodies visualization.
    */
    */
-
-
 		updateMatrixWorld( force ) {
 		updateMatrixWorld( force ) {
 
 
 			var mesh = this.root;
 			var mesh = this.root;
-
 			if ( this.visible ) {
 			if ( this.visible ) {
 
 
 				var bodies = this.physics.bodies;
 				var bodies = this.physics.bodies;
-
 				_matrixWorldInv.copy( mesh.matrixWorld ).decompose( _position, _quaternion, _scale ).compose( _position, _quaternion, _scale.set( 1, 1, 1 ) ).invert();
 				_matrixWorldInv.copy( mesh.matrixWorld ).decompose( _position, _quaternion, _scale ).compose( _position, _quaternion, _scale.set( 1, 1, 1 ) ).invert();
-
 				for ( var i = 0, il = bodies.length; i < il; i ++ ) {
 				for ( var i = 0, il = bodies.length; i < il; i ++ ) {
 
 
 					var body = bodies[ i ].body;
 					var body = bodies[ i ].body;
@@ -1219,26 +1134,23 @@
 			this.matrix.copy( mesh.matrixWorld ).decompose( _position, _quaternion, _scale ).compose( _position, _quaternion, _scale.set( 1, 1, 1 ) );
 			this.matrix.copy( mesh.matrixWorld ).decompose( _position, _quaternion, _scale ).compose( _position, _quaternion, _scale.set( 1, 1, 1 ) );
 			super.updateMatrixWorld( force );
 			super.updateMatrixWorld( force );
 
 
-		} // private method
+		}
 
 
+		// private method
 
 
 		_init() {
 		_init() {
 
 
 			var bodies = this.physics.bodies;
 			var bodies = this.physics.bodies;
-
 			function createGeometry( param ) {
 			function createGeometry( param ) {
 
 
 				switch ( param.shapeType ) {
 				switch ( param.shapeType ) {
 
 
 					case 0:
 					case 0:
 						return new THREE.SphereGeometry( param.width, 16, 8 );
 						return new THREE.SphereGeometry( param.width, 16, 8 );
-
 					case 1:
 					case 1:
 						return new THREE.BoxGeometry( param.width * 2, param.height * 2, param.depth * 2, 8, 8, 8 );
 						return new THREE.BoxGeometry( param.width * 2, param.height * 2, param.depth * 2, 8, 8, 8 );
-
 					case 2:
 					case 2:
 						return new THREE.CapsuleGeometry( param.width, param.height, 8, 16 );
 						return new THREE.CapsuleGeometry( param.width, param.height, 8, 16 );
-
 					default:
 					default:
 						return null;
 						return null;
 
 

+ 33 - 22
examples/js/cameras/CinematicCamera.js

@@ -20,29 +20,31 @@
 				fragmentShader: depthShader.fragmentShader
 				fragmentShader: depthShader.fragmentShader
 			} );
 			} );
 			this.materialDepth.uniforms[ 'mNear' ].value = near;
 			this.materialDepth.uniforms[ 'mNear' ].value = near;
-			this.materialDepth.uniforms[ 'mFar' ].value = far; // In case of cinematicCamera, having a default lens set is important
+			this.materialDepth.uniforms[ 'mFar' ].value = far;
 
 
+			// In case of cinematicCamera, having a default lens set is important
 			this.setLens();
 			this.setLens();
 			this.initPostProcessing();
 			this.initPostProcessing();
 
 
-		} // providing fnumber and coc(Circle of Confusion) as extra arguments
+		}
+
+		// providing fnumber and coc(Circle of Confusion) as extra arguments
 		// In case of cinematicCamera, having a default lens set is important
 		// In case of cinematicCamera, having a default lens set is important
 		// if fnumber and coc are not provided, cinematicCamera tries to act as a basic THREE.PerspectiveCamera
 		// if fnumber and coc are not provided, cinematicCamera tries to act as a basic THREE.PerspectiveCamera
-
-
 		setLens( focalLength = 35, filmGauge = 35, fNumber = 8, coc = 0.019 ) {
 		setLens( focalLength = 35, filmGauge = 35, fNumber = 8, coc = 0.019 ) {
 
 
 			this.filmGauge = filmGauge;
 			this.filmGauge = filmGauge;
 			this.setFocalLength( focalLength );
 			this.setFocalLength( focalLength );
 			this.fNumber = fNumber;
 			this.fNumber = fNumber;
-			this.coc = coc; // fNumber is focalLength by aperture
+			this.coc = coc;
 
 
-			this.aperture = focalLength / this.fNumber; // hyperFocal is required to calculate depthOfField when a lens tries to focus at a distance with given fNumber and focalLength
+			// fNumber is focalLength by aperture
+			this.aperture = focalLength / this.fNumber;
 
 
+			// hyperFocal is required to calculate depthOfField when a lens tries to focus at a distance with given fNumber and focalLength
 			this.hyperFocal = focalLength * focalLength / ( this.aperture * this.coc );
 			this.hyperFocal = focalLength * focalLength / ( this.aperture * this.coc );
 
 
 		}
 		}
-
 		linearize( depth ) {
 		linearize( depth ) {
 
 
 			const zfar = this.far;
 			const zfar = this.far;
@@ -50,40 +52,42 @@
 			return - zfar * znear / ( depth * ( zfar - znear ) - zfar );
 			return - zfar * znear / ( depth * ( zfar - znear ) - zfar );
 
 
 		}
 		}
-
 		smoothstep( near, far, depth ) {
 		smoothstep( near, far, depth ) {
 
 
 			const x = this.saturate( ( depth - near ) / ( far - near ) );
 			const x = this.saturate( ( depth - near ) / ( far - near ) );
 			return x * x * ( 3 - 2 * x );
 			return x * x * ( 3 - 2 * x );
 
 
 		}
 		}
-
 		saturate( x ) {
 		saturate( x ) {
 
 
 			return Math.max( 0, Math.min( 1, x ) );
 			return Math.max( 0, Math.min( 1, x ) );
 
 
-		} // function for focusing at a distance from the camera
-
+		}
 
 
+		// function for focusing at a distance from the camera
 		focusAt( focusDistance = 20 ) {
 		focusAt( focusDistance = 20 ) {
 
 
-			const focalLength = this.getFocalLength(); // distance from the camera (normal to frustrum) to focus on
+			const focalLength = this.getFocalLength();
 
 
-			this.focus = focusDistance; // the nearest point from the camera which is in focus (unused)
+			// distance from the camera (normal to frustrum) to focus on
+			this.focus = focusDistance;
 
 
-			this.nearPoint = this.hyperFocal * this.focus / ( this.hyperFocal + ( this.focus - focalLength ) ); // the farthest point from the camera which is in focus (unused)
+			// the nearest point from the camera which is in focus (unused)
+			this.nearPoint = this.hyperFocal * this.focus / ( this.hyperFocal + ( this.focus - focalLength ) );
 
 
-			this.farPoint = this.hyperFocal * this.focus / ( this.hyperFocal - ( this.focus - focalLength ) ); // the gap or width of the space in which is everything is in focus (unused)
+			// the farthest point from the camera which is in focus (unused)
+			this.farPoint = this.hyperFocal * this.focus / ( this.hyperFocal - ( this.focus - focalLength ) );
 
 
-			this.depthOfField = this.farPoint - this.nearPoint; // Considering minimum distance of focus for a standard lens (unused)
+			// the gap or width of the space in which is everything is in focus (unused)
+			this.depthOfField = this.farPoint - this.nearPoint;
 
 
+			// Considering minimum distance of focus for a standard lens (unused)
 			if ( this.depthOfField < 0 ) this.depthOfField = 0;
 			if ( this.depthOfField < 0 ) this.depthOfField = 0;
 			this.sdistance = this.smoothstep( this.near, this.far, this.focus );
 			this.sdistance = this.smoothstep( this.near, this.far, this.focus );
 			this.ldistance = this.linearize( 1 - this.sdistance );
 			this.ldistance = this.linearize( 1 - this.sdistance );
 			this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = this.ldistance;
 			this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = this.ldistance;
 
 
 		}
 		}
-
 		initPostProcessing() {
 		initPostProcessing() {
 
 
 			if ( this.postprocessing.enabled ) {
 			if ( this.postprocessing.enabled ) {
@@ -101,7 +105,9 @@
 				this.postprocessing.bokeh_uniforms[ 'shaderFocus' ].value = 0;
 				this.postprocessing.bokeh_uniforms[ 'shaderFocus' ].value = 0;
 				this.postprocessing.bokeh_uniforms[ 'fstop' ].value = 2.8;
 				this.postprocessing.bokeh_uniforms[ 'fstop' ].value = 2.8;
 				this.postprocessing.bokeh_uniforms[ 'showFocus' ].value = 1;
 				this.postprocessing.bokeh_uniforms[ 'showFocus' ].value = 1;
-				this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = 0.1; //console.log( this.postprocessing.bokeh_uniforms[ "focalDepth" ].value );
+				this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = 0.1;
+
+				//console.log( this.postprocessing.bokeh_uniforms[ "focalDepth" ].value );
 
 
 				this.postprocessing.bokeh_uniforms[ 'znear' ].value = this.near;
 				this.postprocessing.bokeh_uniforms[ 'znear' ].value = this.near;
 				this.postprocessing.bokeh_uniforms[ 'zfar' ].value = this.near;
 				this.postprocessing.bokeh_uniforms[ 'zfar' ].value = this.near;
@@ -124,23 +130,28 @@
 			}
 			}
 
 
 		}
 		}
-
 		renderCinematic( scene, renderer ) {
 		renderCinematic( scene, renderer ) {
 
 
 			if ( this.postprocessing.enabled ) {
 			if ( this.postprocessing.enabled ) {
 
 
 				const currentRenderTarget = renderer.getRenderTarget();
 				const currentRenderTarget = renderer.getRenderTarget();
-				renderer.clear(); // Render scene into texture
+				renderer.clear();
+
+				// Render scene into texture
 
 
 				scene.overrideMaterial = null;
 				scene.overrideMaterial = null;
 				renderer.setRenderTarget( this.postprocessing.rtTextureColor );
 				renderer.setRenderTarget( this.postprocessing.rtTextureColor );
 				renderer.clear();
 				renderer.clear();
-				renderer.render( scene, this ); // Render depth into texture
+				renderer.render( scene, this );
+
+				// Render depth into texture
 
 
 				scene.overrideMaterial = this.materialDepth;
 				scene.overrideMaterial = this.materialDepth;
 				renderer.setRenderTarget( this.postprocessing.rtTextureDepth );
 				renderer.setRenderTarget( this.postprocessing.rtTextureDepth );
 				renderer.clear();
 				renderer.clear();
-				renderer.render( scene, this ); // Render bokeh composite
+				renderer.render( scene, this );
+
+				// Render bokeh composite
 
 
 				renderer.setRenderTarget( null );
 				renderer.setRenderTarget( null );
 				renderer.render( this.postprocessing.scene, this.postprocessing.camera );
 				renderer.render( this.postprocessing.scene, this.postprocessing.camera );

文件差異過大導致無法顯示
+ 55 - 183
examples/js/controls/ArcballControls.js


+ 8 - 33
examples/js/controls/DragControls.js

@@ -1,19 +1,12 @@
 ( function () {
 ( function () {
 
 
 	const _plane = new THREE.Plane();
 	const _plane = new THREE.Plane();
-
 	const _raycaster = new THREE.Raycaster();
 	const _raycaster = new THREE.Raycaster();
-
 	const _pointer = new THREE.Vector2();
 	const _pointer = new THREE.Vector2();
-
 	const _offset = new THREE.Vector3();
 	const _offset = new THREE.Vector3();
-
 	const _intersection = new THREE.Vector3();
 	const _intersection = new THREE.Vector3();
-
 	const _worldPosition = new THREE.Vector3();
 	const _worldPosition = new THREE.Vector3();
-
 	const _inverseMatrix = new THREE.Matrix4();
 	const _inverseMatrix = new THREE.Matrix4();
-
 	class DragControls extends THREE.EventDispatcher {
 	class DragControls extends THREE.EventDispatcher {
 
 
 		constructor( _objects, _camera, _domElement ) {
 		constructor( _objects, _camera, _domElement ) {
@@ -23,18 +16,16 @@
 
 
 			let _selected = null,
 			let _selected = null,
 				_hovered = null;
 				_hovered = null;
-			const _intersections = []; //
+			const _intersections = [];
 
 
-			const scope = this;
+			//
 
 
+			const scope = this;
 			function activate() {
 			function activate() {
 
 
 				_domElement.addEventListener( 'pointermove', onPointerMove );
 				_domElement.addEventListener( 'pointermove', onPointerMove );
-
 				_domElement.addEventListener( 'pointerdown', onPointerDown );
 				_domElement.addEventListener( 'pointerdown', onPointerDown );
-
 				_domElement.addEventListener( 'pointerup', onPointerCancel );
 				_domElement.addEventListener( 'pointerup', onPointerCancel );
-
 				_domElement.addEventListener( 'pointerleave', onPointerCancel );
 				_domElement.addEventListener( 'pointerleave', onPointerCancel );
 
 
 			}
 			}
@@ -42,13 +33,9 @@
 			function deactivate() {
 			function deactivate() {
 
 
 				_domElement.removeEventListener( 'pointermove', onPointerMove );
 				_domElement.removeEventListener( 'pointermove', onPointerMove );
-
 				_domElement.removeEventListener( 'pointerdown', onPointerDown );
 				_domElement.removeEventListener( 'pointerdown', onPointerDown );
-
 				_domElement.removeEventListener( 'pointerup', onPointerCancel );
 				_domElement.removeEventListener( 'pointerup', onPointerCancel );
-
 				_domElement.removeEventListener( 'pointerleave', onPointerCancel );
 				_domElement.removeEventListener( 'pointerleave', onPointerCancel );
-
 				_domElement.style.cursor = '';
 				_domElement.style.cursor = '';
 
 
 			}
 			}
@@ -75,9 +62,7 @@
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
 				updatePointer( event );
 				updatePointer( event );
-
 				_raycaster.setFromCamera( _pointer, _camera );
 				_raycaster.setFromCamera( _pointer, _camera );
-
 				if ( _selected ) {
 				if ( _selected ) {
 
 
 					if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 					if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
@@ -92,23 +77,19 @@
 					} );
 					} );
 					return;
 					return;
 
 
-				} // hover support
+				}
 
 
+				// hover support
 
 
 				if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
 				if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
 
 
 					_intersections.length = 0;
 					_intersections.length = 0;
-
 					_raycaster.setFromCamera( _pointer, _camera );
 					_raycaster.setFromCamera( _pointer, _camera );
-
 					_raycaster.intersectObjects( _objects, true, _intersections );
 					_raycaster.intersectObjects( _objects, true, _intersections );
-
 					if ( _intersections.length > 0 ) {
 					if ( _intersections.length > 0 ) {
 
 
 						const object = _intersections[ 0 ].object;
 						const object = _intersections[ 0 ].object;
-
 						_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
 						_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
-
 						if ( _hovered !== object && _hovered !== null ) {
 						if ( _hovered !== object && _hovered !== null ) {
 
 
 							scope.dispatchEvent( {
 							scope.dispatchEvent( {
@@ -155,21 +136,15 @@
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
 				updatePointer( event );
 				updatePointer( event );
 				_intersections.length = 0;
 				_intersections.length = 0;
-
 				_raycaster.setFromCamera( _pointer, _camera );
 				_raycaster.setFromCamera( _pointer, _camera );
-
 				_raycaster.intersectObjects( _objects, true, _intersections );
 				_raycaster.intersectObjects( _objects, true, _intersections );
-
 				if ( _intersections.length > 0 ) {
 				if ( _intersections.length > 0 ) {
 
 
 					_selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object;
 					_selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object;
-
 					_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 					_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
-
 					if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 					if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
 
 						_inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
 						_inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
-
 						_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 						_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 
 
 					}
 					}
@@ -187,7 +162,6 @@
 			function onPointerCancel() {
 			function onPointerCancel() {
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
-
 				if ( _selected ) {
 				if ( _selected ) {
 
 
 					scope.dispatchEvent( {
 					scope.dispatchEvent( {
@@ -205,13 +179,14 @@
 			function updatePointer( event ) {
 			function updatePointer( event ) {
 
 
 				const rect = _domElement.getBoundingClientRect();
 				const rect = _domElement.getBoundingClientRect();
-
 				_pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
 				_pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
 				_pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
 				_pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
 
 
 			}
 			}
 
 
-			activate(); // API
+			activate();
+
+			// API
 
 
 			this.enabled = true;
 			this.enabled = true;
 			this.transformGroup = false;
 			this.transformGroup = false;

+ 12 - 34
examples/js/controls/FirstPersonControls.js

@@ -1,17 +1,16 @@
 ( function () {
 ( function () {
 
 
 	const _lookDirection = new THREE.Vector3();
 	const _lookDirection = new THREE.Vector3();
-
 	const _spherical = new THREE.Spherical();
 	const _spherical = new THREE.Spherical();
-
 	const _target = new THREE.Vector3();
 	const _target = new THREE.Vector3();
-
 	class FirstPersonControls {
 	class FirstPersonControls {
 
 
 		constructor( object, domElement ) {
 		constructor( object, domElement ) {
 
 
 			this.object = object;
 			this.object = object;
-			this.domElement = domElement; // API
+			this.domElement = domElement;
+
+			// API
 
 
 			this.enabled = true;
 			this.enabled = true;
 			this.movementSpeed = 1.0;
 			this.movementSpeed = 1.0;
@@ -26,7 +25,9 @@
 			this.constrainVertical = false;
 			this.constrainVertical = false;
 			this.verticalMin = 0;
 			this.verticalMin = 0;
 			this.verticalMax = Math.PI;
 			this.verticalMax = Math.PI;
-			this.mouseDragOn = false; // internals
+			this.mouseDragOn = false;
+
+			// internals
 
 
 			this.autoSpeedFactor = 0.0;
 			this.autoSpeedFactor = 0.0;
 			this.pointerX = 0;
 			this.pointerX = 0;
@@ -36,10 +37,14 @@
 			this.moveLeft = false;
 			this.moveLeft = false;
 			this.moveRight = false;
 			this.moveRight = false;
 			this.viewHalfX = 0;
 			this.viewHalfX = 0;
-			this.viewHalfY = 0; // private variables
+			this.viewHalfY = 0;
+
+			// private variables
 
 
 			let lat = 0;
 			let lat = 0;
-			let lon = 0; //
+			let lon = 0;
+
+			//
 
 
 			this.handleResize = function () {
 			this.handleResize = function () {
 
 
@@ -72,7 +77,6 @@
 						case 0:
 						case 0:
 							this.moveForward = true;
 							this.moveForward = true;
 							break;
 							break;
-
 						case 2:
 						case 2:
 							this.moveBackward = true;
 							this.moveBackward = true;
 							break;
 							break;
@@ -94,7 +98,6 @@
 						case 0:
 						case 0:
 							this.moveForward = false;
 							this.moveForward = false;
 							break;
 							break;
-
 						case 2:
 						case 2:
 							this.moveBackward = false;
 							this.moveBackward = false;
 							break;
 							break;
@@ -131,26 +134,21 @@
 					case 'KeyW':
 					case 'KeyW':
 						this.moveForward = true;
 						this.moveForward = true;
 						break;
 						break;
-
 					case 'ArrowLeft':
 					case 'ArrowLeft':
 					case 'KeyA':
 					case 'KeyA':
 						this.moveLeft = true;
 						this.moveLeft = true;
 						break;
 						break;
-
 					case 'ArrowDown':
 					case 'ArrowDown':
 					case 'KeyS':
 					case 'KeyS':
 						this.moveBackward = true;
 						this.moveBackward = true;
 						break;
 						break;
-
 					case 'ArrowRight':
 					case 'ArrowRight':
 					case 'KeyD':
 					case 'KeyD':
 						this.moveRight = true;
 						this.moveRight = true;
 						break;
 						break;
-
 					case 'KeyR':
 					case 'KeyR':
 						this.moveUp = true;
 						this.moveUp = true;
 						break;
 						break;
-
 					case 'KeyF':
 					case 'KeyF':
 						this.moveDown = true;
 						this.moveDown = true;
 						break;
 						break;
@@ -167,26 +165,21 @@
 					case 'KeyW':
 					case 'KeyW':
 						this.moveForward = false;
 						this.moveForward = false;
 						break;
 						break;
-
 					case 'ArrowLeft':
 					case 'ArrowLeft':
 					case 'KeyA':
 					case 'KeyA':
 						this.moveLeft = false;
 						this.moveLeft = false;
 						break;
 						break;
-
 					case 'ArrowDown':
 					case 'ArrowDown':
 					case 'KeyS':
 					case 'KeyS':
 						this.moveBackward = false;
 						this.moveBackward = false;
 						break;
 						break;
-
 					case 'ArrowRight':
 					case 'ArrowRight':
 					case 'KeyD':
 					case 'KeyD':
 						this.moveRight = false;
 						this.moveRight = false;
 						break;
 						break;
-
 					case 'KeyR':
 					case 'KeyR':
 						this.moveUp = false;
 						this.moveUp = false;
 						break;
 						break;
-
 					case 'KeyF':
 					case 'KeyF':
 						this.moveDown = false;
 						this.moveDown = false;
 						break;
 						break;
@@ -219,7 +212,6 @@
 				return function update( delta ) {
 				return function update( delta ) {
 
 
 					if ( this.enabled === false ) return;
 					if ( this.enabled === false ) return;
-
 					if ( this.heightSpeed ) {
 					if ( this.heightSpeed ) {
 
 
 						const y = THREE.MathUtils.clamp( this.object.position.y, this.heightMin, this.heightMax );
 						const y = THREE.MathUtils.clamp( this.object.position.y, this.heightMin, this.heightMax );
@@ -240,7 +232,6 @@
 					if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
 					if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
 					if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
 					if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
 					let actualLookSpeed = delta * this.lookSpeed;
 					let actualLookSpeed = delta * this.lookSpeed;
-
 					if ( ! this.activeLook ) {
 					if ( ! this.activeLook ) {
 
 
 						actualLookSpeed = 0;
 						actualLookSpeed = 0;
@@ -248,7 +239,6 @@
 					}
 					}
 
 
 					let verticalLookRatio = 1;
 					let verticalLookRatio = 1;
-
 					if ( this.constrainVertical ) {
 					if ( this.constrainVertical ) {
 
 
 						verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
 						verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
@@ -260,7 +250,6 @@
 					lat = Math.max( - 85, Math.min( 85, lat ) );
 					lat = Math.max( - 85, Math.min( 85, lat ) );
 					let phi = THREE.MathUtils.degToRad( 90 - lat );
 					let phi = THREE.MathUtils.degToRad( 90 - lat );
 					const theta = THREE.MathUtils.degToRad( lon );
 					const theta = THREE.MathUtils.degToRad( lon );
-
 					if ( this.constrainVertical ) {
 					if ( this.constrainVertical ) {
 
 
 						phi = THREE.MathUtils.mapLinear( phi, 0, Math.PI, this.verticalMin, this.verticalMax );
 						phi = THREE.MathUtils.mapLinear( phi, 0, Math.PI, this.verticalMin, this.verticalMax );
@@ -274,7 +263,6 @@
 				};
 				};
 
 
 			}();
 			}();
-
 			this.dispose = function () {
 			this.dispose = function () {
 
 
 				this.domElement.removeEventListener( 'contextmenu', contextmenu );
 				this.domElement.removeEventListener( 'contextmenu', contextmenu );
@@ -287,30 +275,21 @@
 			};
 			};
 
 
 			const _onPointerMove = this.onPointerMove.bind( this );
 			const _onPointerMove = this.onPointerMove.bind( this );
-
 			const _onPointerDown = this.onPointerDown.bind( this );
 			const _onPointerDown = this.onPointerDown.bind( this );
-
 			const _onPointerUp = this.onPointerUp.bind( this );
 			const _onPointerUp = this.onPointerUp.bind( this );
-
 			const _onKeyDown = this.onKeyDown.bind( this );
 			const _onKeyDown = this.onKeyDown.bind( this );
-
 			const _onKeyUp = this.onKeyUp.bind( this );
 			const _onKeyUp = this.onKeyUp.bind( this );
-
 			this.domElement.addEventListener( 'contextmenu', contextmenu );
 			this.domElement.addEventListener( 'contextmenu', contextmenu );
 			this.domElement.addEventListener( 'pointerdown', _onPointerDown );
 			this.domElement.addEventListener( 'pointerdown', _onPointerDown );
 			this.domElement.addEventListener( 'pointermove', _onPointerMove );
 			this.domElement.addEventListener( 'pointermove', _onPointerMove );
 			this.domElement.addEventListener( 'pointerup', _onPointerUp );
 			this.domElement.addEventListener( 'pointerup', _onPointerUp );
 			window.addEventListener( 'keydown', _onKeyDown );
 			window.addEventListener( 'keydown', _onKeyDown );
 			window.addEventListener( 'keyup', _onKeyUp );
 			window.addEventListener( 'keyup', _onKeyUp );
-
 			function setOrientation( controls ) {
 			function setOrientation( controls ) {
 
 
 				const quaternion = controls.object.quaternion;
 				const quaternion = controls.object.quaternion;
-
 				_lookDirection.set( 0, 0, - 1 ).applyQuaternion( quaternion );
 				_lookDirection.set( 0, 0, - 1 ).applyQuaternion( quaternion );
-
 				_spherical.setFromVector3( _lookDirection );
 				_spherical.setFromVector3( _lookDirection );
-
 				lat = 90 - THREE.MathUtils.radToDeg( _spherical.phi );
 				lat = 90 - THREE.MathUtils.radToDeg( _spherical.phi );
 				lon = THREE.MathUtils.radToDeg( _spherical.theta );
 				lon = THREE.MathUtils.radToDeg( _spherical.theta );
 
 
@@ -322,7 +301,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function contextmenu( event ) {
 	function contextmenu( event ) {
 
 
 		event.preventDefault();
 		event.preventDefault();

+ 13 - 39
examples/js/controls/FlyControls.js

@@ -3,19 +3,23 @@
 	const _changeEvent = {
 	const _changeEvent = {
 		type: 'change'
 		type: 'change'
 	};
 	};
-
 	class FlyControls extends THREE.EventDispatcher {
 	class FlyControls extends THREE.EventDispatcher {
 
 
 		constructor( object, domElement ) {
 		constructor( object, domElement ) {
 
 
 			super();
 			super();
 			this.object = object;
 			this.object = object;
-			this.domElement = domElement; // API
+			this.domElement = domElement;
+
+			// API
 
 
 			this.movementSpeed = 1.0;
 			this.movementSpeed = 1.0;
 			this.rollSpeed = 0.005;
 			this.rollSpeed = 0.005;
 			this.dragToLook = false;
 			this.dragToLook = false;
-			this.autoForward = false; // disable default target object behavior
+			this.autoForward = false;
+
+			// disable default target object behavior
+
 			// internals
 			// internals
 
 
 			const scope = this;
 			const scope = this;
@@ -40,7 +44,6 @@
 			};
 			};
 			this.moveVector = new THREE.Vector3( 0, 0, 0 );
 			this.moveVector = new THREE.Vector3( 0, 0, 0 );
 			this.rotationVector = new THREE.Vector3( 0, 0, 0 );
 			this.rotationVector = new THREE.Vector3( 0, 0, 0 );
-
 			this.keydown = function ( event ) {
 			this.keydown = function ( event ) {
 
 
 				if ( event.altKey ) {
 				if ( event.altKey ) {
@@ -55,51 +58,39 @@
 					case 'ShiftRight':
 					case 'ShiftRight':
 						this.movementSpeedMultiplier = .1;
 						this.movementSpeedMultiplier = .1;
 						break;
 						break;
-
 					case 'KeyW':
 					case 'KeyW':
 						this.moveState.forward = 1;
 						this.moveState.forward = 1;
 						break;
 						break;
-
 					case 'KeyS':
 					case 'KeyS':
 						this.moveState.back = 1;
 						this.moveState.back = 1;
 						break;
 						break;
-
 					case 'KeyA':
 					case 'KeyA':
 						this.moveState.left = 1;
 						this.moveState.left = 1;
 						break;
 						break;
-
 					case 'KeyD':
 					case 'KeyD':
 						this.moveState.right = 1;
 						this.moveState.right = 1;
 						break;
 						break;
-
 					case 'KeyR':
 					case 'KeyR':
 						this.moveState.up = 1;
 						this.moveState.up = 1;
 						break;
 						break;
-
 					case 'KeyF':
 					case 'KeyF':
 						this.moveState.down = 1;
 						this.moveState.down = 1;
 						break;
 						break;
-
 					case 'ArrowUp':
 					case 'ArrowUp':
 						this.moveState.pitchUp = 1;
 						this.moveState.pitchUp = 1;
 						break;
 						break;
-
 					case 'ArrowDown':
 					case 'ArrowDown':
 						this.moveState.pitchDown = 1;
 						this.moveState.pitchDown = 1;
 						break;
 						break;
-
 					case 'ArrowLeft':
 					case 'ArrowLeft':
 						this.moveState.yawLeft = 1;
 						this.moveState.yawLeft = 1;
 						break;
 						break;
-
 					case 'ArrowRight':
 					case 'ArrowRight':
 						this.moveState.yawRight = 1;
 						this.moveState.yawRight = 1;
 						break;
 						break;
-
 					case 'KeyQ':
 					case 'KeyQ':
 						this.moveState.rollLeft = 1;
 						this.moveState.rollLeft = 1;
 						break;
 						break;
-
 					case 'KeyE':
 					case 'KeyE':
 						this.moveState.rollRight = 1;
 						this.moveState.rollRight = 1;
 						break;
 						break;
@@ -119,51 +110,39 @@
 					case 'ShiftRight':
 					case 'ShiftRight':
 						this.movementSpeedMultiplier = 1;
 						this.movementSpeedMultiplier = 1;
 						break;
 						break;
-
 					case 'KeyW':
 					case 'KeyW':
 						this.moveState.forward = 0;
 						this.moveState.forward = 0;
 						break;
 						break;
-
 					case 'KeyS':
 					case 'KeyS':
 						this.moveState.back = 0;
 						this.moveState.back = 0;
 						break;
 						break;
-
 					case 'KeyA':
 					case 'KeyA':
 						this.moveState.left = 0;
 						this.moveState.left = 0;
 						break;
 						break;
-
 					case 'KeyD':
 					case 'KeyD':
 						this.moveState.right = 0;
 						this.moveState.right = 0;
 						break;
 						break;
-
 					case 'KeyR':
 					case 'KeyR':
 						this.moveState.up = 0;
 						this.moveState.up = 0;
 						break;
 						break;
-
 					case 'KeyF':
 					case 'KeyF':
 						this.moveState.down = 0;
 						this.moveState.down = 0;
 						break;
 						break;
-
 					case 'ArrowUp':
 					case 'ArrowUp':
 						this.moveState.pitchUp = 0;
 						this.moveState.pitchUp = 0;
 						break;
 						break;
-
 					case 'ArrowDown':
 					case 'ArrowDown':
 						this.moveState.pitchDown = 0;
 						this.moveState.pitchDown = 0;
 						break;
 						break;
-
 					case 'ArrowLeft':
 					case 'ArrowLeft':
 						this.moveState.yawLeft = 0;
 						this.moveState.yawLeft = 0;
 						break;
 						break;
-
 					case 'ArrowRight':
 					case 'ArrowRight':
 						this.moveState.yawRight = 0;
 						this.moveState.yawRight = 0;
 						break;
 						break;
-
 					case 'KeyQ':
 					case 'KeyQ':
 						this.moveState.rollLeft = 0;
 						this.moveState.rollLeft = 0;
 						break;
 						break;
-
 					case 'KeyE':
 					case 'KeyE':
 						this.moveState.rollRight = 0;
 						this.moveState.rollRight = 0;
 						break;
 						break;
@@ -188,7 +167,6 @@
 						case 0:
 						case 0:
 							this.moveState.forward = 1;
 							this.moveState.forward = 1;
 							break;
 							break;
-
 						case 2:
 						case 2:
 							this.moveState.back = 1;
 							this.moveState.back = 1;
 							break;
 							break;
@@ -230,7 +208,6 @@
 						case 0:
 						case 0:
 							this.moveState.forward = 0;
 							this.moveState.forward = 0;
 							break;
 							break;
-
 						case 2:
 						case 2:
 							this.moveState.back = 0;
 							this.moveState.back = 0;
 							break;
 							break;
@@ -254,7 +231,6 @@
 				scope.object.translateZ( scope.moveVector.z * moveMult );
 				scope.object.translateZ( scope.moveVector.z * moveMult );
 				scope.tmpQuaternion.set( scope.rotationVector.x * rotMult, scope.rotationVector.y * rotMult, scope.rotationVector.z * rotMult, 1 ).normalize();
 				scope.tmpQuaternion.set( scope.rotationVector.x * rotMult, scope.rotationVector.y * rotMult, scope.rotationVector.z * rotMult, 1 ).normalize();
 				scope.object.quaternion.multiply( scope.tmpQuaternion );
 				scope.object.quaternion.multiply( scope.tmpQuaternion );
-
 				if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
 				if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
 
 
 					scope.dispatchEvent( _changeEvent );
 					scope.dispatchEvent( _changeEvent );
@@ -270,7 +246,9 @@
 				const forward = this.moveState.forward || this.autoForward && ! this.moveState.back ? 1 : 0;
 				const forward = this.moveState.forward || this.autoForward && ! this.moveState.back ? 1 : 0;
 				this.moveVector.x = - this.moveState.left + this.moveState.right;
 				this.moveVector.x = - this.moveState.left + this.moveState.right;
 				this.moveVector.y = - this.moveState.down + this.moveState.up;
 				this.moveVector.y = - this.moveState.down + this.moveState.up;
-				this.moveVector.z = - forward + this.moveState.back; //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
+				this.moveVector.z = - forward + this.moveState.back;
+
+				//console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
 
 
 			};
 			};
 
 
@@ -278,7 +256,9 @@
 
 
 				this.rotationVector.x = - this.moveState.pitchDown + this.moveState.pitchUp;
 				this.rotationVector.x = - this.moveState.pitchDown + this.moveState.pitchUp;
 				this.rotationVector.y = - this.moveState.yawRight + this.moveState.yawLeft;
 				this.rotationVector.y = - this.moveState.yawRight + this.moveState.yawLeft;
-				this.rotationVector.z = - this.moveState.rollRight + this.moveState.rollLeft; //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );
+				this.rotationVector.z = - this.moveState.rollRight + this.moveState.rollLeft;
+
+				//console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );
 
 
 			};
 			};
 
 
@@ -314,15 +294,10 @@
 			};
 			};
 
 
 			const _pointermove = this.pointermove.bind( this );
 			const _pointermove = this.pointermove.bind( this );
-
 			const _pointerdown = this.pointerdown.bind( this );
 			const _pointerdown = this.pointerdown.bind( this );
-
 			const _pointerup = this.pointerup.bind( this );
 			const _pointerup = this.pointerup.bind( this );
-
 			const _keydown = this.keydown.bind( this );
 			const _keydown = this.keydown.bind( this );
-
 			const _keyup = this.keyup.bind( this );
 			const _keyup = this.keyup.bind( this );
-
 			this.domElement.addEventListener( 'contextmenu', contextmenu );
 			this.domElement.addEventListener( 'contextmenu', contextmenu );
 			this.domElement.addEventListener( 'pointerdown', _pointerdown );
 			this.domElement.addEventListener( 'pointerdown', _pointerdown );
 			this.domElement.addEventListener( 'pointermove', _pointermove );
 			this.domElement.addEventListener( 'pointermove', _pointermove );
@@ -335,7 +310,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function contextmenu( event ) {
 	function contextmenu( event ) {
 
 
 		event.preventDefault();
 		event.preventDefault();

+ 85 - 95
examples/js/controls/OrbitControls.js

@@ -1,5 +1,6 @@
 ( function () {
 ( function () {
 
 
+	// This set of controls performs orbiting, dollying (zooming), and panning.
 	// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
 	// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
 	//
 	//
 	//    Orbit - left mouse / touch: one-finger move
 	//    Orbit - left mouse / touch: one-finger move
@@ -15,7 +16,6 @@
 	const _endEvent = {
 	const _endEvent = {
 		type: 'end'
 		type: 'end'
 	};
 	};
-
 	class OrbitControls extends THREE.EventDispatcher {
 	class OrbitControls extends THREE.EventDispatcher {
 
 
 		constructor( object, domElement ) {
 		constructor( object, domElement ) {
@@ -24,76 +24,86 @@
 			this.object = object;
 			this.object = object;
 			this.domElement = domElement;
 			this.domElement = domElement;
 			this.domElement.style.touchAction = 'none'; // disable touch scroll
 			this.domElement.style.touchAction = 'none'; // disable touch scroll
-			// Set to false to disable this control
 
 
-			this.enabled = true; // "target" sets the location of focus, where the object orbits around
+			// Set to false to disable this control
+			this.enabled = true;
 
 
-			this.target = new THREE.Vector3(); // How far you can dolly in and out ( PerspectiveCamera only )
+			// "target" sets the location of focus, where the object orbits around
+			this.target = new THREE.Vector3();
 
 
+			// How far you can dolly in and out ( PerspectiveCamera only )
 			this.minDistance = 0;
 			this.minDistance = 0;
-			this.maxDistance = Infinity; // How far you can zoom in and out ( OrthographicCamera only )
+			this.maxDistance = Infinity;
 
 
+			// How far you can zoom in and out ( OrthographicCamera only )
 			this.minZoom = 0;
 			this.minZoom = 0;
-			this.maxZoom = Infinity; // How far you can orbit vertically, upper and lower limits.
-			// Range is 0 to Math.PI radians.
+			this.maxZoom = Infinity;
 
 
+			// How far you can orbit vertically, upper and lower limits.
+			// Range is 0 to Math.PI radians.
 			this.minPolarAngle = 0; // radians
 			this.minPolarAngle = 0; // radians
-
 			this.maxPolarAngle = Math.PI; // radians
 			this.maxPolarAngle = Math.PI; // radians
+
 			// How far you can orbit horizontally, upper and lower limits.
 			// How far you can orbit horizontally, upper and lower limits.
 			// If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI )
 			// If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI )
-
 			this.minAzimuthAngle = - Infinity; // radians
 			this.minAzimuthAngle = - Infinity; // radians
-
 			this.maxAzimuthAngle = Infinity; // radians
 			this.maxAzimuthAngle = Infinity; // radians
+
 			// Set to true to enable damping (inertia)
 			// Set to true to enable damping (inertia)
 			// If damping is enabled, you must call controls.update() in your animation loop
 			// If damping is enabled, you must call controls.update() in your animation loop
-
 			this.enableDamping = false;
 			this.enableDamping = false;
-			this.dampingFactor = 0.05; // This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
-			// Set to false to disable zooming
+			this.dampingFactor = 0.05;
 
 
+			// This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
+			// Set to false to disable zooming
 			this.enableZoom = true;
 			this.enableZoom = true;
-			this.zoomSpeed = 1.0; // Set to false to disable rotating
+			this.zoomSpeed = 1.0;
 
 
+			// Set to false to disable rotating
 			this.enableRotate = true;
 			this.enableRotate = true;
-			this.rotateSpeed = 1.0; // Set to false to disable panning
+			this.rotateSpeed = 1.0;
 
 
+			// Set to false to disable panning
 			this.enablePan = true;
 			this.enablePan = true;
 			this.panSpeed = 1.0;
 			this.panSpeed = 1.0;
 			this.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up
 			this.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up
-
 			this.keyPanSpeed = 7.0; // pixels moved per arrow key push
 			this.keyPanSpeed = 7.0; // pixels moved per arrow key push
+
 			// Set to true to automatically rotate around the target
 			// Set to true to automatically rotate around the target
 			// If auto-rotate is enabled, you must call controls.update() in your animation loop
 			// If auto-rotate is enabled, you must call controls.update() in your animation loop
-
 			this.autoRotate = false;
 			this.autoRotate = false;
 			this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60
 			this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60
-			// The four arrow keys
 
 
+			// The four arrow keys
 			this.keys = {
 			this.keys = {
 				LEFT: 'ArrowLeft',
 				LEFT: 'ArrowLeft',
 				UP: 'ArrowUp',
 				UP: 'ArrowUp',
 				RIGHT: 'ArrowRight',
 				RIGHT: 'ArrowRight',
 				BOTTOM: 'ArrowDown'
 				BOTTOM: 'ArrowDown'
-			}; // Mouse buttons
+			};
 
 
+			// Mouse buttons
 			this.mouseButtons = {
 			this.mouseButtons = {
 				LEFT: THREE.MOUSE.ROTATE,
 				LEFT: THREE.MOUSE.ROTATE,
 				MIDDLE: THREE.MOUSE.DOLLY,
 				MIDDLE: THREE.MOUSE.DOLLY,
 				RIGHT: THREE.MOUSE.PAN
 				RIGHT: THREE.MOUSE.PAN
-			}; // Touch fingers
+			};
 
 
+			// Touch fingers
 			this.touches = {
 			this.touches = {
 				ONE: THREE.TOUCH.ROTATE,
 				ONE: THREE.TOUCH.ROTATE,
 				TWO: THREE.TOUCH.DOLLY_PAN
 				TWO: THREE.TOUCH.DOLLY_PAN
-			}; // for reset
+			};
 
 
+			// for reset
 			this.target0 = this.target.clone();
 			this.target0 = this.target.clone();
 			this.position0 = this.object.position.clone();
 			this.position0 = this.object.position.clone();
-			this.zoom0 = this.object.zoom; // the target DOM element for key events
+			this.zoom0 = this.object.zoom;
+
+			// the target DOM element for key events
+			this._domElementKeyEvents = null;
 
 
-			this._domElementKeyEvents = null; //
+			//
 			// public methods
 			// public methods
 			//
 			//
 
 
@@ -140,13 +150,14 @@
 				scope.update();
 				scope.update();
 				state = STATE.NONE;
 				state = STATE.NONE;
 
 
-			}; // this method is exposed, but perhaps it would be better if we can make it private...
-
+			};
 
 
+			// this method is exposed, but perhaps it would be better if we can make it private...
 			this.update = function () {
 			this.update = function () {
 
 
-				const offset = new THREE.Vector3(); // so camera.up is the orbit axis
+				const offset = new THREE.Vector3();
 
 
+				// so camera.up is the orbit axis
 				const quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
 				const quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
 				const quatInverse = quat.clone().invert();
 				const quatInverse = quat.clone().invert();
 				const lastPosition = new THREE.Vector3();
 				const lastPosition = new THREE.Vector3();
@@ -155,12 +166,13 @@
 				return function update() {
 				return function update() {
 
 
 					const position = scope.object.position;
 					const position = scope.object.position;
-					offset.copy( position ).sub( scope.target ); // rotate offset to "y-axis-is-up" space
+					offset.copy( position ).sub( scope.target );
 
 
-					offset.applyQuaternion( quat ); // angle from z-axis around y-axis
+					// rotate offset to "y-axis-is-up" space
+					offset.applyQuaternion( quat );
 
 
+					// angle from z-axis around y-axis
 					spherical.setFromVector3( offset );
 					spherical.setFromVector3( offset );
-
 					if ( scope.autoRotate && state === STATE.NONE ) {
 					if ( scope.autoRotate && state === STATE.NONE ) {
 
 
 						rotateLeft( getAutoRotationAngle() );
 						rotateLeft( getAutoRotationAngle() );
@@ -177,17 +189,16 @@
 						spherical.theta += sphericalDelta.theta;
 						spherical.theta += sphericalDelta.theta;
 						spherical.phi += sphericalDelta.phi;
 						spherical.phi += sphericalDelta.phi;
 
 
-					} // restrict theta to be between desired limits
+					}
 
 
+					// restrict theta to be between desired limits
 
 
 					let min = scope.minAzimuthAngle;
 					let min = scope.minAzimuthAngle;
 					let max = scope.maxAzimuthAngle;
 					let max = scope.maxAzimuthAngle;
-
 					if ( isFinite( min ) && isFinite( max ) ) {
 					if ( isFinite( min ) && isFinite( max ) ) {
 
 
 						if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;
 						if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;
 						if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;
 						if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;
-
 						if ( min <= max ) {
 						if ( min <= max ) {
 
 
 							spherical.theta = Math.max( min, Math.min( max, spherical.theta ) );
 							spherical.theta = Math.max( min, Math.min( max, spherical.theta ) );
@@ -198,14 +209,17 @@
 
 
 						}
 						}
 
 
-					} // restrict phi to be between desired limits
-
+					}
 
 
+					// restrict phi to be between desired limits
 					spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
 					spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
 					spherical.makeSafe();
 					spherical.makeSafe();
-					spherical.radius *= scale; // restrict radius to be between desired limits
+					spherical.radius *= scale;
+
+					// restrict radius to be between desired limits
+					spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
 
 
-					spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); // move target to panned location
+					// move target to panned location
 
 
 					if ( scope.enableDamping === true ) {
 					if ( scope.enableDamping === true ) {
 
 
@@ -217,12 +231,12 @@
 
 
 					}
 					}
 
 
-					offset.setFromSpherical( spherical ); // rotate offset back to "camera-up-vector-is-up" space
+					offset.setFromSpherical( spherical );
 
 
+					// rotate offset back to "camera-up-vector-is-up" space
 					offset.applyQuaternion( quatInverse );
 					offset.applyQuaternion( quatInverse );
 					position.copy( scope.target ).add( offset );
 					position.copy( scope.target ).add( offset );
 					scope.object.lookAt( scope.target );
 					scope.object.lookAt( scope.target );
-
 					if ( scope.enableDamping === true ) {
 					if ( scope.enableDamping === true ) {
 
 
 						sphericalDelta.theta *= 1 - scope.dampingFactor;
 						sphericalDelta.theta *= 1 - scope.dampingFactor;
@@ -236,7 +250,9 @@
 
 
 					}
 					}
 
 
-					scale = 1; // update condition is:
+					scale = 1;
+
+					// update condition is:
 					// min(camera displacement, camera rotation in radians)^2 > EPS
 					// min(camera displacement, camera rotation in radians)^2 > EPS
 					// using small-angle approximation cos(x/2) = 1 - x^2 / 8
 					// using small-angle approximation cos(x/2) = 1 - x^2 / 8
 
 
@@ -255,7 +271,6 @@
 				};
 				};
 
 
 			}();
 			}();
-
 			this.dispose = function () {
 			this.dispose = function () {
 
 
 				scope.domElement.removeEventListener( 'contextmenu', onContextMenu );
 				scope.domElement.removeEventListener( 'contextmenu', onContextMenu );
@@ -264,18 +279,20 @@
 				scope.domElement.removeEventListener( 'wheel', onMouseWheel );
 				scope.domElement.removeEventListener( 'wheel', onMouseWheel );
 				scope.domElement.removeEventListener( 'pointermove', onPointerMove );
 				scope.domElement.removeEventListener( 'pointermove', onPointerMove );
 				scope.domElement.removeEventListener( 'pointerup', onPointerUp );
 				scope.domElement.removeEventListener( 'pointerup', onPointerUp );
-
 				if ( scope._domElementKeyEvents !== null ) {
 				if ( scope._domElementKeyEvents !== null ) {
 
 
 					scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
 					scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
 
 
-				} //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
+				}
+
+				//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
+
+			};
 
 
-			}; //
+			//
 			// internals
 			// internals
 			//
 			//
 
 
-
 			const scope = this;
 			const scope = this;
 			const STATE = {
 			const STATE = {
 				NONE: - 1,
 				NONE: - 1,
@@ -288,8 +305,9 @@
 				TOUCH_DOLLY_ROTATE: 6
 				TOUCH_DOLLY_ROTATE: 6
 			};
 			};
 			let state = STATE.NONE;
 			let state = STATE.NONE;
-			const EPS = 0.000001; // current position in spherical coordinates
+			const EPS = 0.000001;
 
 
+			// current position in spherical coordinates
 			const spherical = new THREE.Spherical();
 			const spherical = new THREE.Spherical();
 			const sphericalDelta = new THREE.Spherical();
 			const sphericalDelta = new THREE.Spherical();
 			let scale = 1;
 			let scale = 1;
@@ -306,7 +324,6 @@
 			const dollyDelta = new THREE.Vector2();
 			const dollyDelta = new THREE.Vector2();
 			const pointers = [];
 			const pointers = [];
 			const pointerPositions = {};
 			const pointerPositions = {};
-
 			function getAutoRotationAngle() {
 			function getAutoRotationAngle() {
 
 
 				return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
 				return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
@@ -337,14 +354,12 @@
 				return function panLeft( distance, objectMatrix ) {
 				return function panLeft( distance, objectMatrix ) {
 
 
 					v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
 					v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
-
 					v.multiplyScalar( - distance );
 					v.multiplyScalar( - distance );
 					panOffset.add( v );
 					panOffset.add( v );
 
 
 				};
 				};
 
 
 			}();
 			}();
-
 			const panUp = function () {
 			const panUp = function () {
 
 
 				const v = new THREE.Vector3();
 				const v = new THREE.Vector3();
@@ -366,25 +381,26 @@
 
 
 				};
 				};
 
 
-			}(); // deltaX and deltaY are in pixels; right and down are positive
-
+			}();
 
 
+			// deltaX and deltaY are in pixels; right and down are positive
 			const pan = function () {
 			const pan = function () {
 
 
 				const offset = new THREE.Vector3();
 				const offset = new THREE.Vector3();
 				return function pan( deltaX, deltaY ) {
 				return function pan( deltaX, deltaY ) {
 
 
 					const element = scope.domElement;
 					const element = scope.domElement;
-
 					if ( scope.object.isPerspectiveCamera ) {
 					if ( scope.object.isPerspectiveCamera ) {
 
 
 						// perspective
 						// perspective
 						const position = scope.object.position;
 						const position = scope.object.position;
 						offset.copy( position ).sub( scope.target );
 						offset.copy( position ).sub( scope.target );
-						let targetDistance = offset.length(); // half of the fov is center to top of screen
+						let targetDistance = offset.length();
 
 
-						targetDistance *= Math.tan( scope.object.fov / 2 * Math.PI / 180.0 ); // we use only clientHeight here so aspect ratio does not distort speed
+						// half of the fov is center to top of screen
+						targetDistance *= Math.tan( scope.object.fov / 2 * Math.PI / 180.0 );
 
 
+						// we use only clientHeight here so aspect ratio does not distort speed
 						panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
 						panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
 						panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
 						panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
 
 
@@ -405,7 +421,6 @@
 				};
 				};
 
 
 			}();
 			}();
-
 			function dollyOut( dollyScale ) {
 			function dollyOut( dollyScale ) {
 
 
 				if ( scope.object.isPerspectiveCamera ) {
 				if ( scope.object.isPerspectiveCamera ) {
@@ -446,11 +461,12 @@
 
 
 				}
 				}
 
 
-			} //
+			}
+
+			//
 			// event callbacks - update the object state
 			// event callbacks - update the object state
 			//
 			//
 
 
-
 			function handleMouseDownRotate( event ) {
 			function handleMouseDownRotate( event ) {
 
 
 				rotateStart.set( event.clientX, event.clientY );
 				rotateStart.set( event.clientX, event.clientY );
@@ -486,7 +502,6 @@
 
 
 				dollyEnd.set( event.clientX, event.clientY );
 				dollyEnd.set( event.clientX, event.clientY );
 				dollyDelta.subVectors( dollyEnd, dollyStart );
 				dollyDelta.subVectors( dollyEnd, dollyStart );
-
 				if ( dollyDelta.y > 0 ) {
 				if ( dollyDelta.y > 0 ) {
 
 
 					dollyOut( getZoomScale() );
 					dollyOut( getZoomScale() );
@@ -531,24 +546,20 @@
 			function handleKeyDown( event ) {
 			function handleKeyDown( event ) {
 
 
 				let needsUpdate = false;
 				let needsUpdate = false;
-
 				switch ( event.code ) {
 				switch ( event.code ) {
 
 
 					case scope.keys.UP:
 					case scope.keys.UP:
 						pan( 0, scope.keyPanSpeed );
 						pan( 0, scope.keyPanSpeed );
 						needsUpdate = true;
 						needsUpdate = true;
 						break;
 						break;
-
 					case scope.keys.BOTTOM:
 					case scope.keys.BOTTOM:
 						pan( 0, - scope.keyPanSpeed );
 						pan( 0, - scope.keyPanSpeed );
 						needsUpdate = true;
 						needsUpdate = true;
 						break;
 						break;
-
 					case scope.keys.LEFT:
 					case scope.keys.LEFT:
 						pan( scope.keyPanSpeed, 0 );
 						pan( scope.keyPanSpeed, 0 );
 						needsUpdate = true;
 						needsUpdate = true;
 						break;
 						break;
-
 					case scope.keys.RIGHT:
 					case scope.keys.RIGHT:
 						pan( - scope.keyPanSpeed, 0 );
 						pan( - scope.keyPanSpeed, 0 );
 						needsUpdate = true;
 						needsUpdate = true;
@@ -691,26 +702,26 @@
 				if ( scope.enableZoom ) handleTouchMoveDolly( event );
 				if ( scope.enableZoom ) handleTouchMoveDolly( event );
 				if ( scope.enableRotate ) handleTouchMoveRotate( event );
 				if ( scope.enableRotate ) handleTouchMoveRotate( event );
 
 
-			} //
+			}
+
+			//
 			// event handlers - FSM: listen for events and reset state
 			// event handlers - FSM: listen for events and reset state
 			//
 			//
 
 
-
 			function onPointerDown( event ) {
 			function onPointerDown( event ) {
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
-
 				if ( pointers.length === 0 ) {
 				if ( pointers.length === 0 ) {
 
 
 					scope.domElement.setPointerCapture( event.pointerId );
 					scope.domElement.setPointerCapture( event.pointerId );
 					scope.domElement.addEventListener( 'pointermove', onPointerMove );
 					scope.domElement.addEventListener( 'pointermove', onPointerMove );
 					scope.domElement.addEventListener( 'pointerup', onPointerUp );
 					scope.domElement.addEventListener( 'pointerup', onPointerUp );
 
 
-				} //
+				}
 
 
+				//
 
 
 				addPointer( event );
 				addPointer( event );
-
 				if ( event.pointerType === 'touch' ) {
 				if ( event.pointerType === 'touch' ) {
 
 
 					onTouchStart( event );
 					onTouchStart( event );
@@ -726,7 +737,6 @@
 			function onPointerMove( event ) {
 			function onPointerMove( event ) {
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
-
 				if ( event.pointerType === 'touch' ) {
 				if ( event.pointerType === 'touch' ) {
 
 
 					onTouchMove( event );
 					onTouchMove( event );
@@ -742,7 +752,6 @@
 			function onPointerUp( event ) {
 			function onPointerUp( event ) {
 
 
 				removePointer( event );
 				removePointer( event );
-
 				if ( pointers.length === 0 ) {
 				if ( pointers.length === 0 ) {
 
 
 					scope.domElement.releasePointerCapture( event.pointerId );
 					scope.domElement.releasePointerCapture( event.pointerId );
@@ -765,21 +774,17 @@
 			function onMouseDown( event ) {
 			function onMouseDown( event ) {
 
 
 				let mouseAction;
 				let mouseAction;
-
 				switch ( event.button ) {
 				switch ( event.button ) {
 
 
 					case 0:
 					case 0:
 						mouseAction = scope.mouseButtons.LEFT;
 						mouseAction = scope.mouseButtons.LEFT;
 						break;
 						break;
-
 					case 1:
 					case 1:
 						mouseAction = scope.mouseButtons.MIDDLE;
 						mouseAction = scope.mouseButtons.MIDDLE;
 						break;
 						break;
-
 					case 2:
 					case 2:
 						mouseAction = scope.mouseButtons.RIGHT;
 						mouseAction = scope.mouseButtons.RIGHT;
 						break;
 						break;
-
 					default:
 					default:
 						mouseAction = - 1;
 						mouseAction = - 1;
 
 
@@ -792,7 +797,6 @@
 						handleMouseDownDolly( event );
 						handleMouseDownDolly( event );
 						state = STATE.DOLLY;
 						state = STATE.DOLLY;
 						break;
 						break;
-
 					case THREE.MOUSE.ROTATE:
 					case THREE.MOUSE.ROTATE:
 						if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
 						if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
 
 
@@ -809,7 +813,6 @@
 						}
 						}
 
 
 						break;
 						break;
-
 					case THREE.MOUSE.PAN:
 					case THREE.MOUSE.PAN:
 						if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
 						if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
 
 
@@ -826,7 +829,6 @@
 						}
 						}
 
 
 						break;
 						break;
-
 					default:
 					default:
 						state = STATE.NONE;
 						state = STATE.NONE;
 
 
@@ -848,12 +850,10 @@
 						if ( scope.enableRotate === false ) return;
 						if ( scope.enableRotate === false ) return;
 						handleMouseMoveRotate( event );
 						handleMouseMoveRotate( event );
 						break;
 						break;
-
 					case STATE.DOLLY:
 					case STATE.DOLLY:
 						if ( scope.enableZoom === false ) return;
 						if ( scope.enableZoom === false ) return;
 						handleMouseMoveDolly( event );
 						handleMouseMoveDolly( event );
 						break;
 						break;
-
 					case STATE.PAN:
 					case STATE.PAN:
 						if ( scope.enablePan === false ) return;
 						if ( scope.enablePan === false ) return;
 						handleMouseMovePan( event );
 						handleMouseMovePan( event );
@@ -883,7 +883,6 @@
 			function onTouchStart( event ) {
 			function onTouchStart( event ) {
 
 
 				trackPointer( event );
 				trackPointer( event );
-
 				switch ( pointers.length ) {
 				switch ( pointers.length ) {
 
 
 					case 1:
 					case 1:
@@ -894,20 +893,17 @@
 								handleTouchStartRotate();
 								handleTouchStartRotate();
 								state = STATE.TOUCH_ROTATE;
 								state = STATE.TOUCH_ROTATE;
 								break;
 								break;
-
 							case THREE.TOUCH.PAN:
 							case THREE.TOUCH.PAN:
 								if ( scope.enablePan === false ) return;
 								if ( scope.enablePan === false ) return;
 								handleTouchStartPan();
 								handleTouchStartPan();
 								state = STATE.TOUCH_PAN;
 								state = STATE.TOUCH_PAN;
 								break;
 								break;
-
 							default:
 							default:
 								state = STATE.NONE;
 								state = STATE.NONE;
 
 
 						}
 						}
 
 
 						break;
 						break;
-
 					case 2:
 					case 2:
 						switch ( scope.touches.TWO ) {
 						switch ( scope.touches.TWO ) {
 
 
@@ -916,20 +912,17 @@
 								handleTouchStartDollyPan();
 								handleTouchStartDollyPan();
 								state = STATE.TOUCH_DOLLY_PAN;
 								state = STATE.TOUCH_DOLLY_PAN;
 								break;
 								break;
-
 							case THREE.TOUCH.DOLLY_ROTATE:
 							case THREE.TOUCH.DOLLY_ROTATE:
 								if ( scope.enableZoom === false && scope.enableRotate === false ) return;
 								if ( scope.enableZoom === false && scope.enableRotate === false ) return;
 								handleTouchStartDollyRotate();
 								handleTouchStartDollyRotate();
 								state = STATE.TOUCH_DOLLY_ROTATE;
 								state = STATE.TOUCH_DOLLY_ROTATE;
 								break;
 								break;
-
 							default:
 							default:
 								state = STATE.NONE;
 								state = STATE.NONE;
 
 
 						}
 						}
 
 
 						break;
 						break;
-
 					default:
 					default:
 						state = STATE.NONE;
 						state = STATE.NONE;
 
 
@@ -946,7 +939,6 @@
 			function onTouchMove( event ) {
 			function onTouchMove( event ) {
 
 
 				trackPointer( event );
 				trackPointer( event );
-
 				switch ( state ) {
 				switch ( state ) {
 
 
 					case STATE.TOUCH_ROTATE:
 					case STATE.TOUCH_ROTATE:
@@ -954,25 +946,21 @@
 						handleTouchMoveRotate( event );
 						handleTouchMoveRotate( event );
 						scope.update();
 						scope.update();
 						break;
 						break;
-
 					case STATE.TOUCH_PAN:
 					case STATE.TOUCH_PAN:
 						if ( scope.enablePan === false ) return;
 						if ( scope.enablePan === false ) return;
 						handleTouchMovePan( event );
 						handleTouchMovePan( event );
 						scope.update();
 						scope.update();
 						break;
 						break;
-
 					case STATE.TOUCH_DOLLY_PAN:
 					case STATE.TOUCH_DOLLY_PAN:
 						if ( scope.enableZoom === false && scope.enablePan === false ) return;
 						if ( scope.enableZoom === false && scope.enablePan === false ) return;
 						handleTouchMoveDollyPan( event );
 						handleTouchMoveDollyPan( event );
 						scope.update();
 						scope.update();
 						break;
 						break;
-
 					case STATE.TOUCH_DOLLY_ROTATE:
 					case STATE.TOUCH_DOLLY_ROTATE:
 						if ( scope.enableZoom === false && scope.enableRotate === false ) return;
 						if ( scope.enableZoom === false && scope.enableRotate === false ) return;
 						handleTouchMoveDollyRotate( event );
 						handleTouchMoveDollyRotate( event );
 						scope.update();
 						scope.update();
 						break;
 						break;
-
 					default:
 					default:
 						state = STATE.NONE;
 						state = STATE.NONE;
 
 
@@ -996,7 +984,6 @@
 			function removePointer( event ) {
 			function removePointer( event ) {
 
 
 				delete pointerPositions[ event.pointerId ];
 				delete pointerPositions[ event.pointerId ];
-
 				for ( let i = 0; i < pointers.length; i ++ ) {
 				for ( let i = 0; i < pointers.length; i ++ ) {
 
 
 					if ( pointers[ i ].pointerId == event.pointerId ) {
 					if ( pointers[ i ].pointerId == event.pointerId ) {
@@ -1013,7 +1000,6 @@
 			function trackPointer( event ) {
 			function trackPointer( event ) {
 
 
 				let position = pointerPositions[ event.pointerId ];
 				let position = pointerPositions[ event.pointerId ];
-
 				if ( position === undefined ) {
 				if ( position === undefined ) {
 
 
 					position = new THREE.Vector2();
 					position = new THREE.Vector2();
@@ -1030,21 +1016,26 @@
 				const pointer = event.pointerId === pointers[ 0 ].pointerId ? pointers[ 1 ] : pointers[ 0 ];
 				const pointer = event.pointerId === pointers[ 0 ].pointerId ? pointers[ 1 ] : pointers[ 0 ];
 				return pointerPositions[ pointer.pointerId ];
 				return pointerPositions[ pointer.pointerId ];
 
 
-			} //
+			}
 
 
+			//
 
 
 			scope.domElement.addEventListener( 'contextmenu', onContextMenu );
 			scope.domElement.addEventListener( 'contextmenu', onContextMenu );
 			scope.domElement.addEventListener( 'pointerdown', onPointerDown );
 			scope.domElement.addEventListener( 'pointerdown', onPointerDown );
 			scope.domElement.addEventListener( 'pointercancel', onPointerCancel );
 			scope.domElement.addEventListener( 'pointercancel', onPointerCancel );
 			scope.domElement.addEventListener( 'wheel', onMouseWheel, {
 			scope.domElement.addEventListener( 'wheel', onMouseWheel, {
 				passive: false
 				passive: false
-			} ); // force an update at start
+			} );
+
+			// force an update at start
 
 
 			this.update();
 			this.update();
 
 
 		}
 		}
 
 
-	} // This set of controls performs orbiting, dollying (zooming), and panning.
+	}
+
+	// This set of controls performs orbiting, dollying (zooming), and panning.
 	// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
 	// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
 	// This is very similar to OrbitControls, another set of touch behavior
 	// This is very similar to OrbitControls, another set of touch behavior
 	//
 	//
@@ -1052,7 +1043,6 @@
 	//    Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
 	//    Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish
 	//    Pan - left mouse, or arrow keys / touch: one-finger move
 	//    Pan - left mouse, or arrow keys / touch: one-finger move
 
 
-
 	class MapControls extends OrbitControls {
 	class MapControls extends OrbitControls {
 
 
 		constructor( object, domElement ) {
 		constructor( object, domElement ) {

+ 5 - 14
examples/js/controls/PointerLockControls.js

@@ -1,9 +1,7 @@
 ( function () {
 ( function () {
 
 
 	const _euler = new THREE.Euler( 0, 0, 0, 'YXZ' );
 	const _euler = new THREE.Euler( 0, 0, 0, 'YXZ' );
-
 	const _vector = new THREE.Vector3();
 	const _vector = new THREE.Vector3();
-
 	const _changeEvent = {
 	const _changeEvent = {
 		type: 'change'
 		type: 'change'
 	};
 	};
@@ -13,33 +11,28 @@
 	const _unlockEvent = {
 	const _unlockEvent = {
 		type: 'unlock'
 		type: 'unlock'
 	};
 	};
-
 	const _PI_2 = Math.PI / 2;
 	const _PI_2 = Math.PI / 2;
-
 	class PointerLockControls extends THREE.EventDispatcher {
 	class PointerLockControls extends THREE.EventDispatcher {
 
 
 		constructor( camera, domElement ) {
 		constructor( camera, domElement ) {
 
 
 			super();
 			super();
 			this.domElement = domElement;
 			this.domElement = domElement;
-			this.isLocked = false; // Set to constrain the pitch of the camera
-			// Range is 0 to Math.PI radians
+			this.isLocked = false;
 
 
+			// Set to constrain the pitch of the camera
+			// Range is 0 to Math.PI radians
 			this.minPolarAngle = 0; // radians
 			this.minPolarAngle = 0; // radians
-
 			this.maxPolarAngle = Math.PI; // radians
 			this.maxPolarAngle = Math.PI; // radians
 
 
 			this.pointerSpeed = 1.0;
 			this.pointerSpeed = 1.0;
 			const scope = this;
 			const scope = this;
-
 			function onMouseMove( event ) {
 			function onMouseMove( event ) {
 
 
 				if ( scope.isLocked === false ) return;
 				if ( scope.isLocked === false ) return;
 				const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
 				const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
 				const movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
 				const movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
-
 				_euler.setFromQuaternion( camera.quaternion );
 				_euler.setFromQuaternion( camera.quaternion );
-
 				_euler.y -= movementX * 0.002 * scope.pointerSpeed;
 				_euler.y -= movementX * 0.002 * scope.pointerSpeed;
 				_euler.x -= movementY * 0.002 * scope.pointerSpeed;
 				_euler.x -= movementY * 0.002 * scope.pointerSpeed;
 				_euler.x = Math.max( _PI_2 - scope.maxPolarAngle, Math.min( _PI_2 - scope.minPolarAngle, _euler.x ) );
 				_euler.x = Math.max( _PI_2 - scope.maxPolarAngle, Math.min( _PI_2 - scope.minPolarAngle, _euler.x ) );
@@ -95,6 +88,7 @@
 			this.getObject = function () {
 			this.getObject = function () {
 
 
 				// retaining this method for backward compatibility
 				// retaining this method for backward compatibility
+
 				return camera;
 				return camera;
 
 
 			};
 			};
@@ -109,15 +103,13 @@
 				};
 				};
 
 
 			}();
 			}();
-
 			this.moveForward = function ( distance ) {
 			this.moveForward = function ( distance ) {
 
 
 				// move forward parallel to the xz-plane
 				// move forward parallel to the xz-plane
 				// assumes camera.up is y-up
 				// assumes camera.up is y-up
-				_vector.setFromMatrixColumn( camera.matrix, 0 );
 
 
+				_vector.setFromMatrixColumn( camera.matrix, 0 );
 				_vector.crossVectors( camera.up, _vector );
 				_vector.crossVectors( camera.up, _vector );
-
 				camera.position.addScaledVector( _vector, distance );
 				camera.position.addScaledVector( _vector, distance );
 
 
 			};
 			};
@@ -125,7 +117,6 @@
 			this.moveRight = function ( distance ) {
 			this.moveRight = function ( distance ) {
 
 
 				_vector.setFromMatrixColumn( camera.matrix, 0 );
 				_vector.setFromMatrixColumn( camera.matrix, 0 );
-
 				camera.position.addScaledVector( _vector, distance );
 				camera.position.addScaledVector( _vector, distance );
 
 
 			};
 			};

+ 23 - 88
examples/js/controls/TrackballControls.js

@@ -9,7 +9,6 @@
 	const _endEvent = {
 	const _endEvent = {
 		type: 'end'
 		type: 'end'
 	};
 	};
-
 	class TrackballControls extends THREE.EventDispatcher {
 	class TrackballControls extends THREE.EventDispatcher {
 
 
 		constructor( object, domElement ) {
 		constructor( object, domElement ) {
@@ -27,6 +26,7 @@
 			this.object = object;
 			this.object = object;
 			this.domElement = domElement;
 			this.domElement = domElement;
 			this.domElement.style.touchAction = 'none'; // disable touch scroll
 			this.domElement.style.touchAction = 'none'; // disable touch scroll
+
 			// API
 			// API
 
 
 			this.enabled = true;
 			this.enabled = true;
@@ -46,18 +46,15 @@
 			this.dynamicDampingFactor = 0.2;
 			this.dynamicDampingFactor = 0.2;
 			this.minDistance = 0;
 			this.minDistance = 0;
 			this.maxDistance = Infinity;
 			this.maxDistance = Infinity;
-			this.keys = [ 'KeyA',
-				/*A*/
-				'KeyS',
-				/*S*/
-				'KeyD'
-				/*D*/
-			];
+			this.keys = [ 'KeyA' /*A*/, 'KeyS' /*S*/, 'KeyD' /*D*/];
+
 			this.mouseButtons = {
 			this.mouseButtons = {
 				LEFT: THREE.MOUSE.ROTATE,
 				LEFT: THREE.MOUSE.ROTATE,
 				MIDDLE: THREE.MOUSE.DOLLY,
 				MIDDLE: THREE.MOUSE.DOLLY,
 				RIGHT: THREE.MOUSE.PAN
 				RIGHT: THREE.MOUSE.PAN
-			}; // internals
+			};
+
+			// internals
 
 
 			this.target = new THREE.Vector3();
 			this.target = new THREE.Vector3();
 			const EPS = 0.000001;
 			const EPS = 0.000001;
@@ -68,7 +65,6 @@
 				_touchZoomDistanceStart = 0,
 				_touchZoomDistanceStart = 0,
 				_touchZoomDistanceEnd = 0,
 				_touchZoomDistanceEnd = 0,
 				_lastAngle = 0;
 				_lastAngle = 0;
-
 			const _eye = new THREE.Vector3(),
 			const _eye = new THREE.Vector3(),
 				_movePrev = new THREE.Vector2(),
 				_movePrev = new THREE.Vector2(),
 				_moveCurr = new THREE.Vector2(),
 				_moveCurr = new THREE.Vector2(),
@@ -78,18 +74,21 @@
 				_panStart = new THREE.Vector2(),
 				_panStart = new THREE.Vector2(),
 				_panEnd = new THREE.Vector2(),
 				_panEnd = new THREE.Vector2(),
 				_pointers = [],
 				_pointers = [],
-				_pointerPositions = {}; // for reset
+				_pointerPositions = {};
 
 
+			// for reset
 
 
 			this.target0 = this.target.clone();
 			this.target0 = this.target.clone();
 			this.position0 = this.object.position.clone();
 			this.position0 = this.object.position.clone();
 			this.up0 = this.object.up.clone();
 			this.up0 = this.object.up.clone();
-			this.zoom0 = this.object.zoom; // methods
+			this.zoom0 = this.object.zoom;
 
 
-			this.handleResize = function () {
+			// methods
 
 
-				const box = scope.domElement.getBoundingClientRect(); // adjustments come from similar code in the jquery offset() function
+			this.handleResize = function () {
 
 
+				const box = scope.domElement.getBoundingClientRect();
+				// adjustments come from similar code in the jquery offset() function
 				const d = scope.domElement.ownerDocument.documentElement;
 				const d = scope.domElement.ownerDocument.documentElement;
 				scope.screen.left = box.left + window.pageXOffset - d.clientLeft;
 				scope.screen.left = box.left + window.pageXOffset - d.clientLeft;
 				scope.screen.top = box.top + window.pageYOffset - d.clientTop;
 				scope.screen.top = box.top + window.pageYOffset - d.clientTop;
@@ -109,7 +108,6 @@
 				};
 				};
 
 
 			}();
 			}();
-
 			const getMouseOnCircle = function () {
 			const getMouseOnCircle = function () {
 
 
 				const vector = new THREE.Vector2();
 				const vector = new THREE.Vector2();
@@ -117,12 +115,12 @@
 
 
 					vector.set( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ), ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width // screen.width intentional
 					vector.set( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ), ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width // screen.width intentional
 					);
 					);
+
 					return vector;
 					return vector;
 
 
 				};
 				};
 
 
 			}();
 			}();
-
 			this.rotateCamera = function () {
 			this.rotateCamera = function () {
 
 
 				const axis = new THREE.Vector3(),
 				const axis = new THREE.Vector3(),
@@ -135,11 +133,9 @@
 
 
 					moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );
 					moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );
 					let angle = moveDirection.length();
 					let angle = moveDirection.length();
-
 					if ( angle ) {
 					if ( angle ) {
 
 
 						_eye.copy( scope.object.position ).sub( scope.target );
 						_eye.copy( scope.object.position ).sub( scope.target );
-
 						eyeDirection.copy( _eye ).normalize();
 						eyeDirection.copy( _eye ).normalize();
 						objectUpDirection.copy( scope.object.up ).normalize();
 						objectUpDirection.copy( scope.object.up ).normalize();
 						objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();
 						objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();
@@ -149,25 +145,17 @@
 						axis.crossVectors( moveDirection, _eye ).normalize();
 						axis.crossVectors( moveDirection, _eye ).normalize();
 						angle *= scope.rotateSpeed;
 						angle *= scope.rotateSpeed;
 						quaternion.setFromAxisAngle( axis, angle );
 						quaternion.setFromAxisAngle( axis, angle );
-
 						_eye.applyQuaternion( quaternion );
 						_eye.applyQuaternion( quaternion );
-
 						scope.object.up.applyQuaternion( quaternion );
 						scope.object.up.applyQuaternion( quaternion );
-
 						_lastAxis.copy( axis );
 						_lastAxis.copy( axis );
-
 						_lastAngle = angle;
 						_lastAngle = angle;
 
 
 					} else if ( ! scope.staticMoving && _lastAngle ) {
 					} else if ( ! scope.staticMoving && _lastAngle ) {
 
 
 						_lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor );
 						_lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor );
-
 						_eye.copy( scope.object.position ).sub( scope.target );
 						_eye.copy( scope.object.position ).sub( scope.target );
-
 						quaternion.setFromAxisAngle( _lastAxis, _lastAngle );
 						quaternion.setFromAxisAngle( _lastAxis, _lastAngle );
-
 						_eye.applyQuaternion( quaternion );
 						_eye.applyQuaternion( quaternion );
-
 						scope.object.up.applyQuaternion( quaternion );
 						scope.object.up.applyQuaternion( quaternion );
 
 
 					}
 					}
@@ -177,16 +165,13 @@
 				};
 				};
 
 
 			}();
 			}();
-
 			this.zoomCamera = function () {
 			this.zoomCamera = function () {
 
 
 				let factor;
 				let factor;
-
 				if ( _state === STATE.TOUCH_ZOOM_PAN ) {
 				if ( _state === STATE.TOUCH_ZOOM_PAN ) {
 
 
 					factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
 					factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
 					_touchZoomDistanceStart = _touchZoomDistanceEnd;
 					_touchZoomDistanceStart = _touchZoomDistanceEnd;
-
 					if ( scope.object.isPerspectiveCamera ) {
 					if ( scope.object.isPerspectiveCamera ) {
 
 
 						_eye.multiplyScalar( factor );
 						_eye.multiplyScalar( factor );
@@ -205,7 +190,6 @@
 				} else {
 				} else {
 
 
 					factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed;
 					factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed;
-
 					if ( factor !== 1.0 && factor > 0.0 ) {
 					if ( factor !== 1.0 && factor > 0.0 ) {
 
 
 						if ( scope.object.isPerspectiveCamera ) {
 						if ( scope.object.isPerspectiveCamera ) {
@@ -247,7 +231,6 @@
 				return function panCamera() {
 				return function panCamera() {
 
 
 					mouseChange.copy( _panEnd ).sub( _panStart );
 					mouseChange.copy( _panEnd ).sub( _panStart );
-
 					if ( mouseChange.lengthSq() ) {
 					if ( mouseChange.lengthSq() ) {
 
 
 						if ( scope.object.isOrthographicCamera ) {
 						if ( scope.object.isOrthographicCamera ) {
@@ -264,7 +247,6 @@
 						pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) );
 						pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) );
 						scope.object.position.add( pan );
 						scope.object.position.add( pan );
 						scope.target.add( pan );
 						scope.target.add( pan );
-
 						if ( scope.staticMoving ) {
 						if ( scope.staticMoving ) {
 
 
 							_panStart.copy( _panEnd );
 							_panStart.copy( _panEnd );
@@ -280,7 +262,6 @@
 				};
 				};
 
 
 			}();
 			}();
-
 			this.checkDistances = function () {
 			this.checkDistances = function () {
 
 
 				if ( ! scope.noZoom || ! scope.noPan ) {
 				if ( ! scope.noZoom || ! scope.noPan ) {
@@ -288,7 +269,6 @@
 					if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) {
 					if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) {
 
 
 						scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) );
 						scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) );
-
 						_zoomStart.copy( _zoomEnd );
 						_zoomStart.copy( _zoomEnd );
 
 
 					}
 					}
@@ -296,7 +276,6 @@
 					if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) {
 					if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) {
 
 
 						scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) );
 						scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) );
-
 						_zoomStart.copy( _zoomEnd );
 						_zoomStart.copy( _zoomEnd );
 
 
 					}
 					}
@@ -308,7 +287,6 @@
 			this.update = function () {
 			this.update = function () {
 
 
 				_eye.subVectors( scope.object.position, scope.target );
 				_eye.subVectors( scope.object.position, scope.target );
-
 				if ( ! scope.noRotate ) {
 				if ( ! scope.noRotate ) {
 
 
 					scope.rotateCamera();
 					scope.rotateCamera();
@@ -328,12 +306,10 @@
 				}
 				}
 
 
 				scope.object.position.addVectors( scope.target, _eye );
 				scope.object.position.addVectors( scope.target, _eye );
-
 				if ( scope.object.isPerspectiveCamera ) {
 				if ( scope.object.isPerspectiveCamera ) {
 
 
 					scope.checkDistances();
 					scope.checkDistances();
 					scope.object.lookAt( scope.target );
 					scope.object.lookAt( scope.target );
-
 					if ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) {
 					if ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) {
 
 
 						scope.dispatchEvent( _changeEvent );
 						scope.dispatchEvent( _changeEvent );
@@ -344,7 +320,6 @@
 				} else if ( scope.object.isOrthographicCamera ) {
 				} else if ( scope.object.isOrthographicCamera ) {
 
 
 					scope.object.lookAt( scope.target );
 					scope.object.lookAt( scope.target );
-
 					if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) {
 					if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) {
 
 
 						scope.dispatchEvent( _changeEvent );
 						scope.dispatchEvent( _changeEvent );
@@ -370,32 +345,30 @@
 				scope.object.up.copy( scope.up0 );
 				scope.object.up.copy( scope.up0 );
 				scope.object.zoom = scope.zoom0;
 				scope.object.zoom = scope.zoom0;
 				scope.object.updateProjectionMatrix();
 				scope.object.updateProjectionMatrix();
-
 				_eye.subVectors( scope.object.position, scope.target );
 				_eye.subVectors( scope.object.position, scope.target );
-
 				scope.object.lookAt( scope.target );
 				scope.object.lookAt( scope.target );
 				scope.dispatchEvent( _changeEvent );
 				scope.dispatchEvent( _changeEvent );
 				lastPosition.copy( scope.object.position );
 				lastPosition.copy( scope.object.position );
 				lastZoom = scope.object.zoom;
 				lastZoom = scope.object.zoom;
 
 
-			}; // listeners
+			};
 
 
+			// listeners
 
 
 			function onPointerDown( event ) {
 			function onPointerDown( event ) {
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
-
 				if ( _pointers.length === 0 ) {
 				if ( _pointers.length === 0 ) {
 
 
 					scope.domElement.setPointerCapture( event.pointerId );
 					scope.domElement.setPointerCapture( event.pointerId );
 					scope.domElement.addEventListener( 'pointermove', onPointerMove );
 					scope.domElement.addEventListener( 'pointermove', onPointerMove );
 					scope.domElement.addEventListener( 'pointerup', onPointerUp );
 					scope.domElement.addEventListener( 'pointerup', onPointerUp );
 
 
-				} //
+				}
 
 
+				//
 
 
 				addPointer( event );
 				addPointer( event );
-
 				if ( event.pointerType === 'touch' ) {
 				if ( event.pointerType === 'touch' ) {
 
 
 					onTouchStart( event );
 					onTouchStart( event );
@@ -411,7 +384,6 @@
 			function onPointerMove( event ) {
 			function onPointerMove( event ) {
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
-
 				if ( event.pointerType === 'touch' ) {
 				if ( event.pointerType === 'touch' ) {
 
 
 					onTouchMove( event );
 					onTouchMove( event );
@@ -427,7 +399,6 @@
 			function onPointerUp( event ) {
 			function onPointerUp( event ) {
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
-
 				if ( event.pointerType === 'touch' ) {
 				if ( event.pointerType === 'touch' ) {
 
 
 					onTouchEnd( event );
 					onTouchEnd( event );
@@ -436,11 +407,11 @@
 
 
 					onMouseUp();
 					onMouseUp();
 
 
-				} //
+				}
 
 
+				//
 
 
 				removePointer( event );
 				removePointer( event );
-
 				if ( _pointers.length === 0 ) {
 				if ( _pointers.length === 0 ) {
 
 
 					scope.domElement.releasePointerCapture( event.pointerId );
 					scope.domElement.releasePointerCapture( event.pointerId );
@@ -461,7 +432,6 @@
 
 
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
 				window.removeEventListener( 'keydown', keydown );
 				window.removeEventListener( 'keydown', keydown );
-
 				if ( _keyState !== STATE.NONE ) {
 				if ( _keyState !== STATE.NONE ) {
 
 
 					return;
 					return;
@@ -499,11 +469,9 @@
 						case scope.mouseButtons.LEFT:
 						case scope.mouseButtons.LEFT:
 							_state = STATE.ROTATE;
 							_state = STATE.ROTATE;
 							break;
 							break;
-
 						case scope.mouseButtons.MIDDLE:
 						case scope.mouseButtons.MIDDLE:
 							_state = STATE.ZOOM;
 							_state = STATE.ZOOM;
 							break;
 							break;
-
 						case scope.mouseButtons.RIGHT:
 						case scope.mouseButtons.RIGHT:
 							_state = STATE.PAN;
 							_state = STATE.PAN;
 							break;
 							break;
@@ -513,23 +481,19 @@
 				}
 				}
 
 
 				const state = _keyState !== STATE.NONE ? _keyState : _state;
 				const state = _keyState !== STATE.NONE ? _keyState : _state;
-
 				if ( state === STATE.ROTATE && ! scope.noRotate ) {
 				if ( state === STATE.ROTATE && ! scope.noRotate ) {
 
 
 					_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
 					_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
-
 					_movePrev.copy( _moveCurr );
 					_movePrev.copy( _moveCurr );
 
 
 				} else if ( state === STATE.ZOOM && ! scope.noZoom ) {
 				} else if ( state === STATE.ZOOM && ! scope.noZoom ) {
 
 
 					_zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
 					_zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-
 					_zoomEnd.copy( _zoomStart );
 					_zoomEnd.copy( _zoomStart );
 
 
 				} else if ( state === STATE.PAN && ! scope.noPan ) {
 				} else if ( state === STATE.PAN && ! scope.noPan ) {
 
 
 					_panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
 					_panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
-
 					_panEnd.copy( _panStart );
 					_panEnd.copy( _panStart );
 
 
 				}
 				}
@@ -541,11 +505,9 @@
 			function onMouseMove( event ) {
 			function onMouseMove( event ) {
 
 
 				const state = _keyState !== STATE.NONE ? _keyState : _state;
 				const state = _keyState !== STATE.NONE ? _keyState : _state;
-
 				if ( state === STATE.ROTATE && ! scope.noRotate ) {
 				if ( state === STATE.ROTATE && ! scope.noRotate ) {
 
 
 					_movePrev.copy( _moveCurr );
 					_movePrev.copy( _moveCurr );
-
 					_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
 					_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
 
 
 				} else if ( state === STATE.ZOOM && ! scope.noZoom ) {
 				} else if ( state === STATE.ZOOM && ! scope.noZoom ) {
@@ -572,19 +534,16 @@
 				if ( scope.enabled === false ) return;
 				if ( scope.enabled === false ) return;
 				if ( scope.noZoom === true ) return;
 				if ( scope.noZoom === true ) return;
 				event.preventDefault();
 				event.preventDefault();
-
 				switch ( event.deltaMode ) {
 				switch ( event.deltaMode ) {
 
 
 					case 2:
 					case 2:
 						// Zoom in pages
 						// Zoom in pages
 						_zoomStart.y -= event.deltaY * 0.025;
 						_zoomStart.y -= event.deltaY * 0.025;
 						break;
 						break;
-
 					case 1:
 					case 1:
 						// Zoom in lines
 						// Zoom in lines
 						_zoomStart.y -= event.deltaY * 0.01;
 						_zoomStart.y -= event.deltaY * 0.01;
 						break;
 						break;
-
 					default:
 					default:
 						// undefined, 0, assume pixels
 						// undefined, 0, assume pixels
 						_zoomStart.y -= event.deltaY * 0.00025;
 						_zoomStart.y -= event.deltaY * 0.00025;
@@ -600,18 +559,13 @@
 			function onTouchStart( event ) {
 			function onTouchStart( event ) {
 
 
 				trackPointer( event );
 				trackPointer( event );
-
 				switch ( _pointers.length ) {
 				switch ( _pointers.length ) {
 
 
 					case 1:
 					case 1:
 						_state = STATE.TOUCH_ROTATE;
 						_state = STATE.TOUCH_ROTATE;
-
 						_moveCurr.copy( getMouseOnCircle( _pointers[ 0 ].pageX, _pointers[ 0 ].pageY ) );
 						_moveCurr.copy( getMouseOnCircle( _pointers[ 0 ].pageX, _pointers[ 0 ].pageY ) );
-
 						_movePrev.copy( _moveCurr );
 						_movePrev.copy( _moveCurr );
-
 						break;
 						break;
-
 					default:
 					default:
 						// 2 or more
 						// 2 or more
 						_state = STATE.TOUCH_ZOOM_PAN;
 						_state = STATE.TOUCH_ZOOM_PAN;
@@ -620,11 +574,8 @@
 						_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
 						_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
 						const x = ( _pointers[ 0 ].pageX + _pointers[ 1 ].pageX ) / 2;
 						const x = ( _pointers[ 0 ].pageX + _pointers[ 1 ].pageX ) / 2;
 						const y = ( _pointers[ 0 ].pageY + _pointers[ 1 ].pageY ) / 2;
 						const y = ( _pointers[ 0 ].pageY + _pointers[ 1 ].pageY ) / 2;
-
 						_panStart.copy( getMouseOnScreen( x, y ) );
 						_panStart.copy( getMouseOnScreen( x, y ) );
-
 						_panEnd.copy( _panStart );
 						_panEnd.copy( _panStart );
-
 						break;
 						break;
 
 
 				}
 				}
@@ -636,27 +587,22 @@
 			function onTouchMove( event ) {
 			function onTouchMove( event ) {
 
 
 				trackPointer( event );
 				trackPointer( event );
-
 				switch ( _pointers.length ) {
 				switch ( _pointers.length ) {
 
 
 					case 1:
 					case 1:
 						_movePrev.copy( _moveCurr );
 						_movePrev.copy( _moveCurr );
-
 						_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
 						_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
-
 						break;
 						break;
-
 					default:
 					default:
 						// 2 or more
 						// 2 or more
+
 						const position = getSecondPointerPosition( event );
 						const position = getSecondPointerPosition( event );
 						const dx = event.pageX - position.x;
 						const dx = event.pageX - position.x;
 						const dy = event.pageY - position.y;
 						const dy = event.pageY - position.y;
 						_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
 						_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
 						const x = ( event.pageX + position.x ) / 2;
 						const x = ( event.pageX + position.x ) / 2;
 						const y = ( event.pageY + position.y ) / 2;
 						const y = ( event.pageY + position.y ) / 2;
-
 						_panEnd.copy( getMouseOnScreen( x, y ) );
 						_panEnd.copy( getMouseOnScreen( x, y ) );
-
 						break;
 						break;
 
 
 				}
 				}
@@ -670,29 +616,20 @@
 					case 0:
 					case 0:
 						_state = STATE.NONE;
 						_state = STATE.NONE;
 						break;
 						break;
-
 					case 1:
 					case 1:
 						_state = STATE.TOUCH_ROTATE;
 						_state = STATE.TOUCH_ROTATE;
-
 						_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
 						_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
-
 						_movePrev.copy( _moveCurr );
 						_movePrev.copy( _moveCurr );
-
 						break;
 						break;
-
 					case 2:
 					case 2:
 						_state = STATE.TOUCH_ZOOM_PAN;
 						_state = STATE.TOUCH_ZOOM_PAN;
-
 						for ( let i = 0; i < _pointers.length; i ++ ) {
 						for ( let i = 0; i < _pointers.length; i ++ ) {
 
 
 							if ( _pointers[ i ].pointerId !== event.pointerId ) {
 							if ( _pointers[ i ].pointerId !== event.pointerId ) {
 
 
 								const position = _pointerPositions[ _pointers[ i ].pointerId ];
 								const position = _pointerPositions[ _pointers[ i ].pointerId ];
-
 								_moveCurr.copy( getMouseOnCircle( position.x, position.y ) );
 								_moveCurr.copy( getMouseOnCircle( position.x, position.y ) );
-
 								_movePrev.copy( _moveCurr );
 								_movePrev.copy( _moveCurr );
-
 								break;
 								break;
 
 
 							}
 							}
@@ -723,13 +660,11 @@
 			function removePointer( event ) {
 			function removePointer( event ) {
 
 
 				delete _pointerPositions[ event.pointerId ];
 				delete _pointerPositions[ event.pointerId ];
-
 				for ( let i = 0; i < _pointers.length; i ++ ) {
 				for ( let i = 0; i < _pointers.length; i ++ ) {
 
 
 					if ( _pointers[ i ].pointerId == event.pointerId ) {
 					if ( _pointers[ i ].pointerId == event.pointerId ) {
 
 
 						_pointers.splice( i, 1 );
 						_pointers.splice( i, 1 );
-
 						return;
 						return;
 
 
 					}
 					}
@@ -741,7 +676,6 @@
 			function trackPointer( event ) {
 			function trackPointer( event ) {
 
 
 				let position = _pointerPositions[ event.pointerId ];
 				let position = _pointerPositions[ event.pointerId ];
-
 				if ( position === undefined ) {
 				if ( position === undefined ) {
 
 
 					position = new THREE.Vector2();
 					position = new THREE.Vector2();
@@ -781,8 +715,9 @@
 			} );
 			} );
 			window.addEventListener( 'keydown', keydown );
 			window.addEventListener( 'keydown', keydown );
 			window.addEventListener( 'keyup', keyup );
 			window.addEventListener( 'keyup', keyup );
-			this.handleResize(); // force an update at start
+			this.handleResize();
 
 
+			// force an update at start
 			this.update();
 			this.update();
 
 
 		}
 		}

+ 84 - 169
examples/js/controls/TransformControls.js

@@ -1,13 +1,9 @@
 ( function () {
 ( function () {
 
 
 	const _raycaster = new THREE.Raycaster();
 	const _raycaster = new THREE.Raycaster();
-
 	const _tempVector = new THREE.Vector3();
 	const _tempVector = new THREE.Vector3();
-
 	const _tempVector2 = new THREE.Vector3();
 	const _tempVector2 = new THREE.Vector3();
-
 	const _tempQuaternion = new THREE.Quaternion();
 	const _tempQuaternion = new THREE.Quaternion();
-
 	const _unit = {
 	const _unit = {
 		X: new THREE.Vector3( 1, 0, 0 ),
 		X: new THREE.Vector3( 1, 0, 0 ),
 		Y: new THREE.Vector3( 0, 1, 0 ),
 		Y: new THREE.Vector3( 0, 1, 0 ),
@@ -26,13 +22,11 @@
 	const _objectChangeEvent = {
 	const _objectChangeEvent = {
 		type: 'objectChange'
 		type: 'objectChange'
 	};
 	};
-
 	class TransformControls extends THREE.Object3D {
 	class TransformControls extends THREE.Object3D {
 
 
 		constructor( camera, domElement ) {
 		constructor( camera, domElement ) {
 
 
 			super();
 			super();
-
 			if ( domElement === undefined ) {
 			if ( domElement === undefined ) {
 
 
 				console.warn( 'THREE.TransformControls: The second parameter "domElement" is now mandatory.' );
 				console.warn( 'THREE.TransformControls: The second parameter "domElement" is now mandatory.' );
@@ -46,16 +40,14 @@
 			this.domElement.style.touchAction = 'none'; // disable touch scroll
 			this.domElement.style.touchAction = 'none'; // disable touch scroll
 
 
 			const _gizmo = new TransformControlsGizmo();
 			const _gizmo = new TransformControlsGizmo();
-
 			this._gizmo = _gizmo;
 			this._gizmo = _gizmo;
 			this.add( _gizmo );
 			this.add( _gizmo );
-
 			const _plane = new TransformControlsPlane();
 			const _plane = new TransformControlsPlane();
-
 			this._plane = _plane;
 			this._plane = _plane;
 			this.add( _plane );
 			this.add( _plane );
-			const scope = this; // Defined getter, setter and store for a property
+			const scope = this;
 
 
+			// Defined getter, setter and store for a property
 			function defineProperty( propName, defaultValue ) {
 			function defineProperty( propName, defaultValue ) {
 
 
 				let propValue = defaultValue;
 				let propValue = defaultValue;
@@ -86,11 +78,12 @@
 				_plane[ propName ] = defaultValue;
 				_plane[ propName ] = defaultValue;
 				_gizmo[ propName ] = defaultValue;
 				_gizmo[ propName ] = defaultValue;
 
 
-			} // Define properties with getters/setter
+			}
+
+			// Define properties with getters/setter
 			// Setting the defined property will automatically trigger change event
 			// Setting the defined property will automatically trigger change event
 			// Defined properties are passed down to gizmo and plane
 			// Defined properties are passed down to gizmo and plane
 
 
-
 			defineProperty( 'camera', camera );
 			defineProperty( 'camera', camera );
 			defineProperty( 'object', undefined );
 			defineProperty( 'object', undefined );
 			defineProperty( 'enabled', true );
 			defineProperty( 'enabled', true );
@@ -104,7 +97,9 @@
 			defineProperty( 'dragging', false );
 			defineProperty( 'dragging', false );
 			defineProperty( 'showX', true );
 			defineProperty( 'showX', true );
 			defineProperty( 'showY', true );
 			defineProperty( 'showY', true );
-			defineProperty( 'showZ', true ); // Reusable utility variables
+			defineProperty( 'showZ', true );
+
+			// Reusable utility variables
 
 
 			const worldPosition = new THREE.Vector3();
 			const worldPosition = new THREE.Vector3();
 			const worldPositionStart = new THREE.Vector3();
 			const worldPositionStart = new THREE.Vector3();
@@ -116,7 +111,9 @@
 			const pointEnd = new THREE.Vector3();
 			const pointEnd = new THREE.Vector3();
 			const rotationAxis = new THREE.Vector3();
 			const rotationAxis = new THREE.Vector3();
 			const rotationAngle = 0;
 			const rotationAngle = 0;
-			const eye = new THREE.Vector3(); // TODO: remove properties unused in plane and gizmo
+			const eye = new THREE.Vector3();
+
+			// TODO: remove properties unused in plane and gizmo
 
 
 			defineProperty( 'worldPosition', worldPosition );
 			defineProperty( 'worldPosition', worldPosition );
 			defineProperty( 'worldPositionStart', worldPositionStart );
 			defineProperty( 'worldPositionStart', worldPositionStart );
@@ -152,15 +149,14 @@
 			this.domElement.addEventListener( 'pointermove', this._onPointerHover );
 			this.domElement.addEventListener( 'pointermove', this._onPointerHover );
 			this.domElement.addEventListener( 'pointerup', this._onPointerUp );
 			this.domElement.addEventListener( 'pointerup', this._onPointerUp );
 
 
-		} // updateMatrixWorld  updates key transformation variables
-
+		}
 
 
+		// updateMatrixWorld  updates key transformation variables
 		updateMatrixWorld() {
 		updateMatrixWorld() {
 
 
 			if ( this.object !== undefined ) {
 			if ( this.object !== undefined ) {
 
 
 				this.object.updateMatrixWorld();
 				this.object.updateMatrixWorld();
-
 				if ( this.object.parent === null ) {
 				if ( this.object.parent === null ) {
 
 
 					console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );
 					console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );
@@ -172,16 +168,13 @@
 				}
 				}
 
 
 				this.object.matrixWorld.decompose( this.worldPosition, this.worldQuaternion, this._worldScale );
 				this.object.matrixWorld.decompose( this.worldPosition, this.worldQuaternion, this._worldScale );
-
 				this._parentQuaternionInv.copy( this._parentQuaternion ).invert();
 				this._parentQuaternionInv.copy( this._parentQuaternion ).invert();
-
 				this._worldQuaternionInv.copy( this.worldQuaternion ).invert();
 				this._worldQuaternionInv.copy( this.worldQuaternion ).invert();
 
 
 			}
 			}
 
 
 			this.camera.updateMatrixWorld();
 			this.camera.updateMatrixWorld();
 			this.camera.matrixWorld.decompose( this.cameraPosition, this.cameraQuaternion, this._cameraScale );
 			this.camera.matrixWorld.decompose( this.cameraPosition, this.cameraQuaternion, this._cameraScale );
-
 			if ( this.camera.isOrthographicCamera ) {
 			if ( this.camera.isOrthographicCamera ) {
 
 
 				this.camera.getWorldDirection( this.eye ).negate();
 				this.camera.getWorldDirection( this.eye ).negate();
@@ -195,15 +188,11 @@
 			super.updateMatrixWorld( this );
 			super.updateMatrixWorld( this );
 
 
 		}
 		}
-
 		pointerHover( pointer ) {
 		pointerHover( pointer ) {
 
 
 			if ( this.object === undefined || this.dragging === true ) return;
 			if ( this.object === undefined || this.dragging === true ) return;
-
 			_raycaster.setFromCamera( pointer, this.camera );
 			_raycaster.setFromCamera( pointer, this.camera );
-
 			const intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );
 			const intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );
-
 			if ( intersect ) {
 			if ( intersect ) {
 
 
 				this.axis = intersect.object.name;
 				this.axis = intersect.object.name;
@@ -215,28 +204,20 @@
 			}
 			}
 
 
 		}
 		}
-
 		pointerDown( pointer ) {
 		pointerDown( pointer ) {
 
 
 			if ( this.object === undefined || this.dragging === true || pointer.button !== 0 ) return;
 			if ( this.object === undefined || this.dragging === true || pointer.button !== 0 ) return;
-
 			if ( this.axis !== null ) {
 			if ( this.axis !== null ) {
 
 
 				_raycaster.setFromCamera( pointer, this.camera );
 				_raycaster.setFromCamera( pointer, this.camera );
-
 				const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
 				const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
-
 				if ( planeIntersect ) {
 				if ( planeIntersect ) {
 
 
 					this.object.updateMatrixWorld();
 					this.object.updateMatrixWorld();
 					this.object.parent.updateMatrixWorld();
 					this.object.parent.updateMatrixWorld();
-
 					this._positionStart.copy( this.object.position );
 					this._positionStart.copy( this.object.position );
-
 					this._quaternionStart.copy( this.object.quaternion );
 					this._quaternionStart.copy( this.object.quaternion );
-
 					this._scaleStart.copy( this.object.scale );
 					this._scaleStart.copy( this.object.scale );
-
 					this.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart );
 					this.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart );
 					this.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart );
 					this.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart );
 
 
@@ -249,14 +230,12 @@
 			}
 			}
 
 
 		}
 		}
-
 		pointerMove( pointer ) {
 		pointerMove( pointer ) {
 
 
 			const axis = this.axis;
 			const axis = this.axis;
 			const mode = this.mode;
 			const mode = this.mode;
 			const object = this.object;
 			const object = this.object;
 			let space = this.space;
 			let space = this.space;
-
 			if ( mode === 'scale' ) {
 			if ( mode === 'scale' ) {
 
 
 				space = 'local';
 				space = 'local';
@@ -268,18 +247,15 @@
 			}
 			}
 
 
 			if ( object === undefined || axis === null || this.dragging === false || pointer.button !== - 1 ) return;
 			if ( object === undefined || axis === null || this.dragging === false || pointer.button !== - 1 ) return;
-
 			_raycaster.setFromCamera( pointer, this.camera );
 			_raycaster.setFromCamera( pointer, this.camera );
-
 			const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
 			const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
 			if ( ! planeIntersect ) return;
 			if ( ! planeIntersect ) return;
 			this.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart );
 			this.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart );
-
 			if ( mode === 'translate' ) {
 			if ( mode === 'translate' ) {
 
 
 				// Apply translate
 				// Apply translate
-				this._offset.copy( this.pointEnd ).sub( this.pointStart );
 
 
+				this._offset.copy( this.pointEnd ).sub( this.pointStart );
 				if ( space === 'local' && axis !== 'XYZ' ) {
 				if ( space === 'local' && axis !== 'XYZ' ) {
 
 
 					this._offset.applyQuaternion( this._worldQuaternionInv );
 					this._offset.applyQuaternion( this._worldQuaternionInv );
@@ -289,7 +265,6 @@
 				if ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0;
 				if ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0;
 				if ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0;
 				if ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0;
 				if ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0;
 				if ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0;
-
 				if ( space === 'local' && axis !== 'XYZ' ) {
 				if ( space === 'local' && axis !== 'XYZ' ) {
 
 
 					this._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale );
 					this._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale );
@@ -300,14 +275,15 @@
 
 
 				}
 				}
 
 
-				object.position.copy( this._offset ).add( this._positionStart ); // Apply translation snap
+				object.position.copy( this._offset ).add( this._positionStart );
+
+				// Apply translation snap
 
 
 				if ( this.translationSnap ) {
 				if ( this.translationSnap ) {
 
 
 					if ( space === 'local' ) {
 					if ( space === 'local' ) {
 
 
 						object.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() );
 						object.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() );
-
 						if ( axis.search( 'X' ) !== - 1 ) {
 						if ( axis.search( 'X' ) !== - 1 ) {
 
 
 							object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
 							object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
@@ -372,21 +348,15 @@
 
 
 					let d = this.pointEnd.length() / this.pointStart.length();
 					let d = this.pointEnd.length() / this.pointStart.length();
 					if ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1;
 					if ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1;
-
 					_tempVector2.set( d, d, d );
 					_tempVector2.set( d, d, d );
 
 
 				} else {
 				} else {
 
 
 					_tempVector.copy( this.pointStart );
 					_tempVector.copy( this.pointStart );
-
 					_tempVector2.copy( this.pointEnd );
 					_tempVector2.copy( this.pointEnd );
-
 					_tempVector.applyQuaternion( this._worldQuaternionInv );
 					_tempVector.applyQuaternion( this._worldQuaternionInv );
-
 					_tempVector2.applyQuaternion( this._worldQuaternionInv );
 					_tempVector2.applyQuaternion( this._worldQuaternionInv );
-
 					_tempVector2.divide( _tempVector );
 					_tempVector2.divide( _tempVector );
-
 					if ( axis.search( 'X' ) === - 1 ) {
 					if ( axis.search( 'X' ) === - 1 ) {
 
 
 						_tempVector2.x = 1;
 						_tempVector2.x = 1;
@@ -405,11 +375,11 @@
 
 
 					}
 					}
 
 
-				} // Apply scale
+				}
 
 
+				// Apply scale
 
 
 				object.scale.copy( this._scaleStart ).multiply( _tempVector2 );
 				object.scale.copy( this._scaleStart ).multiply( _tempVector2 );
-
 				if ( this.scaleSnap ) {
 				if ( this.scaleSnap ) {
 
 
 					if ( axis.search( 'X' ) !== - 1 ) {
 					if ( axis.search( 'X' ) !== - 1 ) {
@@ -435,18 +405,13 @@
 			} else if ( mode === 'rotate' ) {
 			} else if ( mode === 'rotate' ) {
 
 
 				this._offset.copy( this.pointEnd ).sub( this.pointStart );
 				this._offset.copy( this.pointEnd ).sub( this.pointStart );
-
 				const ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
 				const ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
-
 				if ( axis === 'E' ) {
 				if ( axis === 'E' ) {
 
 
 					this.rotationAxis.copy( this.eye );
 					this.rotationAxis.copy( this.eye );
 					this.rotationAngle = this.pointEnd.angleTo( this.pointStart );
 					this.rotationAngle = this.pointEnd.angleTo( this.pointStart );
-
 					this._startNorm.copy( this.pointStart ).normalize();
 					this._startNorm.copy( this.pointStart ).normalize();
-
 					this._endNorm.copy( this.pointEnd ).normalize();
 					this._endNorm.copy( this.pointEnd ).normalize();
-
 					this.rotationAngle *= this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1;
 					this.rotationAngle *= this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1;
 
 
 				} else if ( axis === 'XYZE' ) {
 				} else if ( axis === 'XYZE' ) {
@@ -457,9 +422,7 @@
 				} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {
 				} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {
 
 
 					this.rotationAxis.copy( _unit[ axis ] );
 					this.rotationAxis.copy( _unit[ axis ] );
-
 					_tempVector.copy( _unit[ axis ] );
 					_tempVector.copy( _unit[ axis ] );
-
 					if ( space === 'local' ) {
 					if ( space === 'local' ) {
 
 
 						_tempVector.applyQuaternion( this.worldQuaternion );
 						_tempVector.applyQuaternion( this.worldQuaternion );
@@ -468,11 +431,13 @@
 
 
 					this.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED;
 					this.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED;
 
 
-				} // Apply rotation snap
+				}
 
 
+				// Apply rotation snap
 
 
-				if ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap; // Apply rotate
+				if ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap;
 
 
+				// Apply rotate
 				if ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {
 				if ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {
 
 
 					object.quaternion.copy( this._quaternionStart );
 					object.quaternion.copy( this._quaternionStart );
@@ -492,11 +457,9 @@
 			this.dispatchEvent( _objectChangeEvent );
 			this.dispatchEvent( _objectChangeEvent );
 
 
 		}
 		}
-
 		pointerUp( pointer ) {
 		pointerUp( pointer ) {
 
 
 			if ( pointer.button !== 0 ) return;
 			if ( pointer.button !== 0 ) return;
-
 			if ( this.dragging && this.axis !== null ) {
 			if ( this.dragging && this.axis !== null ) {
 
 
 				_mouseUpEvent.mode = this.mode;
 				_mouseUpEvent.mode = this.mode;
@@ -508,7 +471,6 @@
 			this.axis = null;
 			this.axis = null;
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
 			this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
@@ -522,18 +484,18 @@
 
 
 			} );
 			} );
 
 
-		} // Set current object
-
+		}
 
 
+		// Set current object
 		attach( object ) {
 		attach( object ) {
 
 
 			this.object = object;
 			this.object = object;
 			this.visible = true;
 			this.visible = true;
 			return this;
 			return this;
 
 
-		} // Detach from object
-
+		}
 
 
+		// Detach from object
 		detach() {
 		detach() {
 
 
 			this.object = undefined;
 			this.object = undefined;
@@ -542,11 +504,9 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		reset() {
 		reset() {
 
 
 			if ( ! this.enabled ) return;
 			if ( ! this.enabled ) return;
-
 			if ( this.dragging ) {
 			if ( this.dragging ) {
 
 
 				this.object.position.copy( this._positionStart );
 				this.object.position.copy( this._positionStart );
@@ -559,58 +519,53 @@
 			}
 			}
 
 
 		}
 		}
-
 		getRaycaster() {
 		getRaycaster() {
 
 
 			return _raycaster;
 			return _raycaster;
 
 
-		} // TODO: deprecate
+		}
 
 
+		// TODO: deprecate
 
 
 		getMode() {
 		getMode() {
 
 
 			return this.mode;
 			return this.mode;
 
 
 		}
 		}
-
 		setMode( mode ) {
 		setMode( mode ) {
 
 
 			this.mode = mode;
 			this.mode = mode;
 
 
 		}
 		}
-
 		setTranslationSnap( translationSnap ) {
 		setTranslationSnap( translationSnap ) {
 
 
 			this.translationSnap = translationSnap;
 			this.translationSnap = translationSnap;
 
 
 		}
 		}
-
 		setRotationSnap( rotationSnap ) {
 		setRotationSnap( rotationSnap ) {
 
 
 			this.rotationSnap = rotationSnap;
 			this.rotationSnap = rotationSnap;
 
 
 		}
 		}
-
 		setScaleSnap( scaleSnap ) {
 		setScaleSnap( scaleSnap ) {
 
 
 			this.scaleSnap = scaleSnap;
 			this.scaleSnap = scaleSnap;
 
 
 		}
 		}
-
 		setSize( size ) {
 		setSize( size ) {
 
 
 			this.size = size;
 			this.size = size;
 
 
 		}
 		}
-
 		setSpace( space ) {
 		setSpace( space ) {
 
 
 			this.space = space;
 			this.space = space;
 
 
 		}
 		}
 
 
-	} // mouse / touch event handlers
+	}
 
 
+	// mouse / touch event handlers
 
 
 	function getPointer( event ) {
 	function getPointer( event ) {
 
 
@@ -638,7 +593,6 @@
 	function onPointerHover( event ) {
 	function onPointerHover( event ) {
 
 
 		if ( ! this.enabled ) return;
 		if ( ! this.enabled ) return;
-
 		switch ( event.pointerType ) {
 		switch ( event.pointerType ) {
 
 
 			case 'mouse':
 			case 'mouse':
@@ -653,7 +607,6 @@
 	function onPointerDown( event ) {
 	function onPointerDown( event ) {
 
 
 		if ( ! this.enabled ) return;
 		if ( ! this.enabled ) return;
-
 		if ( ! document.pointerLockElement ) {
 		if ( ! document.pointerLockElement ) {
 
 
 			this.domElement.setPointerCapture( event.pointerId );
 			this.domElement.setPointerCapture( event.pointerId );
@@ -685,7 +638,6 @@
 	function intersectObjectWithRay( object, raycaster, includeInvisible ) {
 	function intersectObjectWithRay( object, raycaster, includeInvisible ) {
 
 
 		const allIntersections = raycaster.intersectObject( object, true );
 		const allIntersections = raycaster.intersectObject( object, true );
-
 		for ( let i = 0; i < allIntersections.length; i ++ ) {
 		for ( let i = 0; i < allIntersections.length; i ++ ) {
 
 
 			if ( allIntersections[ i ].object.visible || includeInvisible ) {
 			if ( allIntersections[ i ].object.visible || includeInvisible ) {
@@ -698,45 +650,35 @@
 
 
 		return false;
 		return false;
 
 
-	} //
-	// Reusable utility variables
+	}
 
 
+	//
 
 
-	const _tempEuler = new THREE.Euler();
+	// Reusable utility variables
 
 
+	const _tempEuler = new THREE.Euler();
 	const _alignVector = new THREE.Vector3( 0, 1, 0 );
 	const _alignVector = new THREE.Vector3( 0, 1, 0 );
-
 	const _zeroVector = new THREE.Vector3( 0, 0, 0 );
 	const _zeroVector = new THREE.Vector3( 0, 0, 0 );
-
 	const _lookAtMatrix = new THREE.Matrix4();
 	const _lookAtMatrix = new THREE.Matrix4();
-
 	const _tempQuaternion2 = new THREE.Quaternion();
 	const _tempQuaternion2 = new THREE.Quaternion();
-
 	const _identityQuaternion = new THREE.Quaternion();
 	const _identityQuaternion = new THREE.Quaternion();
-
 	const _dirVector = new THREE.Vector3();
 	const _dirVector = new THREE.Vector3();
-
 	const _tempMatrix = new THREE.Matrix4();
 	const _tempMatrix = new THREE.Matrix4();
-
 	const _unitX = new THREE.Vector3( 1, 0, 0 );
 	const _unitX = new THREE.Vector3( 1, 0, 0 );
-
 	const _unitY = new THREE.Vector3( 0, 1, 0 );
 	const _unitY = new THREE.Vector3( 0, 1, 0 );
-
 	const _unitZ = new THREE.Vector3( 0, 0, 1 );
 	const _unitZ = new THREE.Vector3( 0, 0, 1 );
-
 	const _v1 = new THREE.Vector3();
 	const _v1 = new THREE.Vector3();
-
 	const _v2 = new THREE.Vector3();
 	const _v2 = new THREE.Vector3();
-
 	const _v3 = new THREE.Vector3();
 	const _v3 = new THREE.Vector3();
-
 	class TransformControlsGizmo extends THREE.Object3D {
 	class TransformControlsGizmo extends THREE.Object3D {
 
 
 		constructor() {
 		constructor() {
 
 
 			super();
 			super();
 			this.isTransformControlsGizmo = true;
 			this.isTransformControlsGizmo = true;
-			this.type = 'TransformControlsGizmo'; // shared materials
+			this.type = 'TransformControlsGizmo';
+
+			// shared materials
 
 
 			const gizmoMaterial = new THREE.MeshBasicMaterial( {
 			const gizmoMaterial = new THREE.MeshBasicMaterial( {
 				depthTest: false,
 				depthTest: false,
@@ -751,7 +693,9 @@
 				fog: false,
 				fog: false,
 				toneMapped: false,
 				toneMapped: false,
 				transparent: true
 				transparent: true
-			} ); // Make unique material for each axis/color
+			} );
+
+			// Make unique material for each axis/color
 
 
 			const matInvisible = gizmoMaterial.clone();
 			const matInvisible = gizmoMaterial.clone();
 			matInvisible.opacity = 0.15;
 			matInvisible.opacity = 0.15;
@@ -780,7 +724,9 @@
 			const matYellow = gizmoMaterial.clone();
 			const matYellow = gizmoMaterial.clone();
 			matYellow.color.setHex( 0xffff00 );
 			matYellow.color.setHex( 0xffff00 );
 			const matGray = gizmoMaterial.clone();
 			const matGray = gizmoMaterial.clone();
-			matGray.color.setHex( 0x787878 ); // reusable geometry
+			matGray.color.setHex( 0x787878 );
+
+			// reusable geometry
 
 
 			const arrowGeometry = new THREE.CylinderGeometry( 0, 0.04, 0.1, 12 );
 			const arrowGeometry = new THREE.CylinderGeometry( 0, 0.04, 0.1, 12 );
 			arrowGeometry.translate( 0, 0.05, 0 );
 			arrowGeometry.translate( 0, 0.05, 0 );
@@ -790,7 +736,6 @@
 			lineGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 0, 0 ], 3 ) );
 			lineGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 0, 0 ], 3 ) );
 			const lineGeometry2 = new THREE.CylinderGeometry( 0.0075, 0.0075, 0.5, 3 );
 			const lineGeometry2 = new THREE.CylinderGeometry( 0.0075, 0.0075, 0.5, 3 );
 			lineGeometry2.translate( 0, 0.25, 0 );
 			lineGeometry2.translate( 0, 0.25, 0 );
-
 			function CircleGeometry( radius, arc ) {
 			function CircleGeometry( radius, arc ) {
 
 
 				const geometry = new THREE.TorusGeometry( radius, 0.0075, 3, 64, arc * Math.PI * 2 );
 				const geometry = new THREE.TorusGeometry( radius, 0.0075, 3, 64, arc * Math.PI * 2 );
@@ -798,8 +743,9 @@
 				geometry.rotateX( Math.PI / 2 );
 				geometry.rotateX( Math.PI / 2 );
 				return geometry;
 				return geometry;
 
 
-			} // Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position
+			}
 
 
+			// Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position
 
 
 			function TranslateHelperGeometry() {
 			function TranslateHelperGeometry() {
 
 
@@ -807,8 +753,9 @@
 				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) );
 				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) );
 				return geometry;
 				return geometry;
 
 
-			} // Gizmo definitions - custom hierarchy definitions for setupGizmo() function
+			}
 
 
+			// Gizmo definitions - custom hierarchy definitions for setupGizmo() function
 
 
 			const gizmoTranslate = {
 			const gizmoTranslate = {
 				X: [[ new THREE.Mesh( arrowGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( arrowGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]], [ new THREE.Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]],
 				X: [[ new THREE.Mesh( arrowGeometry, matRed ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( arrowGeometry, matRed ), [ - 0.5, 0, 0 ], [ 0, 0, Math.PI / 2 ]], [ new THREE.Mesh( lineGeometry2, matRed ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]],
@@ -875,12 +822,13 @@
 				X: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]],
 				X: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]],
 				Y: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]],
 				Y: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]],
 				Z: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]]
 				Z: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]]
-			}; // Creates an THREE.Object3D with gizmos described in custom hierarchy definition.
+			};
+
+			// Creates an THREE.Object3D with gizmos described in custom hierarchy definition.
 
 
 			function setupGizmo( gizmoMap ) {
 			function setupGizmo( gizmoMap ) {
 
 
 				const gizmo = new THREE.Object3D();
 				const gizmo = new THREE.Object3D();
-
 				for ( const name in gizmoMap ) {
 				for ( const name in gizmoMap ) {
 
 
 					for ( let i = gizmoMap[ name ].length; i --; ) {
 					for ( let i = gizmoMap[ name ].length; i --; ) {
@@ -889,11 +837,11 @@
 						const position = gizmoMap[ name ][ i ][ 1 ];
 						const position = gizmoMap[ name ][ i ][ 1 ];
 						const rotation = gizmoMap[ name ][ i ][ 2 ];
 						const rotation = gizmoMap[ name ][ i ][ 2 ];
 						const scale = gizmoMap[ name ][ i ][ 3 ];
 						const scale = gizmoMap[ name ][ i ][ 3 ];
-						const tag = gizmoMap[ name ][ i ][ 4 ]; // name and tag properties are essential for picking and updating logic.
+						const tag = gizmoMap[ name ][ i ][ 4 ];
 
 
+						// name and tag properties are essential for picking and updating logic.
 						object.name = name;
 						object.name = name;
 						object.tag = tag;
 						object.tag = tag;
-
 						if ( position ) {
 						if ( position ) {
 
 
 							object.position.set( position[ 0 ], position[ 1 ], position[ 2 ] );
 							object.position.set( position[ 0 ], position[ 1 ], position[ 2 ] );
@@ -928,8 +876,9 @@
 
 
 				return gizmo;
 				return gizmo;
 
 
-			} // Gizmo creation
+			}
 
 
+			// Gizmo creation
 
 
 			this.gizmo = {};
 			this.gizmo = {};
 			this.picker = {};
 			this.picker = {};
@@ -942,20 +891,25 @@
 			this.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) );
 			this.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) );
 			this.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) );
 			this.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) );
 			this.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) );
 			this.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) );
-			this.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) ); // Pickers should be hidden always
+			this.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) );
+
+			// Pickers should be hidden always
 
 
 			this.picker[ 'translate' ].visible = false;
 			this.picker[ 'translate' ].visible = false;
 			this.picker[ 'rotate' ].visible = false;
 			this.picker[ 'rotate' ].visible = false;
 			this.picker[ 'scale' ].visible = false;
 			this.picker[ 'scale' ].visible = false;
 
 
-		} // updateMatrixWorld will update transformations and appearance of individual handles
+		}
 
 
+		// updateMatrixWorld will update transformations and appearance of individual handles
 
 
 		updateMatrixWorld( force ) {
 		updateMatrixWorld( force ) {
 
 
 			const space = this.mode === 'scale' ? 'local' : this.space; // scale always oriented to local rotation
 			const space = this.mode === 'scale' ? 'local' : this.space; // scale always oriented to local rotation
 
 
-			const quaternion = space === 'local' ? this.worldQuaternion : _identityQuaternion; // Show only gizmos for current transform mode
+			const quaternion = space === 'local' ? this.worldQuaternion : _identityQuaternion;
+
+			// Show only gizmos for current transform mode
 
 
 			this.gizmo[ 'translate' ].visible = this.mode === 'translate';
 			this.gizmo[ 'translate' ].visible = this.mode === 'translate';
 			this.gizmo[ 'rotate' ].visible = this.mode === 'rotate';
 			this.gizmo[ 'rotate' ].visible = this.mode === 'rotate';
@@ -967,16 +921,16 @@
 			handles = handles.concat( this.picker[ this.mode ].children );
 			handles = handles.concat( this.picker[ this.mode ].children );
 			handles = handles.concat( this.gizmo[ this.mode ].children );
 			handles = handles.concat( this.gizmo[ this.mode ].children );
 			handles = handles.concat( this.helper[ this.mode ].children );
 			handles = handles.concat( this.helper[ this.mode ].children );
-
 			for ( let i = 0; i < handles.length; i ++ ) {
 			for ( let i = 0; i < handles.length; i ++ ) {
 
 
-				const handle = handles[ i ]; // hide aligned to camera
+				const handle = handles[ i ];
+
+				// hide aligned to camera
 
 
 				handle.visible = true;
 				handle.visible = true;
 				handle.rotation.set( 0, 0, 0 );
 				handle.rotation.set( 0, 0, 0 );
 				handle.position.copy( this.worldPosition );
 				handle.position.copy( this.worldPosition );
 				let factor;
 				let factor;
-
 				if ( this.camera.isOrthographicCamera ) {
 				if ( this.camera.isOrthographicCamera ) {
 
 
 					factor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;
 					factor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;
@@ -987,23 +941,21 @@
 
 
 				}
 				}
 
 
-				handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 ); // TODO: simplify helpers and consider decoupling from gizmo
+				handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 4 );
+
+				// TODO: simplify helpers and consider decoupling from gizmo
 
 
 				if ( handle.tag === 'helper' ) {
 				if ( handle.tag === 'helper' ) {
 
 
 					handle.visible = false;
 					handle.visible = false;
-
 					if ( handle.name === 'AXIS' ) {
 					if ( handle.name === 'AXIS' ) {
 
 
 						handle.position.copy( this.worldPositionStart );
 						handle.position.copy( this.worldPositionStart );
 						handle.visible = !! this.axis;
 						handle.visible = !! this.axis;
-
 						if ( this.axis === 'X' ) {
 						if ( this.axis === 'X' ) {
 
 
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) );
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) );
-
 							handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
 							handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
-
 							if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
 							if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
 
 
 								handle.visible = false;
 								handle.visible = false;
@@ -1015,9 +967,7 @@
 						if ( this.axis === 'Y' ) {
 						if ( this.axis === 'Y' ) {
 
 
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) );
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) );
-
 							handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
 							handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
-
 							if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
 							if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
 
 
 								handle.visible = false;
 								handle.visible = false;
@@ -1029,9 +979,7 @@
 						if ( this.axis === 'Z' ) {
 						if ( this.axis === 'Z' ) {
 
 
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
-
 							handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
 							handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
-
 							if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
 							if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
 
 
 								handle.visible = false;
 								handle.visible = false;
@@ -1043,9 +991,7 @@
 						if ( this.axis === 'XYZE' ) {
 						if ( this.axis === 'XYZE' ) {
 
 
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
 							_tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
-
 							_alignVector.copy( this.rotationAxis );
 							_alignVector.copy( this.rotationAxis );
-
 							handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) );
 							handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) );
 							handle.quaternion.multiply( _tempQuaternion );
 							handle.quaternion.multiply( _tempQuaternion );
 							handle.visible = this.dragging;
 							handle.visible = this.dragging;
@@ -1072,18 +1018,14 @@
 
 
 						handle.position.copy( this.worldPositionStart );
 						handle.position.copy( this.worldPositionStart );
 						handle.quaternion.copy( this.worldQuaternionStart );
 						handle.quaternion.copy( this.worldQuaternionStart );
-
 						_tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 );
 						_tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 );
-
 						_tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() );
 						_tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() );
-
 						handle.scale.copy( _tempVector );
 						handle.scale.copy( _tempVector );
 						handle.visible = this.dragging;
 						handle.visible = this.dragging;
 
 
 					} else {
 					} else {
 
 
 						handle.quaternion.copy( quaternion );
 						handle.quaternion.copy( quaternion );
-
 						if ( this.dragging ) {
 						if ( this.dragging ) {
 
 
 							handle.position.copy( this.worldPositionStart );
 							handle.position.copy( this.worldPositionStart );
@@ -1100,22 +1042,22 @@
 
 
 						}
 						}
 
 
-					} // If updating helper, skip rest of the loop
-
+					}
 
 
+					// If updating helper, skip rest of the loop
 					continue;
 					continue;
 
 
-				} // Align handles to current local or world rotation
+				}
 
 
+				// Align handles to current local or world rotation
 
 
 				handle.quaternion.copy( quaternion );
 				handle.quaternion.copy( quaternion );
-
 				if ( this.mode === 'translate' || this.mode === 'scale' ) {
 				if ( this.mode === 'translate' || this.mode === 'scale' ) {
 
 
 					// Hide translate and scale axis facing the camera
 					// Hide translate and scale axis facing the camera
+
 					const AXIS_HIDE_THRESHOLD = 0.99;
 					const AXIS_HIDE_THRESHOLD = 0.99;
 					const PLANE_HIDE_THRESHOLD = 0.2;
 					const PLANE_HIDE_THRESHOLD = 0.2;
-
 					if ( handle.name === 'X' ) {
 					if ( handle.name === 'X' ) {
 
 
 						if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {
 						if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_THRESHOLD ) {
@@ -1185,10 +1127,9 @@
 				} else if ( this.mode === 'rotate' ) {
 				} else if ( this.mode === 'rotate' ) {
 
 
 					// Align handles to current local or world rotation
 					// Align handles to current local or world rotation
-					_tempQuaternion2.copy( quaternion );
 
 
+					_tempQuaternion2.copy( quaternion );
 					_alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() );
 					_alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() );
-
 					if ( handle.name.search( 'E' ) !== - 1 ) {
 					if ( handle.name.search( 'E' ) !== - 1 ) {
 
 
 						handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) );
 						handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) );
@@ -1198,9 +1139,7 @@
 					if ( handle.name === 'X' ) {
 					if ( handle.name === 'X' ) {
 
 
 						_tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) );
 						_tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) );
-
 						_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
 						_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
-
 						handle.quaternion.copy( _tempQuaternion );
 						handle.quaternion.copy( _tempQuaternion );
 
 
 					}
 					}
@@ -1208,9 +1147,7 @@
 					if ( handle.name === 'Y' ) {
 					if ( handle.name === 'Y' ) {
 
 
 						_tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) );
 						_tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) );
-
 						_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
 						_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
-
 						handle.quaternion.copy( _tempQuaternion );
 						handle.quaternion.copy( _tempQuaternion );
 
 
 					}
 					}
@@ -1218,26 +1155,25 @@
 					if ( handle.name === 'Z' ) {
 					if ( handle.name === 'Z' ) {
 
 
 						_tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) );
 						_tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) );
-
 						_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
 						_tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
-
 						handle.quaternion.copy( _tempQuaternion );
 						handle.quaternion.copy( _tempQuaternion );
 
 
 					}
 					}
 
 
-				} // Hide disabled axes
-
+				}
 
 
+				// Hide disabled axes
 				handle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX );
 				handle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX );
 				handle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY );
 				handle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY );
 				handle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ );
 				handle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ );
-				handle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || this.showX && this.showY && this.showZ ); // highlight selected axis
+				handle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || this.showX && this.showY && this.showZ );
+
+				// highlight selected axis
 
 
 				handle.material._color = handle.material._color || handle.material.color.clone();
 				handle.material._color = handle.material._color || handle.material.color.clone();
 				handle.material._opacity = handle.material._opacity || handle.material.opacity;
 				handle.material._opacity = handle.material._opacity || handle.material.opacity;
 				handle.material.color.copy( handle.material._color );
 				handle.material.color.copy( handle.material._color );
 				handle.material.opacity = handle.material._opacity;
 				handle.material.opacity = handle.material._opacity;
-
 				if ( this.enabled && this.axis ) {
 				if ( this.enabled && this.axis ) {
 
 
 					if ( handle.name === this.axis ) {
 					if ( handle.name === this.axis ) {
@@ -1264,8 +1200,9 @@
 
 
 		}
 		}
 
 
-	} //
+	}
 
 
+	//
 
 
 	class TransformControlsPlane extends THREE.Mesh {
 	class TransformControlsPlane extends THREE.Mesh {
 
 
@@ -1283,7 +1220,6 @@
 			this.type = 'TransformControlsPlane';
 			this.type = 'TransformControlsPlane';
 
 
 		}
 		}
-
 		updateMatrixWorld( force ) {
 		updateMatrixWorld( force ) {
 
 
 			let space = this.space;
 			let space = this.space;
@@ -1291,14 +1227,12 @@
 			if ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation
 			if ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation
 
 
 			_v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
 			_v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
-
 			_v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
 			_v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
+			_v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
 
 
-			_v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion ); // Align the plane for current transform mode, axis and space.
-
+			// Align the plane for current transform mode, axis and space.
 
 
 			_alignVector.copy( _v2 );
 			_alignVector.copy( _v2 );
-
 			switch ( this.mode ) {
 			switch ( this.mode ) {
 
 
 				case 'translate':
 				case 'translate':
@@ -1307,52 +1241,34 @@
 
 
 						case 'X':
 						case 'X':
 							_alignVector.copy( this.eye ).cross( _v1 );
 							_alignVector.copy( this.eye ).cross( _v1 );
-
 							_dirVector.copy( _v1 ).cross( _alignVector );
 							_dirVector.copy( _v1 ).cross( _alignVector );
-
 							break;
 							break;
-
 						case 'Y':
 						case 'Y':
 							_alignVector.copy( this.eye ).cross( _v2 );
 							_alignVector.copy( this.eye ).cross( _v2 );
-
 							_dirVector.copy( _v2 ).cross( _alignVector );
 							_dirVector.copy( _v2 ).cross( _alignVector );
-
 							break;
 							break;
-
 						case 'Z':
 						case 'Z':
 							_alignVector.copy( this.eye ).cross( _v3 );
 							_alignVector.copy( this.eye ).cross( _v3 );
-
 							_dirVector.copy( _v3 ).cross( _alignVector );
 							_dirVector.copy( _v3 ).cross( _alignVector );
-
 							break;
 							break;
-
 						case 'XY':
 						case 'XY':
 							_dirVector.copy( _v3 );
 							_dirVector.copy( _v3 );
-
 							break;
 							break;
-
 						case 'YZ':
 						case 'YZ':
 							_dirVector.copy( _v1 );
 							_dirVector.copy( _v1 );
-
 							break;
 							break;
-
 						case 'XZ':
 						case 'XZ':
 							_alignVector.copy( _v3 );
 							_alignVector.copy( _v3 );
-
 							_dirVector.copy( _v2 );
 							_dirVector.copy( _v2 );
-
 							break;
 							break;
-
 						case 'XYZ':
 						case 'XYZ':
 						case 'E':
 						case 'E':
 							_dirVector.set( 0, 0, 0 );
 							_dirVector.set( 0, 0, 0 );
-
 							break;
 							break;
 
 
 					}
 					}
 
 
 					break;
 					break;
-
 				case 'rotate':
 				case 'rotate':
 				default:
 				default:
 					// special case for rotate
 					// special case for rotate
@@ -1368,7 +1284,6 @@
 			} else {
 			} else {
 
 
 				_tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector );
 				_tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector );
-
 				this.quaternion.setFromRotationMatrix( _tempMatrix );
 				this.quaternion.setFromRotationMatrix( _tempMatrix );
 
 
 			}
 			}

+ 3 - 39
examples/js/csm/CSM.js

@@ -1,13 +1,9 @@
 ( function () {
 ( function () {
 
 
 	const _cameraToLightMatrix = new THREE.Matrix4();
 	const _cameraToLightMatrix = new THREE.Matrix4();
-
 	const _lightSpaceFrustum = new THREE.CSMFrustum();
 	const _lightSpaceFrustum = new THREE.CSMFrustum();
-
 	const _center = new THREE.Vector3();
 	const _center = new THREE.Vector3();
-
 	const _bbox = new THREE.Box3();
 	const _bbox = new THREE.Box3();
-
 	const _uniformArray = [];
 	const _uniformArray = [];
 	const _logArray = [];
 	const _logArray = [];
 	class CSM {
 	class CSM {
@@ -39,7 +35,6 @@
 			this.injectInclude();
 			this.injectInclude();
 
 
 		}
 		}
-
 		createLights() {
 		createLights() {
 
 
 			for ( let i = 0; i < this.cascades; i ++ ) {
 			for ( let i = 0; i < this.cascades; i ++ ) {
@@ -58,7 +53,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		initCascades() {
 		initCascades() {
 
 
 			const camera = this.camera;
 			const camera = this.camera;
@@ -67,24 +61,22 @@
 			this.mainFrustum.split( this.breaks, this.frustums );
 			this.mainFrustum.split( this.breaks, this.frustums );
 
 
 		}
 		}
-
 		updateShadowBounds() {
 		updateShadowBounds() {
 
 
 			const frustums = this.frustums;
 			const frustums = this.frustums;
-
 			for ( let i = 0; i < frustums.length; i ++ ) {
 			for ( let i = 0; i < frustums.length; i ++ ) {
 
 
 				const light = this.lights[ i ];
 				const light = this.lights[ i ];
 				const shadowCam = light.shadow.camera;
 				const shadowCam = light.shadow.camera;
-				const frustum = this.frustums[ i ]; // Get the two points that represent that furthest points on the frustum assuming
+				const frustum = this.frustums[ i ];
+
+				// Get the two points that represent that furthest points on the frustum assuming
 				// that's either the diagonal across the far plane or the diagonal across the whole
 				// that's either the diagonal across the far plane or the diagonal across the whole
 				// frustum itself.
 				// frustum itself.
-
 				const nearVerts = frustum.vertices.near;
 				const nearVerts = frustum.vertices.near;
 				const farVerts = frustum.vertices.far;
 				const farVerts = frustum.vertices.far;
 				const point1 = farVerts[ 0 ];
 				const point1 = farVerts[ 0 ];
 				let point2;
 				let point2;
-
 				if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) {
 				if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) {
 
 
 					point2 = farVerts[ 2 ];
 					point2 = farVerts[ 2 ];
@@ -96,7 +88,6 @@
 				}
 				}
 
 
 				let squaredBBWidth = point1.distanceTo( point2 );
 				let squaredBBWidth = point1.distanceTo( point2 );
-
 				if ( this.fade ) {
 				if ( this.fade ) {
 
 
 					// expand the shadow extents by the fade margin if fade is enabled.
 					// expand the shadow extents by the fade margin if fade is enabled.
@@ -117,27 +108,22 @@
 			}
 			}
 
 
 		}
 		}
-
 		getBreaks() {
 		getBreaks() {
 
 
 			const camera = this.camera;
 			const camera = this.camera;
 			const far = Math.min( camera.far, this.maxFar );
 			const far = Math.min( camera.far, this.maxFar );
 			this.breaks.length = 0;
 			this.breaks.length = 0;
-
 			switch ( this.mode ) {
 			switch ( this.mode ) {
 
 
 				case 'uniform':
 				case 'uniform':
 					uniformSplit( this.cascades, camera.near, far, this.breaks );
 					uniformSplit( this.cascades, camera.near, far, this.breaks );
 					break;
 					break;
-
 				case 'logarithmic':
 				case 'logarithmic':
 					logarithmicSplit( this.cascades, camera.near, far, this.breaks );
 					logarithmicSplit( this.cascades, camera.near, far, this.breaks );
 					break;
 					break;
-
 				case 'practical':
 				case 'practical':
 					practicalSplit( this.cascades, camera.near, far, 0.5, this.breaks );
 					practicalSplit( this.cascades, camera.near, far, 0.5, this.breaks );
 					break;
 					break;
-
 				case 'custom':
 				case 'custom':
 					if ( this.customSplitsCallback === undefined ) console.error( 'CSM: Custom split scheme callback not defined.' );
 					if ( this.customSplitsCallback === undefined ) console.error( 'CSM: Custom split scheme callback not defined.' );
 					this.customSplitsCallback( this.cascades, camera.near, far, this.breaks );
 					this.customSplitsCallback( this.cascades, camera.near, far, this.breaks );
@@ -175,7 +161,6 @@
 				_logArray.length = 0;
 				_logArray.length = 0;
 				logarithmicSplit( amount, near, far, _logArray );
 				logarithmicSplit( amount, near, far, _logArray );
 				uniformSplit( amount, near, far, _uniformArray );
 				uniformSplit( amount, near, far, _uniformArray );
-
 				for ( let i = 1; i < amount; i ++ ) {
 				for ( let i = 1; i < amount; i ++ ) {
 
 
 					target.push( THREE.MathUtils.lerp( _uniformArray[ i - 1 ], _logArray[ i - 1 ], lambda ) );
 					target.push( THREE.MathUtils.lerp( _uniformArray[ i - 1 ], _logArray[ i - 1 ], lambda ) );
@@ -187,12 +172,10 @@
 			}
 			}
 
 
 		}
 		}
-
 		update() {
 		update() {
 
 
 			const camera = this.camera;
 			const camera = this.camera;
 			const frustums = this.frustums;
 			const frustums = this.frustums;
-
 			for ( let i = 0; i < frustums.length; i ++ ) {
 			for ( let i = 0; i < frustums.length; i ++ ) {
 
 
 				const light = this.lights[ i ];
 				const light = this.lights[ i ];
@@ -200,31 +183,23 @@
 				const texelWidth = ( shadowCam.right - shadowCam.left ) / this.shadowMapSize;
 				const texelWidth = ( shadowCam.right - shadowCam.left ) / this.shadowMapSize;
 				const texelHeight = ( shadowCam.top - shadowCam.bottom ) / this.shadowMapSize;
 				const texelHeight = ( shadowCam.top - shadowCam.bottom ) / this.shadowMapSize;
 				light.shadow.camera.updateMatrixWorld( true );
 				light.shadow.camera.updateMatrixWorld( true );
-
 				_cameraToLightMatrix.multiplyMatrices( light.shadow.camera.matrixWorldInverse, camera.matrixWorld );
 				_cameraToLightMatrix.multiplyMatrices( light.shadow.camera.matrixWorldInverse, camera.matrixWorld );
-
 				frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum );
 				frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum );
 				const nearVerts = _lightSpaceFrustum.vertices.near;
 				const nearVerts = _lightSpaceFrustum.vertices.near;
 				const farVerts = _lightSpaceFrustum.vertices.far;
 				const farVerts = _lightSpaceFrustum.vertices.far;
-
 				_bbox.makeEmpty();
 				_bbox.makeEmpty();
-
 				for ( let j = 0; j < 4; j ++ ) {
 				for ( let j = 0; j < 4; j ++ ) {
 
 
 					_bbox.expandByPoint( nearVerts[ j ] );
 					_bbox.expandByPoint( nearVerts[ j ] );
-
 					_bbox.expandByPoint( farVerts[ j ] );
 					_bbox.expandByPoint( farVerts[ j ] );
 
 
 				}
 				}
 
 
 				_bbox.getCenter( _center );
 				_bbox.getCenter( _center );
-
 				_center.z = _bbox.max.z + this.lightMargin;
 				_center.z = _bbox.max.z + this.lightMargin;
 				_center.x = Math.floor( _center.x / texelWidth ) * texelWidth;
 				_center.x = Math.floor( _center.x / texelWidth ) * texelWidth;
 				_center.y = Math.floor( _center.y / texelHeight ) * texelHeight;
 				_center.y = Math.floor( _center.y / texelHeight ) * texelHeight;
-
 				_center.applyMatrix4( light.shadow.camera.matrixWorld );
 				_center.applyMatrix4( light.shadow.camera.matrixWorld );
-
 				light.position.copy( _center );
 				light.position.copy( _center );
 				light.target.position.copy( _center );
 				light.target.position.copy( _center );
 				light.target.position.x += this.lightDirection.x;
 				light.target.position.x += this.lightDirection.x;
@@ -234,20 +209,17 @@
 			}
 			}
 
 
 		}
 		}
-
 		injectInclude() {
 		injectInclude() {
 
 
 			THREE.ShaderChunk.lights_fragment_begin = THREE.CSMShader.lights_fragment_begin;
 			THREE.ShaderChunk.lights_fragment_begin = THREE.CSMShader.lights_fragment_begin;
 			THREE.ShaderChunk.lights_pars_begin = THREE.CSMShader.lights_pars_begin;
 			THREE.ShaderChunk.lights_pars_begin = THREE.CSMShader.lights_pars_begin;
 
 
 		}
 		}
-
 		setupMaterial( material ) {
 		setupMaterial( material ) {
 
 
 			material.defines = material.defines || {};
 			material.defines = material.defines || {};
 			material.defines.USE_CSM = 1;
 			material.defines.USE_CSM = 1;
 			material.defines.CSM_CASCADES = this.cascades;
 			material.defines.CSM_CASCADES = this.cascades;
-
 			if ( this.fade ) {
 			if ( this.fade ) {
 
 
 				material.defines.CSM_FADE = '';
 				material.defines.CSM_FADE = '';
@@ -257,7 +229,6 @@
 			const breaksVec2 = [];
 			const breaksVec2 = [];
 			const scope = this;
 			const scope = this;
 			const shaders = this.shaders;
 			const shaders = this.shaders;
-
 			material.onBeforeCompile = function ( shader ) {
 			material.onBeforeCompile = function ( shader ) {
 
 
 				const far = Math.min( scope.camera.far, scope.maxFar );
 				const far = Math.min( scope.camera.far, scope.maxFar );
@@ -278,7 +249,6 @@
 			shaders.set( material, null );
 			shaders.set( material, null );
 
 
 		}
 		}
-
 		updateUniforms() {
 		updateUniforms() {
 
 
 			const far = Math.min( this.camera.far, this.maxFar );
 			const far = Math.min( this.camera.far, this.maxFar );
@@ -309,7 +279,6 @@
 			}, this );
 			}, this );
 
 
 		}
 		}
-
 		getExtendedBreaks( target ) {
 		getExtendedBreaks( target ) {
 
 
 			while ( target.length < this.breaks.length ) {
 			while ( target.length < this.breaks.length ) {
@@ -319,7 +288,6 @@
 			}
 			}
 
 
 			target.length = this.breaks.length;
 			target.length = this.breaks.length;
-
 			for ( let i = 0; i < this.cascades; i ++ ) {
 			for ( let i = 0; i < this.cascades; i ++ ) {
 
 
 				const amount = this.breaks[ i ];
 				const amount = this.breaks[ i ];
@@ -330,7 +298,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		updateFrustums() {
 		updateFrustums() {
 
 
 			this.getBreaks();
 			this.getBreaks();
@@ -339,7 +306,6 @@
 			this.updateUniforms();
 			this.updateUniforms();
 
 
 		}
 		}
-
 		remove() {
 		remove() {
 
 
 			for ( let i = 0; i < this.lights.length; i ++ ) {
 			for ( let i = 0; i < this.lights.length; i ++ ) {
@@ -350,7 +316,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			const shaders = this.shaders;
 			const shaders = this.shaders;
@@ -360,7 +325,6 @@
 				delete material.defines.USE_CSM;
 				delete material.defines.USE_CSM;
 				delete material.defines.CSM_CASCADES;
 				delete material.defines.CSM_CASCADES;
 				delete material.defines.CSM_FADE;
 				delete material.defines.CSM_FADE;
-
 				if ( shader !== null ) {
 				if ( shader !== null ) {
 
 
 					delete shader.uniforms.CSM_cascades;
 					delete shader.uniforms.CSM_cascades;

+ 3 - 9
examples/js/csm/CSMFrustum.js

@@ -1,7 +1,6 @@
 ( function () {
 ( function () {
 
 
 	const inverseProjectionMatrix = new THREE.Matrix4();
 	const inverseProjectionMatrix = new THREE.Matrix4();
-
 	class CSMFrustum {
 	class CSMFrustum {
 
 
 		constructor( data ) {
 		constructor( data ) {
@@ -11,7 +10,6 @@
 				near: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ],
 				near: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ],
 				far: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]
 				far: [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ]
 			};
 			};
-
 			if ( data.projectionMatrix !== undefined ) {
 			if ( data.projectionMatrix !== undefined ) {
 
 
 				this.setFromProjectionMatrix( data.projectionMatrix, data.maxFar || 10000 );
 				this.setFromProjectionMatrix( data.projectionMatrix, data.maxFar || 10000 );
@@ -19,11 +17,12 @@
 			}
 			}
 
 
 		}
 		}
-
 		setFromProjectionMatrix( projectionMatrix, maxFar ) {
 		setFromProjectionMatrix( projectionMatrix, maxFar ) {
 
 
 			const isOrthographic = projectionMatrix.elements[ 2 * 4 + 3 ] === 0;
 			const isOrthographic = projectionMatrix.elements[ 2 * 4 + 3 ] === 0;
-			inverseProjectionMatrix.copy( projectionMatrix ).invert(); // 3 --- 0  vertices.near/far order
+			inverseProjectionMatrix.copy( projectionMatrix ).invert();
+
+			// 3 --- 0  vertices.near/far order
 			// |     |
 			// |     |
 			// 2 --- 1
 			// 2 --- 1
 			// clip space spans from [-1, 1]
 			// clip space spans from [-1, 1]
@@ -45,7 +44,6 @@
 
 
 				v.applyMatrix4( inverseProjectionMatrix );
 				v.applyMatrix4( inverseProjectionMatrix );
 				const absZ = Math.abs( v.z );
 				const absZ = Math.abs( v.z );
-
 				if ( isOrthographic ) {
 				if ( isOrthographic ) {
 
 
 					v.z *= Math.min( maxFar / absZ, 1.0 );
 					v.z *= Math.min( maxFar / absZ, 1.0 );
@@ -60,7 +58,6 @@
 			return this.vertices;
 			return this.vertices;
 
 
 		}
 		}
-
 		split( breaks, target ) {
 		split( breaks, target ) {
 
 
 			while ( breaks.length > target.length ) {
 			while ( breaks.length > target.length ) {
@@ -70,11 +67,9 @@
 			}
 			}
 
 
 			target.length = breaks.length;
 			target.length = breaks.length;
-
 			for ( let i = 0; i < breaks.length; i ++ ) {
 			for ( let i = 0; i < breaks.length; i ++ ) {
 
 
 				const cascade = target[ i ];
 				const cascade = target[ i ];
-
 				if ( i === 0 ) {
 				if ( i === 0 ) {
 
 
 					for ( let j = 0; j < 4; j ++ ) {
 					for ( let j = 0; j < 4; j ++ ) {
@@ -114,7 +109,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		toSpace( cameraMatrix, target ) {
 		toSpace( cameraMatrix, target ) {
 
 
 			for ( let i = 0; i < 4; i ++ ) {
 			for ( let i = 0; i < 4; i ++ ) {

+ 0 - 6
examples/js/csm/CSMHelper.js

@@ -22,7 +22,6 @@
 			this.shadowLines = [];
 			this.shadowLines = [];
 
 
 		}
 		}
-
 		updateVisibility() {
 		updateVisibility() {
 
 
 			const displayFrustum = this.displayFrustum;
 			const displayFrustum = this.displayFrustum;
@@ -32,7 +31,6 @@
 			const cascadeLines = this.cascadeLines;
 			const cascadeLines = this.cascadeLines;
 			const cascadePlanes = this.cascadePlanes;
 			const cascadePlanes = this.cascadePlanes;
 			const shadowLines = this.shadowLines;
 			const shadowLines = this.shadowLines;
-
 			for ( let i = 0, l = cascadeLines.length; i < l; i ++ ) {
 			for ( let i = 0, l = cascadeLines.length; i < l; i ++ ) {
 
 
 				const cascadeLine = cascadeLines[ i ];
 				const cascadeLine = cascadeLines[ i ];
@@ -47,7 +45,6 @@
 			frustumLines.visible = displayFrustum;
 			frustumLines.visible = displayFrustum;
 
 
 		}
 		}
-
 		update() {
 		update() {
 
 
 			const csm = this.csm;
 			const csm = this.csm;
@@ -65,7 +62,6 @@
 			this.quaternion.copy( camera.quaternion );
 			this.quaternion.copy( camera.quaternion );
 			this.scale.copy( camera.scale );
 			this.scale.copy( camera.scale );
 			this.updateMatrixWorld( true );
 			this.updateMatrixWorld( true );
-
 			while ( cascadeLines.length > cascades ) {
 			while ( cascadeLines.length > cascades ) {
 
 
 				this.remove( cascadeLines.pop() );
 				this.remove( cascadeLines.pop() );
@@ -137,7 +133,6 @@
 			frustumLinePositions.needsUpdate = true;
 			frustumLinePositions.needsUpdate = true;
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			const frustumLines = this.frustumLines;
 			const frustumLines = this.frustumLines;
@@ -147,7 +142,6 @@
 			frustumLines.geometry.dispose();
 			frustumLines.geometry.dispose();
 			frustumLines.material.dispose();
 			frustumLines.material.dispose();
 			const cascades = this.csm.cascades;
 			const cascades = this.csm.cascades;
-
 			for ( let i = 0; i < cascades; i ++ ) {
 			for ( let i = 0; i < cascades; i ++ ) {
 
 
 				const cascadeLine = cascadeLines[ i ];
 				const cascadeLine = cascadeLines[ i ];

+ 2 - 6
examples/js/csm/CSMShader.js

@@ -1,9 +1,7 @@
 ( function () {
 ( function () {
 
 
 	const CSMShader = {
 	const CSMShader = {
-		lights_fragment_begin:
-  /* glsl */
-  `
+		lights_fragment_begin: /* glsl */`
 GeometricContext geometry;
 GeometricContext geometry;
 
 
 geometry.position = - vViewPosition;
 geometry.position = - vViewPosition;
@@ -241,9 +239,7 @@ IncidentLight directLight;
 
 
 #endif
 #endif
 `,
 `,
-		lights_pars_begin:
-  /* glsl */
-  `
+		lights_pars_begin: /* glsl */`
 #if defined( USE_CSM ) && defined( CSM_CASCADES )
 #if defined( USE_CSM ) && defined( CSM_CASCADES )
 uniform vec2 CSM_cascades[CSM_CASCADES];
 uniform vec2 CSM_cascades[CSM_CASCADES];
 uniform float cameraNear;
 uniform float cameraNear;

+ 27 - 27
examples/js/curves/CurveExtras.js

@@ -9,6 +9,7 @@
  * http://www.mi.sanu.ac.rs/vismath/taylorapril2011/Taylor.pdf
  * http://www.mi.sanu.ac.rs/vismath/taylorapril2011/Taylor.pdf
  * https://prideout.net/blog/old/blog/index.html@p=44.html
  * https://prideout.net/blog/old/blog/index.html@p=44.html
  */
  */
+
 	// GrannyKnot
 	// GrannyKnot
 
 
 	class GrannyKnot extends THREE.Curve {
 	class GrannyKnot extends THREE.Curve {
@@ -24,8 +25,9 @@
 
 
 		}
 		}
 
 
-	} // HeartCurve
+	}
 
 
+	// HeartCurve
 
 
 	class HeartCurve extends THREE.Curve {
 	class HeartCurve extends THREE.Curve {
 
 
@@ -35,7 +37,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -47,8 +48,9 @@
 
 
 		}
 		}
 
 
-	} // Viviani's THREE.Curve
+	}
 
 
+	// Viviani's THREE.Curve
 
 
 	class VivianiCurve extends THREE.Curve {
 	class VivianiCurve extends THREE.Curve {
 
 
@@ -58,12 +60,10 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
 			t = t * 4 * Math.PI; // normalized to 0..1
 			t = t * 4 * Math.PI; // normalized to 0..1
-
 			const a = this.scale / 2;
 			const a = this.scale / 2;
 			const x = a * ( 1 + Math.cos( t ) );
 			const x = a * ( 1 + Math.cos( t ) );
 			const y = a * Math.sin( t );
 			const y = a * Math.sin( t );
@@ -72,8 +72,9 @@
 
 
 		}
 		}
 
 
-	} // KnotCurve
+	}
 
 
+	// KnotCurve
 
 
 	class KnotCurve extends THREE.Curve {
 	class KnotCurve extends THREE.Curve {
 
 
@@ -90,8 +91,9 @@
 
 
 		}
 		}
 
 
-	} // HelixCurve
+	}
 
 
+	// HelixCurve
 
 
 	class HelixCurve extends THREE.Curve {
 	class HelixCurve extends THREE.Curve {
 
 
@@ -99,7 +101,6 @@
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
 			const a = 30; // radius
 			const a = 30; // radius
-
 			const b = 150; // height
 			const b = 150; // height
 
 
 			const t2 = 2 * Math.PI * t * b / 30;
 			const t2 = 2 * Math.PI * t * b / 30;
@@ -110,8 +111,9 @@
 
 
 		}
 		}
 
 
-	} // TrefoilKnot
+	}
 
 
+	// TrefoilKnot
 
 
 	class TrefoilKnot extends THREE.Curve {
 	class TrefoilKnot extends THREE.Curve {
 
 
@@ -121,7 +123,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -133,8 +134,9 @@
 
 
 		}
 		}
 
 
-	} // TorusKnot
+	}
 
 
+	// TorusKnot
 
 
 	class TorusKnot extends THREE.Curve {
 	class TorusKnot extends THREE.Curve {
 
 
@@ -144,7 +146,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -158,8 +159,9 @@
 
 
 		}
 		}
 
 
-	} // CinquefoilKnot
+	}
 
 
+	// CinquefoilKnot
 
 
 	class CinquefoilKnot extends THREE.Curve {
 	class CinquefoilKnot extends THREE.Curve {
 
 
@@ -169,7 +171,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -183,8 +184,9 @@
 
 
 		}
 		}
 
 
-	} // TrefoilPolynomialKnot
+	}
 
 
+	// TrefoilPolynomialKnot
 
 
 	class TrefoilPolynomialKnot extends THREE.Curve {
 	class TrefoilPolynomialKnot extends THREE.Curve {
 
 
@@ -194,7 +196,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -207,14 +208,14 @@
 		}
 		}
 
 
 	}
 	}
-
 	function scaleTo( x, y, t ) {
 	function scaleTo( x, y, t ) {
 
 
 		const r = y - x;
 		const r = y - x;
 		return t * r + x;
 		return t * r + x;
 
 
-	} // FigureEightPolynomialKnot
+	}
 
 
+	// FigureEightPolynomialKnot
 
 
 	class FigureEightPolynomialKnot extends THREE.Curve {
 	class FigureEightPolynomialKnot extends THREE.Curve {
 
 
@@ -224,7 +225,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -236,8 +236,9 @@
 
 
 		}
 		}
 
 
-	} // DecoratedTorusKnot4a
+	}
 
 
+	// DecoratedTorusKnot4a
 
 
 	class DecoratedTorusKnot4a extends THREE.Curve {
 	class DecoratedTorusKnot4a extends THREE.Curve {
 
 
@@ -247,7 +248,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -259,8 +259,9 @@
 
 
 		}
 		}
 
 
-	} // DecoratedTorusKnot4b
+	}
 
 
+	// DecoratedTorusKnot4b
 
 
 	class DecoratedTorusKnot4b extends THREE.Curve {
 	class DecoratedTorusKnot4b extends THREE.Curve {
 
 
@@ -270,7 +271,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -282,8 +282,9 @@
 
 
 		}
 		}
 
 
-	} // DecoratedTorusKnot5a
+	}
 
 
+	// DecoratedTorusKnot5a
 
 
 	class DecoratedTorusKnot5a extends THREE.Curve {
 	class DecoratedTorusKnot5a extends THREE.Curve {
 
 
@@ -293,7 +294,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
@@ -305,8 +305,9 @@
 
 
 		}
 		}
 
 
-	} // DecoratedTorusKnot5c
+	}
 
 
+	// DecoratedTorusKnot5c
 
 
 	class DecoratedTorusKnot5c extends THREE.Curve {
 	class DecoratedTorusKnot5c extends THREE.Curve {
 
 
@@ -316,7 +317,6 @@
 			this.scale = scale;
 			this.scale = scale;
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;

+ 4 - 16
examples/js/curves/NURBSCurve.js

@@ -11,24 +11,15 @@
 
 
 	class NURBSCurve extends THREE.Curve {
 	class NURBSCurve extends THREE.Curve {
 
 
-		constructor( degree, knots
-			/* array of reals */
-			, controlPoints
-			/* array of Vector(2|3|4) */
-			, startKnot
-			/* index in knots */
-			, endKnot
-			/* index in knots */
-		) {
+		constructor( degree, knots /* array of reals */, controlPoints /* array of Vector(2|3|4) */, startKnot /* index in knots */, endKnot /* index in knots */ ) {
 
 
 			super();
 			super();
 			this.degree = degree;
 			this.degree = degree;
 			this.knots = knots;
 			this.knots = knots;
-			this.controlPoints = []; // Used by periodic NURBS to remove hidden spans
-
+			this.controlPoints = [];
+			// Used by periodic NURBS to remove hidden spans
 			this.startKnot = startKnot || 0;
 			this.startKnot = startKnot || 0;
 			this.endKnot = endKnot || this.knots.length - 1;
 			this.endKnot = endKnot || this.knots.length - 1;
-
 			for ( let i = 0; i < controlPoints.length; ++ i ) {
 			for ( let i = 0; i < controlPoints.length; ++ i ) {
 
 
 				// ensure THREE.Vector4 for control points
 				// ensure THREE.Vector4 for control points
@@ -38,15 +29,13 @@
 			}
 			}
 
 
 		}
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const point = optionalTarget;
 			const point = optionalTarget;
 			const u = this.knots[ this.startKnot ] + t * ( this.knots[ this.endKnot ] - this.knots[ this.startKnot ] ); // linear mapping t->u
 			const u = this.knots[ this.startKnot ] + t * ( this.knots[ this.endKnot ] - this.knots[ this.startKnot ] ); // linear mapping t->u
-			// following results in (wx, wy, wz, w) homogeneous point
 
 
+			// following results in (wx, wy, wz, w) homogeneous point
 			const hpoint = THREE.NURBSUtils.calcBSplinePoint( this.degree, this.knots, this.controlPoints, u );
 			const hpoint = THREE.NURBSUtils.calcBSplinePoint( this.degree, this.knots, this.controlPoints, u );
-
 			if ( hpoint.w !== 1.0 ) {
 			if ( hpoint.w !== 1.0 ) {
 
 
 				// project to 3D space: (wx, wy, wz, w) -> (x, y, z, 1)
 				// project to 3D space: (wx, wy, wz, w) -> (x, y, z, 1)
@@ -57,7 +46,6 @@
 			return point.set( hpoint.x, hpoint.y, hpoint.z );
 			return point.set( hpoint.x, hpoint.y, hpoint.z );
 
 
 		}
 		}
-
 		getTangent( t, optionalTarget = new THREE.Vector3() ) {
 		getTangent( t, optionalTarget = new THREE.Vector3() ) {
 
 
 			const tangent = optionalTarget;
 			const tangent = optionalTarget;

+ 3 - 9
examples/js/curves/NURBSSurface.js

@@ -8,11 +8,7 @@
 
 
 	class NURBSSurface {
 	class NURBSSurface {
 
 
-		constructor( degree1, degree2, knots1, knots2
-			/* arrays of reals */
-			, controlPoints
-			/* array^2 of Vector(2|3|4) */
-		) {
+		constructor( degree1, degree2, knots1, knots2 /* arrays of reals */, controlPoints /* array^2 of Vector(2|3|4) */ ) {
 
 
 			this.degree1 = degree1;
 			this.degree1 = degree1;
 			this.degree2 = degree2;
 			this.degree2 = degree2;
@@ -20,12 +16,12 @@
 			this.knots2 = knots2;
 			this.knots2 = knots2;
 			this.controlPoints = [];
 			this.controlPoints = [];
 			const len1 = knots1.length - degree1 - 1;
 			const len1 = knots1.length - degree1 - 1;
-			const len2 = knots2.length - degree2 - 1; // ensure THREE.Vector4 for control points
+			const len2 = knots2.length - degree2 - 1;
 
 
+			// ensure THREE.Vector4 for control points
 			for ( let i = 0; i < len1; ++ i ) {
 			for ( let i = 0; i < len1; ++ i ) {
 
 
 				this.controlPoints[ i ] = [];
 				this.controlPoints[ i ] = [];
-
 				for ( let j = 0; j < len2; ++ j ) {
 				for ( let j = 0; j < len2; ++ j ) {
 
 
 					const point = controlPoints[ i ][ j ];
 					const point = controlPoints[ i ][ j ];
@@ -36,11 +32,9 @@
 			}
 			}
 
 
 		}
 		}
-
 		getPoint( t1, t2, target ) {
 		getPoint( t1, t2, target ) {
 
 
 			const u = this.knots1[ 0 ] + t1 * ( this.knots1[ this.knots1.length - 1 ] - this.knots1[ 0 ] ); // linear mapping t1->u
 			const u = this.knots1[ 0 ] + t1 * ( this.knots1[ this.knots1.length - 1 ] - this.knots1[ 0 ] ); // linear mapping t1->u
-
 			const v = this.knots2[ 0 ] + t2 * ( this.knots2[ this.knots2.length - 1 ] - this.knots2[ 0 ] ); // linear mapping t2->u
 			const v = this.knots2[ 0 ] + t2 * ( this.knots2[ this.knots2.length - 1 ] - this.knots2[ 0 ] ); // linear mapping t2->u
 
 
 			THREE.NURBSUtils.calcSurfacePoint( this.degree1, this.degree2, this.knots1, this.knots2, this.controlPoints, u, v, target );
 			THREE.NURBSUtils.calcSurfacePoint( this.degree1, this.degree2, this.knots1, this.knots2, this.controlPoints, u, v, target );

+ 8 - 45
examples/js/curves/NURBSUtils.js

@@ -19,11 +19,9 @@ U : knot vector
 
 
 returns the span
 returns the span
 */
 */
-
 	function findSpan( p, u, U ) {
 	function findSpan( p, u, U ) {
 
 
 		const n = U.length - p - 1;
 		const n = U.length - p - 1;
-
 		if ( u >= U[ n ] ) {
 		if ( u >= U[ n ] ) {
 
 
 			return n - 1;
 			return n - 1;
@@ -39,7 +37,6 @@ returns the span
 		let low = p;
 		let low = p;
 		let high = n;
 		let high = n;
 		let mid = Math.floor( ( low + high ) / 2 );
 		let mid = Math.floor( ( low + high ) / 2 );
-
 		while ( u < U[ mid ] || u >= U[ mid + 1 ] ) {
 		while ( u < U[ mid ] || u >= U[ mid + 1 ] ) {
 
 
 			if ( u < U[ mid ] ) {
 			if ( u < U[ mid ] ) {
@@ -59,6 +56,7 @@ returns the span
 		return mid;
 		return mid;
 
 
 	}
 	}
+
 	/*
 	/*
 Calculate basis functions. See The NURBS Book, page 70, algorithm A2.2
 Calculate basis functions. See The NURBS Book, page 70, algorithm A2.2
 
 
@@ -69,21 +67,17 @@ U    : knot vector
 
 
 returns array[p+1] with basis functions values.
 returns array[p+1] with basis functions values.
 */
 */
-
-
 	function calcBasisFunctions( span, u, p, U ) {
 	function calcBasisFunctions( span, u, p, U ) {
 
 
 		const N = [];
 		const N = [];
 		const left = [];
 		const left = [];
 		const right = [];
 		const right = [];
 		N[ 0 ] = 1.0;
 		N[ 0 ] = 1.0;
-
 		for ( let j = 1; j <= p; ++ j ) {
 		for ( let j = 1; j <= p; ++ j ) {
 
 
 			left[ j ] = u - U[ span + 1 - j ];
 			left[ j ] = u - U[ span + 1 - j ];
 			right[ j ] = U[ span + j ] - u;
 			right[ j ] = U[ span + j ] - u;
 			let saved = 0.0;
 			let saved = 0.0;
-
 			for ( let r = 0; r < j; ++ r ) {
 			for ( let r = 0; r < j; ++ r ) {
 
 
 				const rv = right[ r + 1 ];
 				const rv = right[ r + 1 ];
@@ -101,6 +95,7 @@ returns array[p+1] with basis functions values.
 		return N;
 		return N;
 
 
 	}
 	}
+
 	/*
 	/*
 Calculate B-Spline curve points. See The NURBS Book, page 82, algorithm A3.1.
 Calculate B-Spline curve points. See The NURBS Book, page 82, algorithm A3.1.
 
 
@@ -111,14 +106,11 @@ u : parametric point
 
 
 returns point for given u
 returns point for given u
 */
 */
-
-
 	function calcBSplinePoint( p, U, P, u ) {
 	function calcBSplinePoint( p, U, P, u ) {
 
 
 		const span = findSpan( p, u, U );
 		const span = findSpan( p, u, U );
 		const N = calcBasisFunctions( span, u, p, U );
 		const N = calcBasisFunctions( span, u, p, U );
 		const C = new THREE.Vector4( 0, 0, 0, 0 );
 		const C = new THREE.Vector4( 0, 0, 0, 0 );
-
 		for ( let j = 0; j <= p; ++ j ) {
 		for ( let j = 0; j <= p; ++ j ) {
 
 
 			const point = P[ span - p + j ];
 			const point = P[ span - p + j ];
@@ -134,6 +126,7 @@ returns point for given u
 		return C;
 		return C;
 
 
 	}
 	}
+
 	/*
 	/*
 Calculate basis functions derivatives. See The NURBS Book, page 72, algorithm A2.3.
 Calculate basis functions derivatives. See The NURBS Book, page 72, algorithm A2.3.
 
 
@@ -145,32 +138,22 @@ U    : knot vector
 
 
 returns array[n+1][p+1] with basis functions derivatives
 returns array[n+1][p+1] with basis functions derivatives
 */
 */
-
-
 	function calcBasisFunctionDerivatives( span, u, p, n, U ) {
 	function calcBasisFunctionDerivatives( span, u, p, n, U ) {
 
 
 		const zeroArr = [];
 		const zeroArr = [];
-
 		for ( let i = 0; i <= p; ++ i ) zeroArr[ i ] = 0.0;
 		for ( let i = 0; i <= p; ++ i ) zeroArr[ i ] = 0.0;
-
 		const ders = [];
 		const ders = [];
-
 		for ( let i = 0; i <= n; ++ i ) ders[ i ] = zeroArr.slice( 0 );
 		for ( let i = 0; i <= n; ++ i ) ders[ i ] = zeroArr.slice( 0 );
-
 		const ndu = [];
 		const ndu = [];
-
 		for ( let i = 0; i <= p; ++ i ) ndu[ i ] = zeroArr.slice( 0 );
 		for ( let i = 0; i <= p; ++ i ) ndu[ i ] = zeroArr.slice( 0 );
-
 		ndu[ 0 ][ 0 ] = 1.0;
 		ndu[ 0 ][ 0 ] = 1.0;
 		const left = zeroArr.slice( 0 );
 		const left = zeroArr.slice( 0 );
 		const right = zeroArr.slice( 0 );
 		const right = zeroArr.slice( 0 );
-
 		for ( let j = 1; j <= p; ++ j ) {
 		for ( let j = 1; j <= p; ++ j ) {
 
 
 			left[ j ] = u - U[ span + 1 - j ];
 			left[ j ] = u - U[ span + 1 - j ];
 			right[ j ] = U[ span + j ] - u;
 			right[ j ] = U[ span + j ] - u;
 			let saved = 0.0;
 			let saved = 0.0;
-
 			for ( let r = 0; r < j; ++ r ) {
 			for ( let r = 0; r < j; ++ r ) {
 
 
 				const rv = right[ r + 1 ];
 				const rv = right[ r + 1 ];
@@ -197,7 +180,6 @@ returns array[n+1][p+1] with basis functions derivatives
 			let s1 = 0;
 			let s1 = 0;
 			let s2 = 1;
 			let s2 = 1;
 			const a = [];
 			const a = [];
-
 			for ( let i = 0; i <= p; ++ i ) {
 			for ( let i = 0; i <= p; ++ i ) {
 
 
 				a[ i ] = zeroArr.slice( 0 );
 				a[ i ] = zeroArr.slice( 0 );
@@ -205,13 +187,11 @@ returns array[n+1][p+1] with basis functions derivatives
 			}
 			}
 
 
 			a[ 0 ][ 0 ] = 1.0;
 			a[ 0 ][ 0 ] = 1.0;
-
 			for ( let k = 1; k <= n; ++ k ) {
 			for ( let k = 1; k <= n; ++ k ) {
 
 
 				let d = 0.0;
 				let d = 0.0;
 				const rk = r - k;
 				const rk = r - k;
 				const pk = p - k;
 				const pk = p - k;
-
 				if ( r >= k ) {
 				if ( r >= k ) {
 
 
 					a[ s2 ][ 0 ] = a[ s1 ][ 0 ] / ndu[ pk + 1 ][ rk ];
 					a[ s2 ][ 0 ] = a[ s1 ][ 0 ] / ndu[ pk + 1 ][ rk ];
@@ -221,7 +201,6 @@ returns array[n+1][p+1] with basis functions derivatives
 
 
 				const j1 = rk >= - 1 ? 1 : - rk;
 				const j1 = rk >= - 1 ? 1 : - rk;
 				const j2 = r - 1 <= pk ? k - 1 : p - r;
 				const j2 = r - 1 <= pk ? k - 1 : p - r;
-
 				for ( let j = j1; j <= j2; ++ j ) {
 				for ( let j = j1; j <= j2; ++ j ) {
 
 
 					a[ s2 ][ j ] = ( a[ s1 ][ j ] - a[ s1 ][ j - 1 ] ) / ndu[ pk + 1 ][ rk + j ];
 					a[ s2 ][ j ] = ( a[ s1 ][ j ] - a[ s1 ][ j - 1 ] ) / ndu[ pk + 1 ][ rk + j ];
@@ -246,7 +225,6 @@ returns array[n+1][p+1] with basis functions derivatives
 		}
 		}
 
 
 		let r = p;
 		let r = p;
-
 		for ( let k = 1; k <= n; ++ k ) {
 		for ( let k = 1; k <= n; ++ k ) {
 
 
 			for ( let j = 0; j <= p; ++ j ) {
 			for ( let j = 0; j <= p; ++ j ) {
@@ -262,6 +240,7 @@ returns array[n+1][p+1] with basis functions derivatives
 		return ders;
 		return ders;
 
 
 	}
 	}
+
 	/*
 	/*
 	Calculate derivatives of a B-Spline. See The NURBS Book, page 93, algorithm A3.2.
 	Calculate derivatives of a B-Spline. See The NURBS Book, page 93, algorithm A3.2.
 
 
@@ -273,8 +252,6 @@ returns array[n+1][p+1] with basis functions derivatives
 
 
 	returns array[d+1] with derivatives
 	returns array[d+1] with derivatives
 	*/
 	*/
-
-
 	function calcBSplineDerivatives( p, U, P, u, nd ) {
 	function calcBSplineDerivatives( p, U, P, u, nd ) {
 
 
 		const du = nd < p ? nd : p;
 		const du = nd < p ? nd : p;
@@ -282,7 +259,6 @@ returns array[n+1][p+1] with basis functions derivatives
 		const span = findSpan( p, u, U );
 		const span = findSpan( p, u, U );
 		const nders = calcBasisFunctionDerivatives( span, u, p, du, U );
 		const nders = calcBasisFunctionDerivatives( span, u, p, du, U );
 		const Pw = [];
 		const Pw = [];
-
 		for ( let i = 0; i < P.length; ++ i ) {
 		for ( let i = 0; i < P.length; ++ i ) {
 
 
 			const point = P[ i ].clone();
 			const point = P[ i ].clone();
@@ -297,7 +273,6 @@ returns array[n+1][p+1] with basis functions derivatives
 		for ( let k = 0; k <= du; ++ k ) {
 		for ( let k = 0; k <= du; ++ k ) {
 
 
 			const point = Pw[ span - p ].clone().multiplyScalar( nders[ k ][ 0 ] );
 			const point = Pw[ span - p ].clone().multiplyScalar( nders[ k ][ 0 ] );
-
 			for ( let j = 1; j <= p; ++ j ) {
 			for ( let j = 1; j <= p; ++ j ) {
 
 
 				point.add( Pw[ span - p + j ].clone().multiplyScalar( nders[ k ][ j ] ) );
 				point.add( Pw[ span - p + j ].clone().multiplyScalar( nders[ k ][ j ] ) );
@@ -317,17 +292,15 @@ returns array[n+1][p+1] with basis functions derivatives
 		return CK;
 		return CK;
 
 
 	}
 	}
+
 	/*
 	/*
 Calculate "K over I"
 Calculate "K over I"
 
 
 returns k!/(i!(k-i)!)
 returns k!/(i!(k-i)!)
 */
 */
-
-
 	function calcKoverI( k, i ) {
 	function calcKoverI( k, i ) {
 
 
 		let nom = 1;
 		let nom = 1;
-
 		for ( let j = 2; j <= k; ++ j ) {
 		for ( let j = 2; j <= k; ++ j ) {
 
 
 			nom *= j;
 			nom *= j;
@@ -335,7 +308,6 @@ returns k!/(i!(k-i)!)
 		}
 		}
 
 
 		let denom = 1;
 		let denom = 1;
-
 		for ( let j = 2; j <= i; ++ j ) {
 		for ( let j = 2; j <= i; ++ j ) {
 
 
 			denom *= j;
 			denom *= j;
@@ -351,6 +323,7 @@ returns k!/(i!(k-i)!)
 		return nom / denom;
 		return nom / denom;
 
 
 	}
 	}
+
 	/*
 	/*
 Calculate derivatives (0-nd) of rational curve. See The NURBS Book, page 127, algorithm A4.2.
 Calculate derivatives (0-nd) of rational curve. See The NURBS Book, page 127, algorithm A4.2.
 
 
@@ -358,14 +331,11 @@ Pders : result of function calcBSplineDerivatives
 
 
 returns array with derivatives for rational curve.
 returns array with derivatives for rational curve.
 */
 */
-
-
 	function calcRationalCurveDerivatives( Pders ) {
 	function calcRationalCurveDerivatives( Pders ) {
 
 
 		const nd = Pders.length;
 		const nd = Pders.length;
 		const Aders = [];
 		const Aders = [];
 		const wders = [];
 		const wders = [];
-
 		for ( let i = 0; i < nd; ++ i ) {
 		for ( let i = 0; i < nd; ++ i ) {
 
 
 			const point = Pders[ i ];
 			const point = Pders[ i ];
@@ -375,11 +345,9 @@ returns array with derivatives for rational curve.
 		}
 		}
 
 
 		const CK = [];
 		const CK = [];
-
 		for ( let k = 0; k < nd; ++ k ) {
 		for ( let k = 0; k < nd; ++ k ) {
 
 
 			const v = Aders[ k ].clone();
 			const v = Aders[ k ].clone();
-
 			for ( let i = 1; i <= k; ++ i ) {
 			for ( let i = 1; i <= k; ++ i ) {
 
 
 				v.sub( CK[ k - i ].clone().multiplyScalar( calcKoverI( k, i ) * wders[ i ] ) );
 				v.sub( CK[ k - i ].clone().multiplyScalar( calcKoverI( k, i ) * wders[ i ] ) );
@@ -393,6 +361,7 @@ returns array with derivatives for rational curve.
 		return CK;
 		return CK;
 
 
 	}
 	}
+
 	/*
 	/*
 Calculate NURBS curve derivatives. See The NURBS Book, page 127, algorithm A4.2.
 Calculate NURBS curve derivatives. See The NURBS Book, page 127, algorithm A4.2.
 
 
@@ -404,14 +373,13 @@ nd : number of derivatives
 
 
 returns array with derivatives.
 returns array with derivatives.
 */
 */
-
-
 	function calcNURBSDerivatives( p, U, P, u, nd ) {
 	function calcNURBSDerivatives( p, U, P, u, nd ) {
 
 
 		const Pders = calcBSplineDerivatives( p, U, P, u, nd );
 		const Pders = calcBSplineDerivatives( p, U, P, u, nd );
 		return calcRationalCurveDerivatives( Pders );
 		return calcRationalCurveDerivatives( Pders );
 
 
 	}
 	}
+
 	/*
 	/*
 Calculate rational B-Spline surface point. See The NURBS Book, page 134, algorithm A4.3.
 Calculate rational B-Spline surface point. See The NURBS Book, page 134, algorithm A4.3.
 
 
@@ -422,8 +390,6 @@ u, v   : parametric values
 
 
 returns point for given (u, v)
 returns point for given (u, v)
 */
 */
-
-
 	function calcSurfacePoint( p, q, U, V, P, u, v, target ) {
 	function calcSurfacePoint( p, q, U, V, P, u, v, target ) {
 
 
 		const uspan = findSpan( p, u, U );
 		const uspan = findSpan( p, u, U );
@@ -431,11 +397,9 @@ returns point for given (u, v)
 		const Nu = calcBasisFunctions( uspan, u, p, U );
 		const Nu = calcBasisFunctions( uspan, u, p, U );
 		const Nv = calcBasisFunctions( vspan, v, q, V );
 		const Nv = calcBasisFunctions( vspan, v, q, V );
 		const temp = [];
 		const temp = [];
-
 		for ( let l = 0; l <= q; ++ l ) {
 		for ( let l = 0; l <= q; ++ l ) {
 
 
 			temp[ l ] = new THREE.Vector4( 0, 0, 0, 0 );
 			temp[ l ] = new THREE.Vector4( 0, 0, 0, 0 );
-
 			for ( let k = 0; k <= p; ++ k ) {
 			for ( let k = 0; k <= p; ++ k ) {
 
 
 				const point = P[ uspan - p + k ][ vspan - q + l ].clone();
 				const point = P[ uspan - p + k ][ vspan - q + l ].clone();
@@ -450,7 +414,6 @@ returns point for given (u, v)
 		}
 		}
 
 
 		const Sw = new THREE.Vector4( 0, 0, 0, 0 );
 		const Sw = new THREE.Vector4( 0, 0, 0, 0 );
-
 		for ( let l = 0; l <= q; ++ l ) {
 		for ( let l = 0; l <= q; ++ l ) {
 
 
 			Sw.add( temp[ l ].multiplyScalar( Nv[ l ] ) );
 			Sw.add( temp[ l ].multiplyScalar( Nv[ l ] ) );

+ 4 - 18
examples/js/effects/AnaglyphEffect.js

@@ -5,25 +5,19 @@
 		constructor( renderer, width = 512, height = 512 ) {
 		constructor( renderer, width = 512, height = 512 ) {
 
 
 			// Dubois matrices from https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.6968&rep=rep1&type=pdf#page=4
 			// Dubois matrices from https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.6968&rep=rep1&type=pdf#page=4
+
 			this.colorMatrixLeft = new THREE.Matrix3().fromArray( [ 0.456100, - 0.0400822, - 0.0152161, 0.500484, - 0.0378246, - 0.0205971, 0.176381, - 0.0157589, - 0.00546856 ] );
 			this.colorMatrixLeft = new THREE.Matrix3().fromArray( [ 0.456100, - 0.0400822, - 0.0152161, 0.500484, - 0.0378246, - 0.0205971, 0.176381, - 0.0157589, - 0.00546856 ] );
 			this.colorMatrixRight = new THREE.Matrix3().fromArray( [ - 0.0434706, 0.378476, - 0.0721527, - 0.0879388, 0.73364, - 0.112961, - 0.00155529, - 0.0184503, 1.2264 ] );
 			this.colorMatrixRight = new THREE.Matrix3().fromArray( [ - 0.0434706, 0.378476, - 0.0721527, - 0.0879388, 0.73364, - 0.112961, - 0.00155529, - 0.0184503, 1.2264 ] );
-
 			const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
 			const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-
 			const _scene = new THREE.Scene();
 			const _scene = new THREE.Scene();
-
 			const _stereo = new THREE.StereoCamera();
 			const _stereo = new THREE.StereoCamera();
-
 			const _params = {
 			const _params = {
 				minFilter: THREE.LinearFilter,
 				minFilter: THREE.LinearFilter,
 				magFilter: THREE.NearestFilter,
 				magFilter: THREE.NearestFilter,
 				format: THREE.RGBAFormat
 				format: THREE.RGBAFormat
 			};
 			};
-
 			const _renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
 			const _renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
-
 			const _renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
 			const _renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
-
 			const _material = new THREE.ShaderMaterial( {
 			const _material = new THREE.ShaderMaterial( {
 				uniforms: {
 				uniforms: {
 					'mapLeft': {
 					'mapLeft': {
@@ -40,21 +34,18 @@
 					}
 					}
 				},
 				},
 				vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = vec2( uv.x, uv.y );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
 				vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = vec2( uv.x, uv.y );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-				fragmentShader: [ 'uniform sampler2D mapLeft;', 'uniform sampler2D mapRight;', 'varying vec2 vUv;', 'uniform mat3 colorMatrixLeft;', 'uniform mat3 colorMatrixRight;', // These functions implement sRGB linearization and gamma correction
+				fragmentShader: [ 'uniform sampler2D mapLeft;', 'uniform sampler2D mapRight;', 'varying vec2 vUv;', 'uniform mat3 colorMatrixLeft;', 'uniform mat3 colorMatrixRight;',
+					// These functions implement sRGB linearization and gamma correction
+
 					'float lin( float c ) {', '	return c <= 0.04045 ? c * 0.0773993808 :', '			pow( c * 0.9478672986 + 0.0521327014, 2.4 );', '}', 'vec4 lin( vec4 c ) {', '	return vec4( lin( c.r ), lin( c.g ), lin( c.b ), c.a );', '}', 'float dev( float c ) {', '	return c <= 0.0031308 ? c * 12.92', '			: pow( c, 0.41666 ) * 1.055 - 0.055;', '}', 'void main() {', '	vec2 uv = vUv;', '	vec4 colorL = lin( texture2D( mapLeft, uv ) );', '	vec4 colorR = lin( texture2D( mapRight, uv ) );', '	vec3 color = clamp(', '			colorMatrixLeft * colorL.rgb +', '			colorMatrixRight * colorR.rgb, 0., 1. );', '	gl_FragColor = vec4(', '			dev( color.r ), dev( color.g ), dev( color.b ),', '			max( colorL.a, colorR.a ) );', '}' ].join( '\n' )
 					'float lin( float c ) {', '	return c <= 0.04045 ? c * 0.0773993808 :', '			pow( c * 0.9478672986 + 0.0521327014, 2.4 );', '}', 'vec4 lin( vec4 c ) {', '	return vec4( lin( c.r ), lin( c.g ), lin( c.b ), c.a );', '}', 'float dev( float c ) {', '	return c <= 0.0031308 ? c * 12.92', '			: pow( c, 0.41666 ) * 1.055 - 0.055;', '}', 'void main() {', '	vec2 uv = vUv;', '	vec4 colorL = lin( texture2D( mapLeft, uv ) );', '	vec4 colorR = lin( texture2D( mapRight, uv ) );', '	vec3 color = clamp(', '			colorMatrixLeft * colorL.rgb +', '			colorMatrixRight * colorR.rgb, 0., 1. );', '	gl_FragColor = vec4(', '			dev( color.r ), dev( color.g ), dev( color.b ),', '			max( colorL.a, colorR.a ) );', '}' ].join( '\n' )
 			} );
 			} );
-
 			const _mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
 			const _mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
-
 			_scene.add( _mesh );
 			_scene.add( _mesh );
-
 			this.setSize = function ( width, height ) {
 			this.setSize = function ( width, height ) {
 
 
 				renderer.setSize( width, height );
 				renderer.setSize( width, height );
 				const pixelRatio = renderer.getPixelRatio();
 				const pixelRatio = renderer.getPixelRatio();
-
 				_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
 				_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
-
 				_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
 				_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
 
 
 			};
 			};
@@ -64,9 +55,7 @@
 				const currentRenderTarget = renderer.getRenderTarget();
 				const currentRenderTarget = renderer.getRenderTarget();
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
 				_stereo.update( camera );
 				_stereo.update( camera );
-
 				renderer.setRenderTarget( _renderTargetL );
 				renderer.setRenderTarget( _renderTargetL );
 				renderer.clear();
 				renderer.clear();
 				renderer.render( scene, _stereo.cameraL );
 				renderer.render( scene, _stereo.cameraL );
@@ -82,11 +71,8 @@
 			this.dispose = function () {
 			this.dispose = function () {
 
 
 				_renderTargetL.dispose();
 				_renderTargetL.dispose();
-
 				_renderTargetR.dispose();
 				_renderTargetR.dispose();
-
 				_mesh.geometry.dispose();
 				_mesh.geometry.dispose();
-
 				_mesh.material.dispose();
 				_mesh.material.dispose();
 
 
 			};
 			};

+ 32 - 31
examples/js/effects/AsciiEffect.js

@@ -5,6 +5,7 @@
  *
  *
  * 16 April 2012 - @blurspline
  * 16 April 2012 - @blurspline
  */
  */
+
 	class AsciiEffect {
 	class AsciiEffect {
 
 
 		constructor( renderer, charSet = ' .:-=+*#%@', options = {} ) {
 		constructor( renderer, charSet = ' .:-=+*#%@', options = {} ) {
@@ -12,18 +13,15 @@
 			// ' .,:;=|iI+hHOE#`$';
 			// ' .,:;=|iI+hHOE#`$';
 			// darker bolder character set from https://github.com/saw/Canvas-ASCII-Art/
 			// darker bolder character set from https://github.com/saw/Canvas-ASCII-Art/
 			// ' .\'`^",:;Il!i~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$'.split('');
 			// ' .\'`^",:;Il!i~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$'.split('');
+
 			// Some ASCII settings
 			// Some ASCII settings
-			const fResolution = options[ 'resolution' ] || 0.15; // Higher for more details
 
 
+			const fResolution = options[ 'resolution' ] || 0.15; // Higher for more details
 			const iScale = options[ 'scale' ] || 1;
 			const iScale = options[ 'scale' ] || 1;
 			const bColor = options[ 'color' ] || false; // nice but slows down rendering!
 			const bColor = options[ 'color' ] || false; // nice but slows down rendering!
-
 			const bAlpha = options[ 'alpha' ] || false; // Transparency
 			const bAlpha = options[ 'alpha' ] || false; // Transparency
-
 			const bBlock = options[ 'block' ] || false; // blocked characters. like good O dos
 			const bBlock = options[ 'block' ] || false; // blocked characters. like good O dos
-
 			const bInvert = options[ 'invert' ] || false; // black is white, white is black
 			const bInvert = options[ 'invert' ] || false; // black is white, white is black
-
 			const strResolution = options[ 'strResolution' ] || 'low';
 			const strResolution = options[ 'strResolution' ] || 'low';
 			let width, height;
 			let width, height;
 			const domElement = document.createElement( 'div' );
 			const domElement = document.createElement( 'div' );
@@ -32,7 +30,6 @@
 			domElement.appendChild( oAscii );
 			domElement.appendChild( oAscii );
 			let iWidth, iHeight;
 			let iWidth, iHeight;
 			let oImg;
 			let oImg;
-
 			this.setSize = function ( w, h ) {
 			this.setSize = function ( w, h ) {
 
 
 				width = w;
 				width = w;
@@ -49,19 +46,21 @@
 
 
 			};
 			};
 
 
-			this.domElement = domElement; // Throw in ascii library from https://github.com/hassadee/jsascii/blob/master/jsascii.js (MIT License)
+			this.domElement = domElement;
+
+			// Throw in ascii library from https://github.com/hassadee/jsascii/blob/master/jsascii.js (MIT License)
 
 
 			function initAsciiSize() {
 			function initAsciiSize() {
 
 
 				iWidth = Math.round( width * fResolution );
 				iWidth = Math.round( width * fResolution );
 				iHeight = Math.round( height * fResolution );
 				iHeight = Math.round( height * fResolution );
 				oCanvas.width = iWidth;
 				oCanvas.width = iWidth;
-				oCanvas.height = iHeight; // oCanvas.style.display = "none";
+				oCanvas.height = iHeight;
+				// oCanvas.style.display = "none";
 				// oCanvas.style.width = iWidth;
 				// oCanvas.style.width = iWidth;
 				// oCanvas.style.height = iHeight;
 				// oCanvas.style.height = iHeight;
 
 
 				oImg = renderer.domElement;
 				oImg = renderer.domElement;
-
 				if ( oImg.style.backgroundColor ) {
 				if ( oImg.style.backgroundColor ) {
 
 
 					oAscii.rows[ 0 ].cells[ 0 ].style.backgroundColor = oImg.style.backgroundColor;
 					oAscii.rows[ 0 ].cells[ 0 ].style.backgroundColor = oImg.style.backgroundColor;
@@ -92,7 +91,6 @@
 			const strFont = 'courier new, monospace';
 			const strFont = 'courier new, monospace';
 			const oCanvasImg = renderer.domElement;
 			const oCanvasImg = renderer.domElement;
 			const oCanvas = document.createElement( 'canvas' );
 			const oCanvas = document.createElement( 'canvas' );
-
 			if ( ! oCanvas.getContext ) {
 			if ( ! oCanvas.getContext ) {
 
 
 				return;
 				return;
@@ -100,7 +98,6 @@
 			}
 			}
 
 
 			const oCtx = oCanvas.getContext( '2d' );
 			const oCtx = oCanvas.getContext( '2d' );
-
 			if ( ! oCtx.getImageData ) {
 			if ( ! oCtx.getImageData ) {
 
 
 				return;
 				return;
@@ -108,13 +105,16 @@
 			}
 			}
 
 
 			let aCharList = bColor ? aDefaultColorCharList : aDefaultCharList;
 			let aCharList = bColor ? aDefaultColorCharList : aDefaultCharList;
-			if ( charSet ) aCharList = charSet; // Setup dom
+			if ( charSet ) aCharList = charSet;
+
+			// Setup dom
 
 
 			const fFontSize = 2 / fResolution * iScale;
 			const fFontSize = 2 / fResolution * iScale;
-			const fLineHeight = 2 / fResolution * iScale; // adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width.
+			const fLineHeight = 2 / fResolution * iScale;
 
 
-			let fLetterSpacing = 0;
+			// adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width.
 
 
+			let fLetterSpacing = 0;
 			if ( strResolution == 'low' ) {
 			if ( strResolution == 'low' ) {
 
 
 				switch ( iScale ) {
 				switch ( iScale ) {
@@ -122,16 +122,13 @@
 					case 1:
 					case 1:
 						fLetterSpacing = - 1;
 						fLetterSpacing = - 1;
 						break;
 						break;
-
 					case 2:
 					case 2:
 					case 3:
 					case 3:
 						fLetterSpacing = - 2.1;
 						fLetterSpacing = - 2.1;
 						break;
 						break;
-
 					case 4:
 					case 4:
 						fLetterSpacing = - 3.1;
 						fLetterSpacing = - 3.1;
 						break;
 						break;
-
 					case 5:
 					case 5:
 						fLetterSpacing = - 4.15;
 						fLetterSpacing = - 4.15;
 						break;
 						break;
@@ -147,15 +144,12 @@
 					case 1:
 					case 1:
 						fLetterSpacing = 0;
 						fLetterSpacing = 0;
 						break;
 						break;
-
 					case 2:
 					case 2:
 						fLetterSpacing = - 1;
 						fLetterSpacing = - 1;
 						break;
 						break;
-
 					case 3:
 					case 3:
 						fLetterSpacing = - 1.04;
 						fLetterSpacing = - 1.04;
 						break;
 						break;
-
 					case 4:
 					case 4:
 					case 5:
 					case 5:
 						fLetterSpacing = - 2.1;
 						fLetterSpacing = - 2.1;
@@ -173,7 +167,6 @@
 					case 2:
 					case 2:
 						fLetterSpacing = 0;
 						fLetterSpacing = 0;
 						break;
 						break;
-
 					case 3:
 					case 3:
 					case 4:
 					case 4:
 					case 5:
 					case 5:
@@ -182,17 +175,22 @@
 
 
 				}
 				}
 
 
-			} // can't get a span or div to flow like an img element, but a table works?
-			// convert img element to ascii
+			}
 
 
+			// can't get a span or div to flow like an img element, but a table works?
+
+			// convert img element to ascii
 
 
 			function asciifyImage( oAscii ) {
 			function asciifyImage( oAscii ) {
 
 
 				oCtx.clearRect( 0, 0, iWidth, iHeight );
 				oCtx.clearRect( 0, 0, iWidth, iHeight );
 				oCtx.drawImage( oCanvasImg, 0, 0, iWidth, iHeight );
 				oCtx.drawImage( oCanvasImg, 0, 0, iWidth, iHeight );
-				const oImgData = oCtx.getImageData( 0, 0, iWidth, iHeight ).data; // Coloring loop starts now
+				const oImgData = oCtx.getImageData( 0, 0, iWidth, iHeight ).data;
 
 
-				let strChars = ''; // console.time('rendering');
+				// Coloring loop starts now
+				let strChars = '';
+
+				// console.time('rendering');
 
 
 				for ( let y = 0; y < iHeight; y += 2 ) {
 				for ( let y = 0; y < iHeight; y += 2 ) {
 
 
@@ -205,7 +203,8 @@
 						const iAlpha = oImgData[ iOffset + 3 ];
 						const iAlpha = oImgData[ iOffset + 3 ];
 						let iCharIdx;
 						let iCharIdx;
 						let fBrightness;
 						let fBrightness;
-						fBrightness = ( 0.3 * iRed + 0.59 * iGreen + 0.11 * iBlue ) / 255; // fBrightness = (0.3*iRed + 0.5*iGreen + 0.3*iBlue) / 255;
+						fBrightness = ( 0.3 * iRed + 0.59 * iGreen + 0.11 * iBlue ) / 255;
+						// fBrightness = (0.3*iRed + 0.5*iGreen + 0.3*iBlue) / 255;
 
 
 						if ( iAlpha == 0 ) {
 						if ( iAlpha == 0 ) {
 
 
@@ -216,19 +215,18 @@
 						}
 						}
 
 
 						iCharIdx = Math.floor( ( 1 - fBrightness ) * ( aCharList.length - 1 ) );
 						iCharIdx = Math.floor( ( 1 - fBrightness ) * ( aCharList.length - 1 ) );
-
 						if ( bInvert ) {
 						if ( bInvert ) {
 
 
 							iCharIdx = aCharList.length - iCharIdx - 1;
 							iCharIdx = aCharList.length - iCharIdx - 1;
 
 
-						} // good for debugging
+						}
+
+						// good for debugging
 						//fBrightness = Math.floor(fBrightness * 10);
 						//fBrightness = Math.floor(fBrightness * 10);
 						//strThisChar = fBrightness;
 						//strThisChar = fBrightness;
 
 
-
 						let strThisChar = aCharList[ iCharIdx ];
 						let strThisChar = aCharList[ iCharIdx ];
 						if ( strThisChar === undefined || strThisChar == ' ' ) strThisChar = '&nbsp;';
 						if ( strThisChar === undefined || strThisChar == ' ' ) strThisChar = '&nbsp;';
-
 						if ( bColor ) {
 						if ( bColor ) {
 
 
 							strChars += '<span style=\'' + 'color:rgb(' + iRed + ',' + iGreen + ',' + iBlue + ');' + ( bBlock ? 'background-color:rgb(' + iRed + ',' + iGreen + ',' + iBlue + ');' : '' ) + ( bAlpha ? 'opacity:' + iAlpha / 255 + ';' : '' ) + '\'>' + strThisChar + '</span>';
 							strChars += '<span style=\'' + 'color:rgb(' + iRed + ',' + iGreen + ',' + iBlue + ');' + ( bBlock ? 'background-color:rgb(' + iRed + ',' + iGreen + ',' + iBlue + ');' : '' ) + ( bAlpha ? 'opacity:' + iAlpha / 255 + ';' : '' ) + '\'>' + strThisChar + '</span>';
@@ -245,7 +243,10 @@
 
 
 				}
 				}
 
 
-				oAscii.innerHTML = '<tr><td>' + strChars + '</td></tr>'; // console.timeEnd('rendering');
+				oAscii.innerHTML = '<tr><td>' + strChars + '</td></tr>';
+
+				// console.timeEnd('rendering');
+
 				// return oAscii;
 				// return oAscii;
 
 
 			}
 			}

+ 26 - 30
examples/js/effects/OutlineEffect.js

@@ -64,21 +64,26 @@
 			const defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
 			const defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
 			const defaultColor = new THREE.Color().fromArray( parameters.defaultColor !== undefined ? parameters.defaultColor : [ 0, 0, 0 ] );
 			const defaultColor = new THREE.Color().fromArray( parameters.defaultColor !== undefined ? parameters.defaultColor : [ 0, 0, 0 ] );
 			const defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0;
 			const defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0;
-			const defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false; // object.material.uuid -> outlineMaterial or
+			const defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false;
+
+			// object.material.uuid -> outlineMaterial or
 			// object.material[ n ].uuid -> outlineMaterial
 			// object.material[ n ].uuid -> outlineMaterial
 			// save at the outline material creation and release
 			// save at the outline material creation and release
 			// if it's unused removeThresholdCount frames
 			// if it's unused removeThresholdCount frames
 			// unless keepAlive is true.
 			// unless keepAlive is true.
-
 			const cache = {};
 			const cache = {};
-			const removeThresholdCount = 60; // outlineMaterial.uuid -> object.material or
+			const removeThresholdCount = 60;
+
+			// outlineMaterial.uuid -> object.material or
 			// outlineMaterial.uuid -> object.material[ n ]
 			// outlineMaterial.uuid -> object.material[ n ]
 			// save before render and release after render.
 			// save before render and release after render.
+			const originalMaterials = {};
 
 
-			const originalMaterials = {}; // object.uuid -> originalOnBeforeRender
+			// object.uuid -> originalOnBeforeRender
 			// save before render and release after render.
 			// save before render and release after render.
+			const originalOnBeforeRenders = {};
 
 
-			const originalOnBeforeRenders = {}; //this.cache = cache;  // for debug
+			//this.cache = cache;  // for debug
 
 
 			const uniformsOutline = {
 			const uniformsOutline = {
 				outlineThickness: {
 				outlineThickness: {
@@ -91,12 +96,15 @@
 					value: defaultAlpha
 					value: defaultAlpha
 				}
 				}
 			};
 			};
-			const vertexShader = [ '#include <common>', '#include <uv_pars_vertex>', '#include <displacementmap_pars_vertex>', '#include <fog_pars_vertex>', '#include <morphtarget_pars_vertex>', '#include <skinning_pars_vertex>', '#include <logdepthbuf_pars_vertex>', '#include <clipping_planes_pars_vertex>', 'uniform float outlineThickness;', 'vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {', '	float thickness = outlineThickness;', '	const float ratio = 1.0;', // TODO: support outline thickness ratio for each vertex
-				'	vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );', // NOTE: subtract pos2 from pos because THREE.BackSide objectNormal is negative
-				'	vec4 norm = normalize( pos - pos2 );', '	return pos + norm * thickness * pos.w * ratio;', '}', 'void main() {', '	#include <uv_vertex>', '	#include <beginnormal_vertex>', '	#include <morphnormal_vertex>', '	#include <skinbase_vertex>', '	#include <skinnormal_vertex>', '	#include <begin_vertex>', '	#include <morphtarget_vertex>', '	#include <skinning_vertex>', '	#include <displacementmap_vertex>', '	#include <project_vertex>', '	vec3 outlineNormal = - objectNormal;', // the outline material is always rendered with THREE.BackSide
+			const vertexShader = [ '#include <common>', '#include <uv_pars_vertex>', '#include <displacementmap_pars_vertex>', '#include <fog_pars_vertex>', '#include <morphtarget_pars_vertex>', '#include <skinning_pars_vertex>', '#include <logdepthbuf_pars_vertex>', '#include <clipping_planes_pars_vertex>', 'uniform float outlineThickness;', 'vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {', '	float thickness = outlineThickness;', '	const float ratio = 1.0;',
+				// TODO: support outline thickness ratio for each vertex
+				'	vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );',
+				// NOTE: subtract pos2 from pos because THREE.BackSide objectNormal is negative
+				'	vec4 norm = normalize( pos - pos2 );', '	return pos + norm * thickness * pos.w * ratio;', '}', 'void main() {', '	#include <uv_vertex>', '	#include <beginnormal_vertex>', '	#include <morphnormal_vertex>', '	#include <skinbase_vertex>', '	#include <skinnormal_vertex>', '	#include <begin_vertex>', '	#include <morphtarget_vertex>', '	#include <skinning_vertex>', '	#include <displacementmap_vertex>', '	#include <project_vertex>', '	vec3 outlineNormal = - objectNormal;',
+				// the outline material is always rendered with THREE.BackSide
+
 				'	gl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );', '	#include <logdepthbuf_vertex>', '	#include <clipping_planes_vertex>', '	#include <fog_vertex>', '}' ].join( '\n' );
 				'	gl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );', '	#include <logdepthbuf_vertex>', '	#include <clipping_planes_vertex>', '	#include <fog_vertex>', '}' ].join( '\n' );
 			const fragmentShader = [ '#include <common>', '#include <fog_pars_fragment>', '#include <logdepthbuf_pars_fragment>', '#include <clipping_planes_pars_fragment>', 'uniform vec3 outlineColor;', 'uniform float outlineAlpha;', 'void main() {', '	#include <clipping_planes_fragment>', '	#include <logdepthbuf_fragment>', '	gl_FragColor = vec4( outlineColor, outlineAlpha );', '	#include <tonemapping_fragment>', '	#include <encodings_fragment>', '	#include <fog_fragment>', '	#include <premultiplied_alpha_fragment>', '}' ].join( '\n' );
 			const fragmentShader = [ '#include <common>', '#include <fog_pars_fragment>', '#include <logdepthbuf_pars_fragment>', '#include <clipping_planes_pars_fragment>', 'uniform vec3 outlineColor;', 'uniform float outlineAlpha;', 'void main() {', '	#include <clipping_planes_fragment>', '	#include <logdepthbuf_fragment>', '	gl_FragColor = vec4( outlineColor, outlineAlpha );', '	#include <tonemapping_fragment>', '	#include <encodings_fragment>', '	#include <fog_fragment>', '	#include <premultiplied_alpha_fragment>', '}' ].join( '\n' );
-
 			function createMaterial() {
 			function createMaterial() {
 
 
 				return new THREE.ShaderMaterial( {
 				return new THREE.ShaderMaterial( {
@@ -112,7 +120,6 @@
 			function getOutlineMaterialFromCache( originalMaterial ) {
 			function getOutlineMaterialFromCache( originalMaterial ) {
 
 
 				let data = cache[ originalMaterial.uuid ];
 				let data = cache[ originalMaterial.uuid ];
-
 				if ( data === undefined ) {
 				if ( data === undefined ) {
 
 
 					data = {
 					data = {
@@ -143,7 +150,6 @@
 
 
 				const geometry = object.geometry;
 				const geometry = object.geometry;
 				let hasNormals = false;
 				let hasNormals = false;
-
 				if ( object.geometry !== undefined ) {
 				if ( object.geometry !== undefined ) {
 
 
 					if ( geometry.isBufferGeometry ) {
 					if ( geometry.isBufferGeometry ) {
@@ -165,7 +171,6 @@
 			function setOutlineMaterial( object ) {
 			function setOutlineMaterial( object ) {
 
 
 				if ( isCompatible( object ) === false ) return;
 				if ( isCompatible( object ) === false ) return;
-
 				if ( Array.isArray( object.material ) ) {
 				if ( Array.isArray( object.material ) ) {
 
 
 					for ( let i = 0, il = object.material.length; i < il; i ++ ) {
 					for ( let i = 0, il = object.material.length; i < il; i ++ ) {
@@ -188,7 +193,6 @@
 			function restoreOriginalMaterial( object ) {
 			function restoreOriginalMaterial( object ) {
 
 
 				if ( isCompatible( object ) === false ) return;
 				if ( isCompatible( object ) === false ) return;
-
 				if ( Array.isArray( object.material ) ) {
 				if ( Array.isArray( object.material ) ) {
 
 
 					for ( let i = 0, il = object.material.length; i < il; i ++ ) {
 					for ( let i = 0, il = object.material.length; i < il; i ++ ) {
@@ -209,8 +213,9 @@
 
 
 			function onBeforeRender( renderer, scene, camera, geometry, material ) {
 			function onBeforeRender( renderer, scene, camera, geometry, material ) {
 
 
-				const originalMaterial = originalMaterials[ material.uuid ]; // just in case
+				const originalMaterial = originalMaterials[ material.uuid ];
 
 
+				// just in case
 				if ( originalMaterial === undefined ) return;
 				if ( originalMaterial === undefined ) return;
 				updateUniforms( material, originalMaterial );
 				updateUniforms( material, originalMaterial );
 
 
@@ -220,7 +225,6 @@
 
 
 				const outlineParameters = originalMaterial.userData.outlineParameters;
 				const outlineParameters = originalMaterial.userData.outlineParameters;
 				material.uniforms.outlineAlpha.value = originalMaterial.opacity;
 				material.uniforms.outlineAlpha.value = originalMaterial.opacity;
-
 				if ( outlineParameters !== undefined ) {
 				if ( outlineParameters !== undefined ) {
 
 
 					if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
 					if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
@@ -247,7 +251,6 @@
 				material.toneMapped = originalMaterial.toneMapped;
 				material.toneMapped = originalMaterial.toneMapped;
 				material.premultipliedAlpha = originalMaterial.premultipliedAlpha;
 				material.premultipliedAlpha = originalMaterial.premultipliedAlpha;
 				material.displacementMap = originalMaterial.displacementMap;
 				material.displacementMap = originalMaterial.displacementMap;
-
 				if ( outlineParameters !== undefined ) {
 				if ( outlineParameters !== undefined ) {
 
 
 					if ( originalMaterial.visible === false ) {
 					if ( originalMaterial.visible === false ) {
@@ -271,7 +274,6 @@
 				}
 				}
 
 
 				if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
 				if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
-
 				if ( originalMaterial.clippingPlanes ) {
 				if ( originalMaterial.clippingPlanes ) {
 
 
 					material.clipping = true;
 					material.clipping = true;
@@ -287,36 +289,32 @@
 
 
 			function cleanupCache() {
 			function cleanupCache() {
 
 
-				let keys; // clear originialMaterials
+				let keys;
 
 
+				// clear originialMaterials
 				keys = Object.keys( originalMaterials );
 				keys = Object.keys( originalMaterials );
-
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 
 					originalMaterials[ keys[ i ] ] = undefined;
 					originalMaterials[ keys[ i ] ] = undefined;
 
 
-				} // clear originalOnBeforeRenders
-
+				}
 
 
+				// clear originalOnBeforeRenders
 				keys = Object.keys( originalOnBeforeRenders );
 				keys = Object.keys( originalOnBeforeRenders );
-
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 
 					originalOnBeforeRenders[ keys[ i ] ] = undefined;
 					originalOnBeforeRenders[ keys[ i ] ] = undefined;
 
 
-				} // remove unused outlineMaterial from cache
-
+				}
 
 
+				// remove unused outlineMaterial from cache
 				keys = Object.keys( cache );
 				keys = Object.keys( cache );
-
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 
 					const key = keys[ i ];
 					const key = keys[ i ];
-
 					if ( cache[ key ].used === false ) {
 					if ( cache[ key ].used === false ) {
 
 
 						cache[ key ].count ++;
 						cache[ key ].count ++;
-
 						if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) {
 						if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) {
 
 
 							delete cache[ key ];
 							delete cache[ key ];
@@ -371,6 +369,7 @@
 				renderer.shadowMap.enabled = currentShadowMapEnabled;
 				renderer.shadowMap.enabled = currentShadowMapEnabled;
 
 
 			};
 			};
+
 			/*
 			/*
      * See #9918
      * See #9918
      *
      *
@@ -385,12 +384,9 @@
      *
      *
      * }
      * }
      */
      */
-
-
 			this.autoClear = renderer.autoClear;
 			this.autoClear = renderer.autoClear;
 			this.domElement = renderer.domElement;
 			this.domElement = renderer.domElement;
 			this.shadowMap = renderer.shadowMap;
 			this.shadowMap = renderer.shadowMap;
-
 			this.clear = function ( color, depth, stencil ) {
 			this.clear = function ( color, depth, stencil ) {
 
 
 				renderer.clear( color, depth, stencil );
 				renderer.clear( color, depth, stencil );

+ 0 - 13
examples/js/effects/ParallaxBarrierEffect.js

@@ -5,21 +5,15 @@
 		constructor( renderer ) {
 		constructor( renderer ) {
 
 
 			const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
 			const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-
 			const _scene = new THREE.Scene();
 			const _scene = new THREE.Scene();
-
 			const _stereo = new THREE.StereoCamera();
 			const _stereo = new THREE.StereoCamera();
-
 			const _params = {
 			const _params = {
 				minFilter: THREE.LinearFilter,
 				minFilter: THREE.LinearFilter,
 				magFilter: THREE.NearestFilter,
 				magFilter: THREE.NearestFilter,
 				format: THREE.RGBAFormat
 				format: THREE.RGBAFormat
 			};
 			};
-
 			const _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
 			const _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
-
 			const _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
 			const _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
-
 			const _material = new THREE.ShaderMaterial( {
 			const _material = new THREE.ShaderMaterial( {
 				uniforms: {
 				uniforms: {
 					'mapLeft': {
 					'mapLeft': {
@@ -32,18 +26,13 @@
 				vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = vec2( uv.x, uv.y );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
 				vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = vec2( uv.x, uv.y );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
 				fragmentShader: [ 'uniform sampler2D mapLeft;', 'uniform sampler2D mapRight;', 'varying vec2 vUv;', 'void main() {', '	vec2 uv = vUv;', '	if ( ( mod( gl_FragCoord.y, 2.0 ) ) > 1.00 ) {', '		gl_FragColor = texture2D( mapLeft, uv );', '	} else {', '		gl_FragColor = texture2D( mapRight, uv );', '	}', '}' ].join( '\n' )
 				fragmentShader: [ 'uniform sampler2D mapLeft;', 'uniform sampler2D mapRight;', 'varying vec2 vUv;', 'void main() {', '	vec2 uv = vUv;', '	if ( ( mod( gl_FragCoord.y, 2.0 ) ) > 1.00 ) {', '		gl_FragColor = texture2D( mapLeft, uv );', '	} else {', '		gl_FragColor = texture2D( mapRight, uv );', '	}', '}' ].join( '\n' )
 			} );
 			} );
-
 			const mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
 			const mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
-
 			_scene.add( mesh );
 			_scene.add( mesh );
-
 			this.setSize = function ( width, height ) {
 			this.setSize = function ( width, height ) {
 
 
 				renderer.setSize( width, height );
 				renderer.setSize( width, height );
 				const pixelRatio = renderer.getPixelRatio();
 				const pixelRatio = renderer.getPixelRatio();
-
 				_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
 				_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
-
 				_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
 				_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
 
 
 			};
 			};
@@ -52,9 +41,7 @@
 
 
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
 				_stereo.update( camera );
 				_stereo.update( camera );
-
 				renderer.setRenderTarget( _renderTargetL );
 				renderer.setRenderTarget( _renderTargetL );
 				renderer.clear();
 				renderer.clear();
 				renderer.render( scene, _stereo.cameraL );
 				renderer.render( scene, _stereo.cameraL );

+ 12 - 39
examples/js/effects/PeppersGhostEffect.js

@@ -10,35 +10,24 @@
 
 
 			const scope = this;
 			const scope = this;
 			scope.cameraDistance = 15;
 			scope.cameraDistance = 15;
-			scope.reflectFromAbove = false; // Internals
+			scope.reflectFromAbove = false;
 
 
+			// Internals
 			let _halfWidth, _width, _height;
 			let _halfWidth, _width, _height;
-
 			const _cameraF = new THREE.PerspectiveCamera(); //front
 			const _cameraF = new THREE.PerspectiveCamera(); //front
-
-
 			const _cameraB = new THREE.PerspectiveCamera(); //back
 			const _cameraB = new THREE.PerspectiveCamera(); //back
-
-
 			const _cameraL = new THREE.PerspectiveCamera(); //left
 			const _cameraL = new THREE.PerspectiveCamera(); //left
-
-
 			const _cameraR = new THREE.PerspectiveCamera(); //right
 			const _cameraR = new THREE.PerspectiveCamera(); //right
 
 
-
 			const _position = new THREE.Vector3();
 			const _position = new THREE.Vector3();
-
 			const _quaternion = new THREE.Quaternion();
 			const _quaternion = new THREE.Quaternion();
+			const _scale = new THREE.Vector3();
 
 
-			const _scale = new THREE.Vector3(); // Initialization
-
-
+			// Initialization
 			renderer.autoClear = false;
 			renderer.autoClear = false;
-
 			this.setSize = function ( width, height ) {
 			this.setSize = function ( width, height ) {
 
 
 				_halfWidth = width / 2;
 				_halfWidth = width / 2;
-
 				if ( width < height ) {
 				if ( width < height ) {
 
 
 					_width = width / 3;
 					_width = width / 3;
@@ -59,51 +48,38 @@
 
 
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-				camera.matrixWorld.decompose( _position, _quaternion, _scale ); // front
+				camera.matrixWorld.decompose( _position, _quaternion, _scale );
 
 
+				// front
 				_cameraF.position.copy( _position );
 				_cameraF.position.copy( _position );
-
 				_cameraF.quaternion.copy( _quaternion );
 				_cameraF.quaternion.copy( _quaternion );
-
 				_cameraF.translateZ( scope.cameraDistance );
 				_cameraF.translateZ( scope.cameraDistance );
+				_cameraF.lookAt( scene.position );
 
 
-				_cameraF.lookAt( scene.position ); // back
-
-
+				// back
 				_cameraB.position.copy( _position );
 				_cameraB.position.copy( _position );
-
 				_cameraB.quaternion.copy( _quaternion );
 				_cameraB.quaternion.copy( _quaternion );
-
 				_cameraB.translateZ( - scope.cameraDistance );
 				_cameraB.translateZ( - scope.cameraDistance );
-
 				_cameraB.lookAt( scene.position );
 				_cameraB.lookAt( scene.position );
+				_cameraB.rotation.z += 180 * ( Math.PI / 180 );
 
 
-				_cameraB.rotation.z += 180 * ( Math.PI / 180 ); // left
-
+				// left
 				_cameraL.position.copy( _position );
 				_cameraL.position.copy( _position );
-
 				_cameraL.quaternion.copy( _quaternion );
 				_cameraL.quaternion.copy( _quaternion );
-
 				_cameraL.translateX( - scope.cameraDistance );
 				_cameraL.translateX( - scope.cameraDistance );
-
 				_cameraL.lookAt( scene.position );
 				_cameraL.lookAt( scene.position );
+				_cameraL.rotation.x += 90 * ( Math.PI / 180 );
 
 
-				_cameraL.rotation.x += 90 * ( Math.PI / 180 ); // right
-
+				// right
 				_cameraR.position.copy( _position );
 				_cameraR.position.copy( _position );
-
 				_cameraR.quaternion.copy( _quaternion );
 				_cameraR.quaternion.copy( _quaternion );
-
 				_cameraR.translateX( scope.cameraDistance );
 				_cameraR.translateX( scope.cameraDistance );
-
 				_cameraR.lookAt( scene.position );
 				_cameraR.lookAt( scene.position );
-
 				_cameraR.rotation.x += 90 * ( Math.PI / 180 );
 				_cameraR.rotation.x += 90 * ( Math.PI / 180 );
 				renderer.clear();
 				renderer.clear();
 				renderer.setScissorTest( true );
 				renderer.setScissorTest( true );
 				renderer.setScissor( _halfWidth - _width / 2, _height * 2, _width, _height );
 				renderer.setScissor( _halfWidth - _width / 2, _height * 2, _width, _height );
 				renderer.setViewport( _halfWidth - _width / 2, _height * 2, _width, _height );
 				renderer.setViewport( _halfWidth - _width / 2, _height * 2, _width, _height );
-
 				if ( scope.reflectFromAbove ) {
 				if ( scope.reflectFromAbove ) {
 
 
 					renderer.render( scene, _cameraB );
 					renderer.render( scene, _cameraB );
@@ -116,7 +92,6 @@
 
 
 				renderer.setScissor( _halfWidth - _width / 2, 0, _width, _height );
 				renderer.setScissor( _halfWidth - _width / 2, 0, _width, _height );
 				renderer.setViewport( _halfWidth - _width / 2, 0, _width, _height );
 				renderer.setViewport( _halfWidth - _width / 2, 0, _width, _height );
-
 				if ( scope.reflectFromAbove ) {
 				if ( scope.reflectFromAbove ) {
 
 
 					renderer.render( scene, _cameraF );
 					renderer.render( scene, _cameraF );
@@ -129,7 +104,6 @@
 
 
 				renderer.setScissor( _halfWidth - _width / 2 - _width, _height, _width, _height );
 				renderer.setScissor( _halfWidth - _width / 2 - _width, _height, _width, _height );
 				renderer.setViewport( _halfWidth - _width / 2 - _width, _height, _width, _height );
 				renderer.setViewport( _halfWidth - _width / 2 - _width, _height, _width, _height );
-
 				if ( scope.reflectFromAbove ) {
 				if ( scope.reflectFromAbove ) {
 
 
 					renderer.render( scene, _cameraR );
 					renderer.render( scene, _cameraR );
@@ -142,7 +116,6 @@
 
 
 				renderer.setScissor( _halfWidth + _width / 2, _height, _width, _height );
 				renderer.setScissor( _halfWidth + _width / 2, _height, _width, _height );
 				renderer.setViewport( _halfWidth + _width / 2, _height, _width, _height );
 				renderer.setViewport( _halfWidth + _width / 2, _height, _width, _height );
-
 				if ( scope.reflectFromAbove ) {
 				if ( scope.reflectFromAbove ) {
 
 
 					renderer.render( scene, _cameraL );
 					renderer.render( scene, _cameraL );

+ 0 - 4
examples/js/effects/StereoEffect.js

@@ -5,10 +5,8 @@
 		constructor( renderer ) {
 		constructor( renderer ) {
 
 
 			const _stereo = new THREE.StereoCamera();
 			const _stereo = new THREE.StereoCamera();
-
 			_stereo.aspect = 0.5;
 			_stereo.aspect = 0.5;
 			const size = new THREE.Vector2();
 			const size = new THREE.Vector2();
-
 			this.setEyeSeparation = function ( eyeSep ) {
 			this.setEyeSeparation = function ( eyeSep ) {
 
 
 				_stereo.eyeSep = eyeSep;
 				_stereo.eyeSep = eyeSep;
@@ -25,9 +23,7 @@
 
 
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
 				_stereo.update( camera );
 				_stereo.update( camera );
-
 				renderer.getSize( size );
 				renderer.getSize( size );
 				if ( renderer.autoClear ) renderer.clear();
 				if ( renderer.autoClear ) renderer.clear();
 				renderer.setScissorTest( true );
 				renderer.setScissorTest( true );

+ 12 - 10
examples/js/environments/RoomEnvironment.js

@@ -3,7 +3,6 @@
 	/**
 	/**
  * https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/EnvironmentScene.ts
  * https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/EnvironmentScene.ts
  */
  */
-
 	class RoomEnvironment extends THREE.Scene {
 	class RoomEnvironment extends THREE.Scene {
 
 
 		constructor() {
 		constructor() {
@@ -51,40 +50,45 @@
 			box6.position.set( - 2.193, - 0.369, - 5.547 );
 			box6.position.set( - 2.193, - 0.369, - 5.547 );
 			box6.rotation.set( 0, 0.516, 0 );
 			box6.rotation.set( 0, 0.516, 0 );
 			box6.scale.set( 3.875, 3.487, 2.986 );
 			box6.scale.set( 3.875, 3.487, 2.986 );
-			this.add( box6 ); // -x right
+			this.add( box6 );
 
 
+			// -x right
 			const light1 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) );
 			const light1 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) );
 			light1.position.set( - 16.116, 14.37, 8.208 );
 			light1.position.set( - 16.116, 14.37, 8.208 );
 			light1.scale.set( 0.1, 2.428, 2.739 );
 			light1.scale.set( 0.1, 2.428, 2.739 );
-			this.add( light1 ); // -x left
+			this.add( light1 );
 
 
+			// -x left
 			const light2 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) );
 			const light2 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) );
 			light2.position.set( - 16.109, 18.021, - 8.207 );
 			light2.position.set( - 16.109, 18.021, - 8.207 );
 			light2.scale.set( 0.1, 2.425, 2.751 );
 			light2.scale.set( 0.1, 2.425, 2.751 );
-			this.add( light2 ); // +x
+			this.add( light2 );
 
 
+			// +x
 			const light3 = new THREE.Mesh( geometry, createAreaLightMaterial( 17 ) );
 			const light3 = new THREE.Mesh( geometry, createAreaLightMaterial( 17 ) );
 			light3.position.set( 14.904, 12.198, - 1.832 );
 			light3.position.set( 14.904, 12.198, - 1.832 );
 			light3.scale.set( 0.15, 4.265, 6.331 );
 			light3.scale.set( 0.15, 4.265, 6.331 );
-			this.add( light3 ); // +z
+			this.add( light3 );
 
 
+			// +z
 			const light4 = new THREE.Mesh( geometry, createAreaLightMaterial( 43 ) );
 			const light4 = new THREE.Mesh( geometry, createAreaLightMaterial( 43 ) );
 			light4.position.set( - 0.462, 8.89, 14.520 );
 			light4.position.set( - 0.462, 8.89, 14.520 );
 			light4.scale.set( 4.38, 5.441, 0.088 );
 			light4.scale.set( 4.38, 5.441, 0.088 );
-			this.add( light4 ); // -z
+			this.add( light4 );
 
 
+			// -z
 			const light5 = new THREE.Mesh( geometry, createAreaLightMaterial( 20 ) );
 			const light5 = new THREE.Mesh( geometry, createAreaLightMaterial( 20 ) );
 			light5.position.set( 3.235, 11.486, - 12.541 );
 			light5.position.set( 3.235, 11.486, - 12.541 );
 			light5.scale.set( 2.5, 2.0, 0.1 );
 			light5.scale.set( 2.5, 2.0, 0.1 );
-			this.add( light5 ); // +y
+			this.add( light5 );
 
 
+			// +y
 			const light6 = new THREE.Mesh( geometry, createAreaLightMaterial( 100 ) );
 			const light6 = new THREE.Mesh( geometry, createAreaLightMaterial( 100 ) );
 			light6.position.set( 0.0, 20.0, 0.0 );
 			light6.position.set( 0.0, 20.0, 0.0 );
 			light6.scale.set( 1.0, 0.1, 1.0 );
 			light6.scale.set( 1.0, 0.1, 1.0 );
 			this.add( light6 );
 			this.add( light6 );
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			const resources = new Set();
 			const resources = new Set();
@@ -98,7 +102,6 @@
 				}
 				}
 
 
 			} );
 			} );
-
 			for ( const resource of resources ) {
 			for ( const resource of resources ) {
 
 
 				resource.dispose();
 				resource.dispose();
@@ -108,7 +111,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function createAreaLightMaterial( intensity ) {
 	function createAreaLightMaterial( intensity ) {
 
 
 		const material = new THREE.MeshBasicMaterial();
 		const material = new THREE.MeshBasicMaterial();

+ 48 - 65
examples/js/exporters/ColladaExporter.js

@@ -24,7 +24,6 @@
 				unitName: null,
 				unitName: null,
 				unitMeter: null
 				unitMeter: null
 			}, options );
 			}, options );
-
 			if ( options.upAxis.match( /^[XYZ]_UP$/ ) === null ) {
 			if ( options.upAxis.match( /^[XYZ]_UP$/ ) === null ) {
 
 
 				console.error( 'ColladaExporter: Invalid upAxis: valid values are X_UP, Y_UP or Z_UP.' );
 				console.error( 'ColladaExporter: Invalid upAxis: valid values are X_UP, Y_UP or Z_UP.' );
@@ -53,23 +52,20 @@
 			}
 			}
 
 
 			const version = options.version;
 			const version = options.version;
-
 			if ( version !== '1.4.1' && version !== '1.5.0' ) {
 			if ( version !== '1.4.1' && version !== '1.5.0' ) {
 
 
 				console.warn( `ColladaExporter : Version ${version} not supported for export. Only 1.4.1 and 1.5.0.` );
 				console.warn( `ColladaExporter : Version ${version} not supported for export. Only 1.4.1 and 1.5.0.` );
 				return null;
 				return null;
 
 
-			} // Convert the urdf xml into a well-formatted, indented format
-
+			}
 
 
+			// Convert the urdf xml into a well-formatted, indented format
 			function format( urdf ) {
 			function format( urdf ) {
 
 
 				const IS_END_TAG = /^<\//;
 				const IS_END_TAG = /^<\//;
 				const IS_SELF_CLOSING = /(\?>$)|(\/>$)/;
 				const IS_SELF_CLOSING = /(\?>$)|(\/>$)/;
 				const HAS_TEXT = /<[^>]+>[^<]*<\/[^<]+>/;
 				const HAS_TEXT = /<[^>]+>[^<]*<\/[^<]+>/;
-
 				const pad = ( ch, num ) => num > 0 ? ch + pad( ch, num - 1 ) : '';
 				const pad = ( ch, num ) => num > 0 ? ch + pad( ch, num - 1 ) : '';
-
 				let tagnum = 0;
 				let tagnum = 0;
 				return urdf.match( /(<[^>]+>[^<]+<\/[^<]+>)|(<[^>]+>)/g ).map( tag => {
 				return urdf.match( /(<[^>]+>[^<]+<\/[^<]+>)|(<[^>]+>)/g ).map( tag => {
 
 
@@ -80,7 +76,6 @@
 					}
 					}
 
 
 					const res = `${pad( '  ', tagnum )}${tag}`;
 					const res = `${pad( '  ', tagnum )}${tag}`;
-
 					if ( ! HAS_TEXT.test( tag ) && ! IS_SELF_CLOSING.test( tag ) && ! IS_END_TAG.test( tag ) ) {
 					if ( ! HAS_TEXT.test( tag ) && ! IS_SELF_CLOSING.test( tag ) && ! IS_END_TAG.test( tag ) ) {
 
 
 						tagnum ++;
 						tagnum ++;
@@ -91,14 +86,13 @@
 
 
 				} ).join( '\n' );
 				} ).join( '\n' );
 
 
-			} // Convert an image into a png format for saving
-
+			}
 
 
+			// Convert an image into a png format for saving
 			function base64ToBuffer( str ) {
 			function base64ToBuffer( str ) {
 
 
 				const b = atob( str );
 				const b = atob( str );
 				const buf = new Uint8Array( b.length );
 				const buf = new Uint8Array( b.length );
-
 				for ( let i = 0, l = buf.length; i < l; i ++ ) {
 				for ( let i = 0, l = buf.length; i < l; i ++ ) {
 
 
 					buf[ i ] = b.charCodeAt( i );
 					buf[ i ] = b.charCodeAt( i );
@@ -110,25 +104,25 @@
 			}
 			}
 
 
 			let canvas, ctx;
 			let canvas, ctx;
-
 			function imageToData( image, ext ) {
 			function imageToData( image, ext ) {
 
 
 				canvas = canvas || document.createElement( 'canvas' );
 				canvas = canvas || document.createElement( 'canvas' );
 				ctx = ctx || canvas.getContext( '2d' );
 				ctx = ctx || canvas.getContext( '2d' );
 				canvas.width = image.width;
 				canvas.width = image.width;
 				canvas.height = image.height;
 				canvas.height = image.height;
-				ctx.drawImage( image, 0, 0 ); // Get the base64 encoded data
+				ctx.drawImage( image, 0, 0 );
 
 
-				const base64data = canvas.toDataURL( `image/${ext}`, 1 ).replace( /^data:image\/(png|jpg);base64,/, '' ); // Convert to a uint8 array
+				// Get the base64 encoded data
+				const base64data = canvas.toDataURL( `image/${ext}`, 1 ).replace( /^data:image\/(png|jpg);base64,/, '' );
 
 
+				// Convert to a uint8 array
 				return base64ToBuffer( base64data );
 				return base64ToBuffer( base64data );
 
 
-			} // gets the attribute array. Generate a new array if the attribute is interleaved
-
+			}
 
 
+			// gets the attribute array. Generate a new array if the attribute is interleaved
 			const getFuncs = [ 'getX', 'getY', 'getZ', 'getW' ];
 			const getFuncs = [ 'getX', 'getY', 'getZ', 'getW' ];
 			const tempColor = new THREE.Color();
 			const tempColor = new THREE.Color();
-
 			function attrBufferToArray( attr, isColor = false ) {
 			function attrBufferToArray( attr, isColor = false ) {
 
 
 				if ( isColor ) {
 				if ( isColor ) {
@@ -136,7 +130,6 @@
 					// convert the colors to srgb before export
 					// convert the colors to srgb before export
 					// colors are always written as floats
 					// colors are always written as floats
 					const arr = new Float32Array( attr.count * 3 );
 					const arr = new Float32Array( attr.count * 3 );
-
 					for ( let i = 0, l = attr.count; i < l; i ++ ) {
 					for ( let i = 0, l = attr.count; i < l; i ++ ) {
 
 
 						tempColor.fromBufferAttribute( attr, i ).convertLinearToSRGB();
 						tempColor.fromBufferAttribute( attr, i ).convertLinearToSRGB();
@@ -153,7 +146,6 @@
 					// use the typed array constructor to save on memory
 					// use the typed array constructor to save on memory
 					const arr = new attr.array.constructor( attr.count * attr.itemSize );
 					const arr = new attr.array.constructor( attr.count * attr.itemSize );
 					const size = attr.itemSize;
 					const size = attr.itemSize;
-
 					for ( let i = 0, l = attr.count; i < l; i ++ ) {
 					for ( let i = 0, l = attr.count; i < l; i ++ ) {
 
 
 						for ( let j = 0; j < size; j ++ ) {
 						for ( let j = 0; j < size; j ++ ) {
@@ -172,28 +164,27 @@
 
 
 				}
 				}
 
 
-			} // Returns an array of the same type starting at the `st` index,
-			// and `ct` length
-
+			}
 
 
+			// Returns an array of the same type starting at the `st` index,
+			// and `ct` length
 			function subArray( arr, st, ct ) {
 			function subArray( arr, st, ct ) {
 
 
 				if ( Array.isArray( arr ) ) return arr.slice( st, st + ct ); else return new arr.constructor( arr.buffer, st * arr.BYTES_PER_ELEMENT, ct );
 				if ( Array.isArray( arr ) ) return arr.slice( st, st + ct ); else return new arr.constructor( arr.buffer, st * arr.BYTES_PER_ELEMENT, ct );
 
 
-			} // Returns the string for a geometry's attribute
-
+			}
 
 
+			// Returns the string for a geometry's attribute
 			function getAttribute( attr, name, params, type, isColor = false ) {
 			function getAttribute( attr, name, params, type, isColor = false ) {
 
 
 				const array = attrBufferToArray( attr, isColor );
 				const array = attrBufferToArray( attr, isColor );
 				const res = `<source id="${name}">` + `<float_array id="${name}-array" count="${array.length}">` + array.join( ' ' ) + '</float_array>' + '<technique_common>' + `<accessor source="#${name}-array" count="${Math.floor( array.length / attr.itemSize )}" stride="${attr.itemSize}">` + params.map( n => `<param name="${n}" type="${type}" />` ).join( '' ) + '</accessor>' + '</technique_common>' + '</source>';
 				const res = `<source id="${name}">` + `<float_array id="${name}-array" count="${array.length}">` + array.join( ' ' ) + '</float_array>' + '<technique_common>' + `<accessor source="#${name}-array" count="${Math.floor( array.length / attr.itemSize )}" stride="${attr.itemSize}">` + params.map( n => `<param name="${n}" type="${type}" />` ).join( '' ) + '</accessor>' + '</technique_common>' + '</source>';
 				return res;
 				return res;
 
 
-			} // Returns the string for a node's transform information
-
+			}
 
 
+			// Returns the string for a node's transform information
 			let transMat;
 			let transMat;
-
 			function getTransform( o ) {
 			function getTransform( o ) {
 
 
 				// ensure the object's matrix is up to date
 				// ensure the object's matrix is up to date
@@ -204,14 +195,13 @@
 				transMat.transpose();
 				transMat.transpose();
 				return `<matrix>${transMat.toArray().join( ' ' )}</matrix>`;
 				return `<matrix>${transMat.toArray().join( ' ' )}</matrix>`;
 
 
-			} // Process the given piece of geometry into the geometry library
-			// Returns the mesh id
-
+			}
 
 
+			// Process the given piece of geometry into the geometry library
+			// Returns the mesh id
 			function processGeometry( bufferGeometry ) {
 			function processGeometry( bufferGeometry ) {
 
 
 				let info = geometryInfo.get( bufferGeometry );
 				let info = geometryInfo.get( bufferGeometry );
-
 				if ( ! info ) {
 				if ( ! info ) {
 
 
 					const meshid = `Mesh${libraryGeometries.length + 1}`;
 					const meshid = `Mesh${libraryGeometries.length + 1}`;
@@ -222,46 +212,48 @@
 						materialIndex: 0
 						materialIndex: 0
 					} ];
 					} ];
 					const gname = bufferGeometry.name ? ` name="${bufferGeometry.name}"` : '';
 					const gname = bufferGeometry.name ? ` name="${bufferGeometry.name}"` : '';
-					let gnode = `<geometry id="${meshid}"${gname}><mesh>`; // define the geometry node and the vertices for the geometry
+					let gnode = `<geometry id="${meshid}"${gname}><mesh>`;
 
 
+					// define the geometry node and the vertices for the geometry
 					const posName = `${meshid}-position`;
 					const posName = `${meshid}-position`;
 					const vertName = `${meshid}-vertices`;
 					const vertName = `${meshid}-vertices`;
 					gnode += getAttribute( bufferGeometry.attributes.position, posName, [ 'X', 'Y', 'Z' ], 'float' );
 					gnode += getAttribute( bufferGeometry.attributes.position, posName, [ 'X', 'Y', 'Z' ], 'float' );
-					gnode += `<vertices id="${vertName}"><input semantic="POSITION" source="#${posName}" /></vertices>`; // NOTE: We're not optimizing the attribute arrays here, so they're all the same length and
+					gnode += `<vertices id="${vertName}"><input semantic="POSITION" source="#${posName}" /></vertices>`;
+
+					// NOTE: We're not optimizing the attribute arrays here, so they're all the same length and
 					// can therefore share the same triangle indices. However, MeshLab seems to have trouble opening
 					// can therefore share the same triangle indices. However, MeshLab seems to have trouble opening
 					// models with attributes that share an offset.
 					// models with attributes that share an offset.
 					// MeshLab Bug#424: https://sourceforge.net/p/meshlab/bugs/424/
 					// MeshLab Bug#424: https://sourceforge.net/p/meshlab/bugs/424/
-					// serialize normals
 
 
+					// serialize normals
 					let triangleInputs = `<input semantic="VERTEX" source="#${vertName}" offset="0" />`;
 					let triangleInputs = `<input semantic="VERTEX" source="#${vertName}" offset="0" />`;
-
 					if ( 'normal' in bufferGeometry.attributes ) {
 					if ( 'normal' in bufferGeometry.attributes ) {
 
 
 						const normName = `${meshid}-normal`;
 						const normName = `${meshid}-normal`;
 						gnode += getAttribute( bufferGeometry.attributes.normal, normName, [ 'X', 'Y', 'Z' ], 'float' );
 						gnode += getAttribute( bufferGeometry.attributes.normal, normName, [ 'X', 'Y', 'Z' ], 'float' );
 						triangleInputs += `<input semantic="NORMAL" source="#${normName}" offset="0" />`;
 						triangleInputs += `<input semantic="NORMAL" source="#${normName}" offset="0" />`;
 
 
-					} // serialize uvs
-
+					}
 
 
+					// serialize uvs
 					if ( 'uv' in bufferGeometry.attributes ) {
 					if ( 'uv' in bufferGeometry.attributes ) {
 
 
 						const uvName = `${meshid}-texcoord`;
 						const uvName = `${meshid}-texcoord`;
 						gnode += getAttribute( bufferGeometry.attributes.uv, uvName, [ 'S', 'T' ], 'float' );
 						gnode += getAttribute( bufferGeometry.attributes.uv, uvName, [ 'S', 'T' ], 'float' );
 						triangleInputs += `<input semantic="TEXCOORD" source="#${uvName}" offset="0" set="0" />`;
 						triangleInputs += `<input semantic="TEXCOORD" source="#${uvName}" offset="0" set="0" />`;
 
 
-					} // serialize lightmap uvs
-
+					}
 
 
+					// serialize lightmap uvs
 					if ( 'uv2' in bufferGeometry.attributes ) {
 					if ( 'uv2' in bufferGeometry.attributes ) {
 
 
 						const uvName = `${meshid}-texcoord2`;
 						const uvName = `${meshid}-texcoord2`;
 						gnode += getAttribute( bufferGeometry.attributes.uv2, uvName, [ 'S', 'T' ], 'float' );
 						gnode += getAttribute( bufferGeometry.attributes.uv2, uvName, [ 'S', 'T' ], 'float' );
 						triangleInputs += `<input semantic="TEXCOORD" source="#${uvName}" offset="0" set="1" />`;
 						triangleInputs += `<input semantic="TEXCOORD" source="#${uvName}" offset="0" set="1" />`;
 
 
-					} // serialize colors
-
+					}
 
 
+					// serialize colors
 					if ( 'color' in bufferGeometry.attributes ) {
 					if ( 'color' in bufferGeometry.attributes ) {
 
 
 						// colors are always written as floats
 						// colors are always written as floats
@@ -272,7 +264,6 @@
 					}
 					}
 
 
 					let indexArray = null;
 					let indexArray = null;
-
 					if ( bufferGeometry.index ) {
 					if ( bufferGeometry.index ) {
 
 
 						indexArray = attrBufferToArray( bufferGeometry.index );
 						indexArray = attrBufferToArray( bufferGeometry.index );
@@ -280,7 +271,6 @@
 					} else {
 					} else {
 
 
 						indexArray = new Array( indexCount );
 						indexArray = new Array( indexCount );
-
 						for ( let i = 0, l = indexArray.length; i < l; i ++ ) indexArray[ i ] = i;
 						for ( let i = 0, l = indexArray.length; i < l; i ++ ) indexArray[ i ] = i;
 
 
 					}
 					}
@@ -309,21 +299,19 @@
 
 
 				return info;
 				return info;
 
 
-			} // Process the given texture into the image library
-			// Returns the image library
-
+			}
 
 
+			// Process the given texture into the image library
+			// Returns the image library
 			function processTexture( tex ) {
 			function processTexture( tex ) {
 
 
 				let texid = imageMap.get( tex );
 				let texid = imageMap.get( tex );
-
 				if ( texid == null ) {
 				if ( texid == null ) {
 
 
 					texid = `image-${libraryImages.length + 1}`;
 					texid = `image-${libraryImages.length + 1}`;
 					const ext = 'png';
 					const ext = 'png';
 					const name = tex.name || texid;
 					const name = tex.name || texid;
 					let imageNode = `<image id="${texid}" name="${name}">`;
 					let imageNode = `<image id="${texid}" name="${name}">`;
-
 					if ( version === '1.5.0' ) {
 					if ( version === '1.5.0' ) {
 
 
 						imageNode += `<init_from><ref>${options.textureDirectory}${name}.${ext}</ref></init_from>`;
 						imageNode += `<init_from><ref>${options.textureDirectory}${name}.${ext}</ref></init_from>`;
@@ -350,19 +338,17 @@
 
 
 				return texid;
 				return texid;
 
 
-			} // Process the given material into the material and effect libraries
-			// Returns the material id
-
+			}
 
 
+			// Process the given material into the material and effect libraries
+			// Returns the material id
 			function processMaterial( m ) {
 			function processMaterial( m ) {
 
 
 				let matid = materialMap.get( m );
 				let matid = materialMap.get( m );
-
 				if ( matid == null ) {
 				if ( matid == null ) {
 
 
 					matid = `Mat${libraryEffects.length + 1}`;
 					matid = `Mat${libraryEffects.length + 1}`;
 					let type = 'phong';
 					let type = 'phong';
-
 					if ( m.isMeshLambertMaterial === true ) {
 					if ( m.isMeshLambertMaterial === true ) {
 
 
 						type = 'lambert';
 						type = 'lambert';
@@ -370,7 +356,6 @@
 					} else if ( m.isMeshBasicMaterial === true ) {
 					} else if ( m.isMeshBasicMaterial === true ) {
 
 
 						type = 'constant';
 						type = 'constant';
-
 						if ( m.map !== null ) {
 						if ( m.map !== null ) {
 
 
 							// The Collada spec does not support diffuse texture maps with the
 							// The Collada spec does not support diffuse texture maps with the
@@ -389,16 +374,15 @@
 					const reflectivity = m.reflectivity || 0;
 					const reflectivity = m.reflectivity || 0;
 					emissive.convertLinearToSRGB();
 					emissive.convertLinearToSRGB();
 					specular.convertLinearToSRGB();
 					specular.convertLinearToSRGB();
-					diffuse.convertLinearToSRGB(); // Do not export and alpha map for the reasons mentioned in issue (#13792)
+					diffuse.convertLinearToSRGB();
+
+					// Do not export and alpha map for the reasons mentioned in issue (#13792)
 					// in three.js alpha maps are black and white, but collada expects the alpha
 					// in three.js alpha maps are black and white, but collada expects the alpha
 					// channel to specify the transparency
 					// channel to specify the transparency
-
 					let transparencyNode = '';
 					let transparencyNode = '';
-
 					if ( m.transparent === true ) {
 					if ( m.transparent === true ) {
 
 
 						transparencyNode += '<transparent>' + ( m.map ? '<texture texture="diffuse-sampler"></texture>' : '<float>1</float>' ) + '</transparent>';
 						transparencyNode += '<transparent>' + ( m.map ? '<texture texture="diffuse-sampler"></texture>' : '<float>1</float>' ) + '</transparent>';
-
 						if ( m.opacity < 1 ) {
 						if ( m.opacity < 1 ) {
 
 
 							transparencyNode += `<transparency><float>${m.opacity}</float></transparency>`;
 							transparencyNode += `<transparency><float>${m.opacity}</float></transparency>`;
@@ -419,30 +403,30 @@
 
 
 				return matid;
 				return matid;
 
 
-			} // Recursively process the object into a scene
-
+			}
 
 
+			// Recursively process the object into a scene
 			function processObject( o ) {
 			function processObject( o ) {
 
 
 				let node = `<node name="${o.name}">`;
 				let node = `<node name="${o.name}">`;
 				node += getTransform( o );
 				node += getTransform( o );
-
 				if ( o.isMesh === true && o.geometry !== null ) {
 				if ( o.isMesh === true && o.geometry !== null ) {
 
 
 					// function returns the id associated with the mesh and a "BufferGeometry" version
 					// function returns the id associated with the mesh and a "BufferGeometry" version
 					// of the geometry in case it's not a geometry.
 					// of the geometry in case it's not a geometry.
 					const geomInfo = processGeometry( o.geometry );
 					const geomInfo = processGeometry( o.geometry );
 					const meshid = geomInfo.meshid;
 					const meshid = geomInfo.meshid;
-					const geometry = geomInfo.bufferGeometry; // ids of the materials to bind to the geometry
+					const geometry = geomInfo.bufferGeometry;
 
 
+					// ids of the materials to bind to the geometry
 					let matids = null;
 					let matids = null;
-					let matidsArray; // get a list of materials to bind to the sub groups of the geometry.
+					let matidsArray;
+
+					// get a list of materials to bind to the sub groups of the geometry.
 					// If the amount of subgroups is greater than the materials, than reuse
 					// If the amount of subgroups is greater than the materials, than reuse
 					// the materials.
 					// the materials.
-
 					const mat = o.material || new THREE.MeshBasicMaterial();
 					const mat = o.material || new THREE.MeshBasicMaterial();
 					const materials = Array.isArray( mat ) ? mat : [ mat ];
 					const materials = Array.isArray( mat ) ? mat : [ mat ];
-
 					if ( geometry.groups.length > materials.length ) {
 					if ( geometry.groups.length > materials.length ) {
 
 
 						matidsArray = new Array( geometry.groups.length );
 						matidsArray = new Array( geometry.groups.length );
@@ -486,7 +470,6 @@
 				data: format( dae ),
 				data: format( dae ),
 				textures
 				textures
 			};
 			};
-
 			if ( typeof onDone === 'function' ) {
 			if ( typeof onDone === 'function' ) {
 
 
 				requestAnimationFrame( () => onDone( res ) );
 				requestAnimationFrame( () => onDone( res ) );

+ 22 - 22
examples/js/exporters/DRACOExporter.js

@@ -15,6 +15,7 @@
  */
  */
 
 
 	/* global DracoEncoderModule */
 	/* global DracoEncoderModule */
+
 	class DRACOExporter {
 	class DRACOExporter {
 
 
 		parse( object, options = {
 		parse( object, options = {
@@ -38,7 +39,6 @@
 			const encoder = new dracoEncoder.Encoder();
 			const encoder = new dracoEncoder.Encoder();
 			let builder;
 			let builder;
 			let dracoObject;
 			let dracoObject;
-
 			if ( object.isMesh === true ) {
 			if ( object.isMesh === true ) {
 
 
 				builder = new dracoEncoder.MeshBuilder();
 				builder = new dracoEncoder.MeshBuilder();
@@ -46,7 +46,6 @@
 				const vertices = geometry.getAttribute( 'position' );
 				const vertices = geometry.getAttribute( 'position' );
 				builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
 				builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
 				const faces = geometry.getIndex();
 				const faces = geometry.getIndex();
-
 				if ( faces !== null ) {
 				if ( faces !== null ) {
 
 
 					builder.AddFacesToMesh( dracoObject, faces.count / 3, faces.array );
 					builder.AddFacesToMesh( dracoObject, faces.count / 3, faces.array );
@@ -54,7 +53,6 @@
 				} else {
 				} else {
 
 
 					const faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );
 					const faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );
-
 					for ( let i = 0; i < faces.length; i ++ ) {
 					for ( let i = 0; i < faces.length; i ++ ) {
 
 
 						faces[ i ] = i;
 						faces[ i ] = i;
@@ -68,7 +66,6 @@
 				if ( options.exportNormals === true ) {
 				if ( options.exportNormals === true ) {
 
 
 					const normals = geometry.getAttribute( 'normal' );
 					const normals = geometry.getAttribute( 'normal' );
-
 					if ( normals !== undefined ) {
 					if ( normals !== undefined ) {
 
 
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );
@@ -80,7 +77,6 @@
 				if ( options.exportUvs === true ) {
 				if ( options.exportUvs === true ) {
 
 
 					const uvs = geometry.getAttribute( 'uv' );
 					const uvs = geometry.getAttribute( 'uv' );
-
 					if ( uvs !== undefined ) {
 					if ( uvs !== undefined ) {
 
 
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array );
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array );
@@ -92,7 +88,6 @@
 				if ( options.exportColor === true ) {
 				if ( options.exportColor === true ) {
 
 
 					const colors = geometry.getAttribute( 'color' );
 					const colors = geometry.getAttribute( 'color' );
-
 					if ( colors !== undefined ) {
 					if ( colors !== undefined ) {
 
 
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );
@@ -107,11 +102,9 @@
 				dracoObject = new dracoEncoder.PointCloud();
 				dracoObject = new dracoEncoder.PointCloud();
 				const vertices = geometry.getAttribute( 'position' );
 				const vertices = geometry.getAttribute( 'position' );
 				builder.AddFloatAttribute( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
 				builder.AddFloatAttribute( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
-
 				if ( options.exportColor === true ) {
 				if ( options.exportColor === true ) {
 
 
 					const colors = geometry.getAttribute( 'color' );
 					const colors = geometry.getAttribute( 'color' );
-
 					if ( colors !== undefined ) {
 					if ( colors !== undefined ) {
 
 
 						builder.AddFloatAttribute( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );
 						builder.AddFloatAttribute( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );
@@ -124,23 +117,28 @@
 
 
 				throw new Error( 'DRACOExporter: Unsupported object type.' );
 				throw new Error( 'DRACOExporter: Unsupported object type.' );
 
 
-			} //Compress using draco encoder
+			}
+
+			//Compress using draco encoder
 
 
+			const encodedData = new dracoEncoder.DracoInt8Array();
 
 
-			const encodedData = new dracoEncoder.DracoInt8Array(); //Sets the desired encoding and decoding speed for the given options from 0 (slowest speed, but the best compression) to 10 (fastest, but the worst compression).
+			//Sets the desired encoding and decoding speed for the given options from 0 (slowest speed, but the best compression) to 10 (fastest, but the worst compression).
 
 
 			const encodeSpeed = options.encodeSpeed !== undefined ? options.encodeSpeed : 5;
 			const encodeSpeed = options.encodeSpeed !== undefined ? options.encodeSpeed : 5;
 			const decodeSpeed = options.decodeSpeed !== undefined ? options.decodeSpeed : 5;
 			const decodeSpeed = options.decodeSpeed !== undefined ? options.decodeSpeed : 5;
-			encoder.SetSpeedOptions( encodeSpeed, decodeSpeed ); // Sets the desired encoding method for a given geometry.
+			encoder.SetSpeedOptions( encodeSpeed, decodeSpeed );
+
+			// Sets the desired encoding method for a given geometry.
 
 
 			if ( options.encoderMethod !== undefined ) {
 			if ( options.encoderMethod !== undefined ) {
 
 
 				encoder.SetEncodingMethod( options.encoderMethod );
 				encoder.SetEncodingMethod( options.encoderMethod );
 
 
-			} // Sets the quantization (number of bits used to represent) compression options for a named attribute.
-			// The attribute values will be quantized in a box defined by the maximum extent of the attribute values.
-
+			}
 
 
+			// Sets the quantization (number of bits used to represent) compression options for a named attribute.
+			// The attribute values will be quantized in a box defined by the maximum extent of the attribute values.
 			if ( options.quantization !== undefined ) {
 			if ( options.quantization !== undefined ) {
 
 
 				for ( let i = 0; i < 5; i ++ ) {
 				for ( let i = 0; i < 5; i ++ ) {
@@ -156,7 +154,6 @@
 			}
 			}
 
 
 			let length;
 			let length;
-
 			if ( object.isMesh === true ) {
 			if ( object.isMesh === true ) {
 
 
 				length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData );
 				length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData );
@@ -168,16 +165,14 @@
 			}
 			}
 
 
 			dracoEncoder.destroy( dracoObject );
 			dracoEncoder.destroy( dracoObject );
-
 			if ( length === 0 ) {
 			if ( length === 0 ) {
 
 
 				throw new Error( 'THREE.DRACOExporter: Draco encoding failed.' );
 				throw new Error( 'THREE.DRACOExporter: Draco encoding failed.' );
 
 
-			} //Copy encoded data to buffer.
-
+			}
 
 
+			//Copy encoded data to buffer.
 			const outputData = new Int8Array( new ArrayBuffer( length ) );
 			const outputData = new Int8Array( new ArrayBuffer( length ) );
-
 			for ( let i = 0; i < length; i ++ ) {
 			for ( let i = 0; i < length; i ++ ) {
 
 
 				outputData[ i ] = encodedData.GetValue( i );
 				outputData[ i ] = encodedData.GetValue( i );
@@ -191,14 +186,19 @@
 
 
 		}
 		}
 
 
-	} // Encoder methods
+	}
 
 
+	// Encoder methods
 
 
 	DRACOExporter.MESH_EDGEBREAKER_ENCODING = 1;
 	DRACOExporter.MESH_EDGEBREAKER_ENCODING = 1;
-	DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0; // Geometry type
+	DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0;
+
+	// Geometry type
 
 
 	DRACOExporter.POINT_CLOUD = 0;
 	DRACOExporter.POINT_CLOUD = 0;
-	DRACOExporter.TRIANGULAR_MESH = 1; // Attribute type
+	DRACOExporter.TRIANGULAR_MESH = 1;
+
+	// Attribute type
 
 
 	DRACOExporter.INVALID = - 1;
 	DRACOExporter.INVALID = - 1;
 	DRACOExporter.POSITION = 0;
 	DRACOExporter.POSITION = 0;

+ 15 - 18
examples/js/exporters/EXRExporter.js

@@ -10,7 +10,6 @@
 	const NO_COMPRESSION = 0;
 	const NO_COMPRESSION = 0;
 	const ZIPS_COMPRESSION = 2;
 	const ZIPS_COMPRESSION = 2;
 	const ZIP_COMPRESSION = 3;
 	const ZIP_COMPRESSION = 3;
-
 	class EXRExporter {
 	class EXRExporter {
 
 
 		parse( renderer, renderTarget, options ) {
 		parse( renderer, renderTarget, options ) {
@@ -25,7 +24,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function supported( renderer, renderTarget ) {
 	function supported( renderer, renderTarget ) {
 
 
 		if ( ! renderer || ! renderer.isWebGLRenderer ) {
 		if ( ! renderer || ! renderer.isWebGLRenderer ) {
@@ -97,7 +95,6 @@
 	function getPixelData( renderer, rtt, info ) {
 	function getPixelData( renderer, rtt, info ) {
 
 
 		let dataBuffer;
 		let dataBuffer;
-
 		if ( info.type === THREE.FloatType ) {
 		if ( info.type === THREE.FloatType ) {
 
 
 			dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels );
 			dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels );
@@ -131,7 +128,6 @@
 			setValue = info.dataType == 1 ? setFloat16 : setFloat32,
 			setValue = info.dataType == 1 ? setFloat16 : setFloat32,
 			outBuffer = new Uint8Array( info.width * info.height * info.numOutputChannels * info.dataSize ),
 			outBuffer = new Uint8Array( info.width * info.height * info.numOutputChannels * info.dataSize ),
 			dv = new DataView( outBuffer.buffer );
 			dv = new DataView( outBuffer.buffer );
-
 		for ( let y = 0; y < h; ++ y ) {
 		for ( let y = 0; y < h; ++ y ) {
 
 
 			for ( let x = 0; x < w; ++ x ) {
 			for ( let x = 0; x < w; ++ x ) {
@@ -170,13 +166,11 @@
 				totalSize: 0
 				totalSize: 0
 			},
 			},
 			size = info.width * info.numOutputChannels * info.blockLines * info.dataSize;
 			size = info.width * info.numOutputChannels * info.blockLines * info.dataSize;
-
 		switch ( info.compression ) {
 		switch ( info.compression ) {
 
 
 			case 0:
 			case 0:
 				compress = compressNONE;
 				compress = compressNONE;
 				break;
 				break;
-
 			case 2:
 			case 2:
 			case 3:
 			case 3:
 				compress = compressZIP;
 				compress = compressZIP;
@@ -218,11 +212,11 @@
 		//
 		//
 		// Reorder the pixel data.
 		// Reorder the pixel data.
 		//
 		//
+
 		let t1 = 0,
 		let t1 = 0,
 			t2 = Math.floor( ( data.length + 1 ) / 2 ),
 			t2 = Math.floor( ( data.length + 1 ) / 2 ),
 			s = 0;
 			s = 0;
 		const stop = data.length - 1;
 		const stop = data.length - 1;
-
 		while ( true ) {
 		while ( true ) {
 
 
 			if ( s > stop ) break;
 			if ( s > stop ) break;
@@ -230,13 +224,13 @@
 			if ( s > stop ) break;
 			if ( s > stop ) break;
 			tmpBuffer[ t2 ++ ] = data[ s ++ ];
 			tmpBuffer[ t2 ++ ] = data[ s ++ ];
 
 
-		} //
+		}
+
+		//
 		// Predictor.
 		// Predictor.
 		//
 		//
 
 
-
 		let p = tmpBuffer[ 0 ];
 		let p = tmpBuffer[ 0 ];
-
 		for ( let t = 1; t < tmpBuffer.length; t ++ ) {
 		for ( let t = 1; t < tmpBuffer.length; t ++ ) {
 
 
 			const d = tmpBuffer[ t ] - p + ( 128 + 256 );
 			const d = tmpBuffer[ t ] - p + ( 128 + 256 );
@@ -264,8 +258,8 @@
 		};
 		};
 		const dv = new DataView( outBuffer.buffer );
 		const dv = new DataView( outBuffer.buffer );
 		setUint32( dv, 20000630, offset ); // magic
 		setUint32( dv, 20000630, offset ); // magic
-
 		setUint32( dv, 2, offset ); // mask
 		setUint32( dv, 2, offset ); // mask
+
 		// = HEADER =
 		// = HEADER =
 
 
 		setString( dv, 'compression', offset );
 		setString( dv, 'compression', offset );
@@ -326,12 +320,14 @@
 		offset.value += 4;
 		offset.value += 4;
 		setUint32( dv, 1, offset );
 		setUint32( dv, 1, offset );
 		setUint32( dv, 1, offset );
 		setUint32( dv, 1, offset );
-		setUint8( dv, 0, offset ); // null-byte
+		setUint8( dv, 0, offset );
 
 
-		setUint8( dv, 0, offset ); // = OFFSET TABLE =
+		// null-byte
+		setUint8( dv, 0, offset );
 
 
-		let sum = offset.value + info.numBlocks * 8;
+		// = OFFSET TABLE =
 
 
+		let sum = offset.value + info.numBlocks * 8;
 		for ( let i = 0; i < chunks.data.length; ++ i ) {
 		for ( let i = 0; i < chunks.data.length; ++ i ) {
 
 
 			setUint64( dv, sum, offset );
 			setUint64( dv, sum, offset );
@@ -352,7 +348,6 @@
 			outBuffer = new Uint8Array( HeaderSize + TableSize + chunks.totalSize + info.numBlocks * 8 ),
 			outBuffer = new Uint8Array( HeaderSize + TableSize + chunks.totalSize + info.numBlocks * 8 ),
 			dv = new DataView( outBuffer.buffer );
 			dv = new DataView( outBuffer.buffer );
 		fillHeader( outBuffer, chunks, info );
 		fillHeader( outBuffer, chunks, info );
-
 		for ( let i = 0; i < chunks.data.length; ++ i ) {
 		for ( let i = 0; i < chunks.data.length; ++ i ) {
 
 
 			const data = chunks.data[ i ].dataChunk;
 			const data = chunks.data[ i ].dataChunk;
@@ -375,13 +370,16 @@
 		dec.b = b;
 		dec.b = b;
 		dec.a = a;
 		dec.a = a;
 
 
-	} // function decodeSRGB( dec, r, g, b, a ) {
+	}
+
+	// function decodeSRGB( dec, r, g, b, a ) {
+
 	// 	dec.r = r > 0.04045 ? Math.pow( r * 0.9478672986 + 0.0521327014, 2.4 ) : r * 0.0773993808;
 	// 	dec.r = r > 0.04045 ? Math.pow( r * 0.9478672986 + 0.0521327014, 2.4 ) : r * 0.0773993808;
 	// 	dec.g = g > 0.04045 ? Math.pow( g * 0.9478672986 + 0.0521327014, 2.4 ) : g * 0.0773993808;
 	// 	dec.g = g > 0.04045 ? Math.pow( g * 0.9478672986 + 0.0521327014, 2.4 ) : g * 0.0773993808;
 	// 	dec.b = b > 0.04045 ? Math.pow( b * 0.9478672986 + 0.0521327014, 2.4 ) : b * 0.0773993808;
 	// 	dec.b = b > 0.04045 ? Math.pow( b * 0.9478672986 + 0.0521327014, 2.4 ) : b * 0.0773993808;
 	// 	dec.a = a;
 	// 	dec.a = a;
-	// }
 
 
+	// }
 
 
 	function setUint8( dv, value, offset ) {
 	function setUint8( dv, value, offset ) {
 
 
@@ -421,7 +419,6 @@
 	function setString( dv, string, offset ) {
 	function setString( dv, string, offset ) {
 
 
 		const tmp = textEncoder.encode( string + '\0' );
 		const tmp = textEncoder.encode( string + '\0' );
-
 		for ( let i = 0; i < tmp.length; ++ i ) {
 		for ( let i = 0; i < tmp.length; ++ i ) {
 
 
 			setUint8( dv, tmp[ i ], offset );
 			setUint8( dv, tmp[ i ], offset );

文件差異過大導致無法顯示
+ 100 - 143
examples/js/exporters/GLTFExporter.js


+ 5 - 12
examples/js/exporters/MMDExporter.js

@@ -42,7 +42,6 @@
 
 
 				if ( Math.abs( num ) < 1e-6 ) num = 0;
 				if ( Math.abs( num ) < 1e-6 ) num = 0;
 				let a = num.toString();
 				let a = num.toString();
-
 				if ( a.indexOf( '.' ) === - 1 ) {
 				if ( a.indexOf( '.' ) === - 1 ) {
 
 
 					a += '.';
 					a += '.';
@@ -60,7 +59,6 @@
 			function toStringsFromArray( array ) {
 			function toStringsFromArray( array ) {
 
 
 				const a = [];
 				const a = [];
-
 				for ( let i = 0, il = array.length; i < il; i ++ ) {
 				for ( let i = 0, il = array.length; i < il; i ++ ) {
 
 
 					a.push( toStringsFromNumber( array[ i ] ) );
 					a.push( toStringsFromNumber( array[ i ] ) );
@@ -84,16 +82,15 @@
 			array.push( ( skin.name !== '' ? skin.name.replace( /\s/g, '_' ) : 'skin' ) + '.osm;' );
 			array.push( ( skin.name !== '' ? skin.name.replace( /\s/g, '_' ) : 'skin' ) + '.osm;' );
 			array.push( bones.length + ';' );
 			array.push( bones.length + ';' );
 			array.push( '' );
 			array.push( '' );
-
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
 
 				const bone = bones[ i ];
 				const bone = bones[ i ];
 				const bone2 = bones2[ i ];
 				const bone2 = bones2[ i ];
+
 				/*
 				/*
        * use the bone matrix saved before solving IK.
        * use the bone matrix saved before solving IK.
        * see CCDIKSolver for the detail.
        * see CCDIKSolver for the detail.
        */
        */
-
 				if ( useOriginalBones === true && bone.userData.ik !== undefined && bone.userData.ik.originalMatrix !== undefined ) {
 				if ( useOriginalBones === true && bone.userData.ik !== undefined && bone.userData.ik.originalMatrix !== undefined ) {
 
 
 					matrix.fromArray( bone.userData.ik.originalMatrix );
 					matrix.fromArray( bone.userData.ik.originalMatrix );
@@ -107,8 +104,9 @@
 				position.setFromMatrixPosition( matrix );
 				position.setFromMatrixPosition( matrix );
 				quaternion.setFromRotationMatrix( matrix );
 				quaternion.setFromRotationMatrix( matrix );
 				const pArray = position.sub( bone2.position ).toArray();
 				const pArray = position.sub( bone2.position ).toArray();
-				const qArray = quaternion2.copy( bone2.quaternion ).conjugate().multiply( quaternion ).toArray(); // right to left
+				const qArray = quaternion2.copy( bone2.quaternion ).conjugate().multiply( quaternion ).toArray();
 
 
+				// right to left
 				pArray[ 2 ] = - pArray[ 2 ];
 				pArray[ 2 ] = - pArray[ 2 ];
 				qArray[ 0 ] = - qArray[ 0 ];
 				qArray[ 0 ] = - qArray[ 0 ];
 				qArray[ 1 ] = - qArray[ 1 ];
 				qArray[ 1 ] = - qArray[ 1 ];
@@ -126,21 +124,18 @@
 
 
 		}
 		}
 
 
-	} // Unicode to Shift_JIS table
-
+	}
 
 
+	// Unicode to Shift_JIS table
 	let u2sTable;
 	let u2sTable;
-
 	function unicodeToShiftjis( str ) {
 	function unicodeToShiftjis( str ) {
 
 
 		if ( u2sTable === undefined ) {
 		if ( u2sTable === undefined ) {
 
 
 			const encoder = new MMDParser.CharsetEncoder(); // eslint-disable-line no-undef
 			const encoder = new MMDParser.CharsetEncoder(); // eslint-disable-line no-undef
-
 			const table = encoder.s2uTable;
 			const table = encoder.s2uTable;
 			u2sTable = {};
 			u2sTable = {};
 			const keys = Object.keys( table );
 			const keys = Object.keys( table );
-
 			for ( let i = 0, il = keys.length; i < il; i ++ ) {
 			for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 
 				let key = keys[ i ];
 				let key = keys[ i ];
@@ -153,12 +148,10 @@
 		}
 		}
 
 
 		const array = [];
 		const array = [];
-
 		for ( let i = 0, il = str.length; i < il; i ++ ) {
 		for ( let i = 0, il = str.length; i < il; i ++ ) {
 
 
 			const code = str.charCodeAt( i );
 			const code = str.charCodeAt( i );
 			const value = u2sTable[ code ];
 			const value = u2sTable[ code ];
-
 			if ( value === undefined ) {
 			if ( value === undefined ) {
 
 
 				throw new Error( 'cannot convert charcode 0x' + code.toString( 16 ) );
 				throw new Error( 'cannot convert charcode 0x' + code.toString( 16 ) );

+ 42 - 33
examples/js/exporters/OBJExporter.js

@@ -13,73 +13,83 @@
 			const normal = new THREE.Vector3();
 			const normal = new THREE.Vector3();
 			const uv = new THREE.Vector2();
 			const uv = new THREE.Vector2();
 			const face = [];
 			const face = [];
-
 			function parseMesh( mesh ) {
 			function parseMesh( mesh ) {
 
 
 				let nbVertex = 0;
 				let nbVertex = 0;
 				let nbNormals = 0;
 				let nbNormals = 0;
 				let nbVertexUvs = 0;
 				let nbVertexUvs = 0;
 				const geometry = mesh.geometry;
 				const geometry = mesh.geometry;
-				const normalMatrixWorld = new THREE.Matrix3(); // shortcuts
+				const normalMatrixWorld = new THREE.Matrix3();
 
 
+				// shortcuts
 				const vertices = geometry.getAttribute( 'position' );
 				const vertices = geometry.getAttribute( 'position' );
 				const normals = geometry.getAttribute( 'normal' );
 				const normals = geometry.getAttribute( 'normal' );
 				const uvs = geometry.getAttribute( 'uv' );
 				const uvs = geometry.getAttribute( 'uv' );
-				const indices = geometry.getIndex(); // name of the mesh object
+				const indices = geometry.getIndex();
 
 
-				output += 'o ' + mesh.name + '\n'; // name of the mesh material
+				// name of the mesh object
+				output += 'o ' + mesh.name + '\n';
 
 
+				// name of the mesh material
 				if ( mesh.material && mesh.material.name ) {
 				if ( mesh.material && mesh.material.name ) {
 
 
 					output += 'usemtl ' + mesh.material.name + '\n';
 					output += 'usemtl ' + mesh.material.name + '\n';
 
 
-				} // vertices
+				}
 
 
+				// vertices
 
 
 				if ( vertices !== undefined ) {
 				if ( vertices !== undefined ) {
 
 
 					for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
 					for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
 
 
-						vertex.fromBufferAttribute( vertices, i ); // transform the vertex to world space
+						vertex.fromBufferAttribute( vertices, i );
 
 
-						vertex.applyMatrix4( mesh.matrixWorld ); // transform the vertex to export format
+						// transform the vertex to world space
+						vertex.applyMatrix4( mesh.matrixWorld );
 
 
+						// transform the vertex to export format
 						output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
 						output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
 
 
 					}
 					}
 
 
-				} // uvs
+				}
 
 
+				// uvs
 
 
 				if ( uvs !== undefined ) {
 				if ( uvs !== undefined ) {
 
 
 					for ( let i = 0, l = uvs.count; i < l; i ++, nbVertexUvs ++ ) {
 					for ( let i = 0, l = uvs.count; i < l; i ++, nbVertexUvs ++ ) {
 
 
-						uv.fromBufferAttribute( uvs, i ); // transform the uv to export format
+						uv.fromBufferAttribute( uvs, i );
 
 
+						// transform the uv to export format
 						output += 'vt ' + uv.x + ' ' + uv.y + '\n';
 						output += 'vt ' + uv.x + ' ' + uv.y + '\n';
 
 
 					}
 					}
 
 
-				} // normals
+				}
 
 
+				// normals
 
 
 				if ( normals !== undefined ) {
 				if ( normals !== undefined ) {
 
 
 					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
 					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
 					for ( let i = 0, l = normals.count; i < l; i ++, nbNormals ++ ) {
 					for ( let i = 0, l = normals.count; i < l; i ++, nbNormals ++ ) {
 
 
-						normal.fromBufferAttribute( normals, i ); // transform the normal to world space
+						normal.fromBufferAttribute( normals, i );
 
 
-						normal.applyMatrix3( normalMatrixWorld ).normalize(); // transform the normal to export format
+						// transform the normal to world space
+						normal.applyMatrix3( normalMatrixWorld ).normalize();
 
 
+						// transform the normal to export format
 						output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
 						output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
 
 
 					}
 					}
 
 
-				} // faces
+				}
 
 
+				// faces
 
 
 				if ( indices !== null ) {
 				if ( indices !== null ) {
 
 
@@ -90,9 +100,9 @@
 							const j = indices.getX( i + m ) + 1;
 							const j = indices.getX( i + m ) + 1;
 							face[ m ] = indexVertex + j + ( normals || uvs ? '/' + ( uvs ? indexVertexUvs + j : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
 							face[ m ] = indexVertex + j + ( normals || uvs ? '/' + ( uvs ? indexVertexUvs + j : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
 
 
-						} // transform the face to export format
-
+						}
 
 
+						// transform the face to export format
 						output += 'f ' + face.join( ' ' ) + '\n';
 						output += 'f ' + face.join( ' ' ) + '\n';
 
 
 					}
 					}
@@ -106,16 +116,16 @@
 							const j = i + m + 1;
 							const j = i + m + 1;
 							face[ m ] = indexVertex + j + ( normals || uvs ? '/' + ( uvs ? indexVertexUvs + j : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
 							face[ m ] = indexVertex + j + ( normals || uvs ? '/' + ( uvs ? indexVertexUvs + j : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
 
 
-						} // transform the face to export format
-
+						}
 
 
+						// transform the face to export format
 						output += 'f ' + face.join( ' ' ) + '\n';
 						output += 'f ' + face.join( ' ' ) + '\n';
 
 
 					}
 					}
 
 
-				} // update index
-
+				}
 
 
+				// update index
 				indexVertex += nbVertex;
 				indexVertex += nbVertex;
 				indexVertexUvs += nbVertexUvs;
 				indexVertexUvs += nbVertexUvs;
 				indexNormals += nbNormals;
 				indexNormals += nbNormals;
@@ -126,20 +136,23 @@
 
 
 				let nbVertex = 0;
 				let nbVertex = 0;
 				const geometry = line.geometry;
 				const geometry = line.geometry;
-				const type = line.type; // shortcuts
+				const type = line.type;
 
 
-				const vertices = geometry.getAttribute( 'position' ); // name of the line object
+				// shortcuts
+				const vertices = geometry.getAttribute( 'position' );
 
 
+				// name of the line object
 				output += 'o ' + line.name + '\n';
 				output += 'o ' + line.name + '\n';
-
 				if ( vertices !== undefined ) {
 				if ( vertices !== undefined ) {
 
 
 					for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
 					for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
 
 
-						vertex.fromBufferAttribute( vertices, i ); // transform the vertex to world space
+						vertex.fromBufferAttribute( vertices, i );
 
 
-						vertex.applyMatrix4( line.matrixWorld ); // transform the vertex to export format
+						// transform the vertex to world space
+						vertex.applyMatrix4( line.matrixWorld );
 
 
+						// transform the vertex to export format
 						output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
 						output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
 
 
 					}
 					}
@@ -149,7 +162,6 @@
 				if ( type === 'Line' ) {
 				if ( type === 'Line' ) {
 
 
 					output += 'l ';
 					output += 'l ';
-
 					for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
 					for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
 
 
 						output += indexVertex + j + ' ';
 						output += indexVertex + j + ' ';
@@ -168,9 +180,9 @@
 
 
 					}
 					}
 
 
-				} // update index
-
+				}
 
 
+				// update index
 				indexVertex += nbVertex;
 				indexVertex += nbVertex;
 
 
 			}
 			}
@@ -182,7 +194,6 @@
 				const vertices = geometry.getAttribute( 'position' );
 				const vertices = geometry.getAttribute( 'position' );
 				const colors = geometry.getAttribute( 'color' );
 				const colors = geometry.getAttribute( 'color' );
 				output += 'o ' + points.name + '\n';
 				output += 'o ' + points.name + '\n';
-
 				if ( vertices !== undefined ) {
 				if ( vertices !== undefined ) {
 
 
 					for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
 					for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
@@ -190,7 +201,6 @@
 						vertex.fromBufferAttribute( vertices, i );
 						vertex.fromBufferAttribute( vertices, i );
 						vertex.applyMatrix4( points.matrixWorld );
 						vertex.applyMatrix4( points.matrixWorld );
 						output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z;
 						output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z;
-
 						if ( colors !== undefined ) {
 						if ( colors !== undefined ) {
 
 
 							color.fromBufferAttribute( colors, i ).convertLinearToSRGB();
 							color.fromBufferAttribute( colors, i ).convertLinearToSRGB();
@@ -203,7 +213,6 @@
 					}
 					}
 
 
 					output += 'p ';
 					output += 'p ';
-
 					for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
 					for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
 
 
 						output += indexVertex + j + ' ';
 						output += indexVertex + j + ' ';
@@ -212,9 +221,9 @@
 
 
 					output += '\n';
 					output += '\n';
 
 
-				} // update index
-
+				}
 
 
+				// update index
 				indexVertex += nbVertex;
 				indexVertex += nbVertex;
 
 
 			}
 			}

+ 38 - 33
examples/js/exporters/PLYExporter.js

@@ -26,7 +26,6 @@
 
 
 						const mesh = child;
 						const mesh = child;
 						const geometry = mesh.geometry;
 						const geometry = mesh.geometry;
-
 						if ( geometry.hasAttribute( 'position' ) === true ) {
 						if ( geometry.hasAttribute( 'position' ) === true ) {
 
 
 							cb( mesh, geometry );
 							cb( mesh, geometry );
@@ -37,9 +36,9 @@
 
 
 				} );
 				} );
 
 
-			} // Default options
-
+			}
 
 
+			// Default options
 			const defaultOptions = {
 			const defaultOptions = {
 				binary: false,
 				binary: false,
 				excludeAttributes: [],
 				excludeAttributes: [],
@@ -51,9 +50,10 @@
 			let includeIndices = true;
 			let includeIndices = true;
 			let includeNormals = false;
 			let includeNormals = false;
 			let includeColors = false;
 			let includeColors = false;
-			let includeUVs = false; // count the vertices, check which properties are used,
-			// and cache the BufferGeometry
+			let includeUVs = false;
 
 
+			// count the vertices, check which properties are used,
+			// and cache the BufferGeometry
 			let vertexCount = 0;
 			let vertexCount = 0;
 			let faceCount = 0;
 			let faceCount = 0;
 			object.traverse( function ( child ) {
 			object.traverse( function ( child ) {
@@ -67,7 +67,6 @@
 					const uvs = geometry.getAttribute( 'uv' );
 					const uvs = geometry.getAttribute( 'uv' );
 					const colors = geometry.getAttribute( 'color' );
 					const colors = geometry.getAttribute( 'color' );
 					const indices = geometry.getIndex();
 					const indices = geometry.getIndex();
-
 					if ( vertices === undefined ) {
 					if ( vertices === undefined ) {
 
 
 						return;
 						return;
@@ -96,7 +95,6 @@
 			includeNormals = includeNormals && excludeAttributes.indexOf( 'normal' ) === - 1;
 			includeNormals = includeNormals && excludeAttributes.indexOf( 'normal' ) === - 1;
 			includeColors = includeColors && excludeAttributes.indexOf( 'color' ) === - 1;
 			includeColors = includeColors && excludeAttributes.indexOf( 'color' ) === - 1;
 			includeUVs = includeUVs && excludeAttributes.indexOf( 'uv' ) === - 1;
 			includeUVs = includeUVs && excludeAttributes.indexOf( 'uv' ) === - 1;
-
 			if ( includeIndices && faceCount !== Math.floor( faceCount ) ) {
 			if ( includeIndices && faceCount !== Math.floor( faceCount ) ) {
 
 
 				// point cloud meshes will not have an index array and may not have a
 				// point cloud meshes will not have an index array and may not have a
@@ -108,9 +106,9 @@
 			}
 			}
 
 
 			const indexByteCount = 4;
 			const indexByteCount = 4;
-			let header = 'ply\n' + `format ${options.binary ? options.littleEndian ? 'binary_little_endian' : 'binary_big_endian' : 'ascii'} 1.0\n` + `element vertex ${vertexCount}\n` + // position
+			let header = 'ply\n' + `format ${options.binary ? options.littleEndian ? 'binary_little_endian' : 'binary_big_endian' : 'ascii'} 1.0\n` + `element vertex ${vertexCount}\n` +
+    // position
     'property float x\n' + 'property float y\n' + 'property float z\n';
     'property float x\n' + 'property float y\n' + 'property float z\n';
-
 			if ( includeNormals === true ) {
 			if ( includeNormals === true ) {
 
 
 				// normal
 				// normal
@@ -139,23 +137,25 @@
 
 
 			}
 			}
 
 
-			header += 'end_header\n'; // Generate attribute data
+			header += 'end_header\n';
 
 
+			// Generate attribute data
 			const vertex = new THREE.Vector3();
 			const vertex = new THREE.Vector3();
 			const normalMatrixWorld = new THREE.Matrix3();
 			const normalMatrixWorld = new THREE.Matrix3();
 			let result = null;
 			let result = null;
-
 			if ( options.binary === true ) {
 			if ( options.binary === true ) {
 
 
 				// Binary File Generation
 				// Binary File Generation
-				const headerBin = new TextEncoder().encode( header ); // 3 position values at 4 bytes
+				const headerBin = new TextEncoder().encode( header );
+
+				// 3 position values at 4 bytes
 				// 3 normal values at 4 bytes
 				// 3 normal values at 4 bytes
 				// 3 color channels with 1 byte
 				// 3 color channels with 1 byte
 				// 2 uv values at 4 bytes
 				// 2 uv values at 4 bytes
+				const vertexListLength = vertexCount * ( 4 * 3 + ( includeNormals ? 4 * 3 : 0 ) + ( includeColors ? 3 : 0 ) + ( includeUVs ? 4 * 2 : 0 ) );
 
 
-				const vertexListLength = vertexCount * ( 4 * 3 + ( includeNormals ? 4 * 3 : 0 ) + ( includeColors ? 3 : 0 ) + ( includeUVs ? 4 * 2 : 0 ) ); // 1 byte shape desciptor
+				// 1 byte shape desciptor
 				// 3 vertex indices at ${indexByteCount} bytes
 				// 3 vertex indices at ${indexByteCount} bytes
-
 				const faceListLength = includeIndices ? faceCount * ( indexByteCount * 3 + 1 ) : 0;
 				const faceListLength = includeIndices ? faceCount * ( indexByteCount * 3 + 1 ) : 0;
 				const output = new DataView( new ArrayBuffer( headerBin.length + vertexListLength + faceListLength ) );
 				const output = new DataView( new ArrayBuffer( headerBin.length + vertexListLength + faceListLength ) );
 				new Uint8Array( output.buffer ).set( headerBin, 0 );
 				new Uint8Array( output.buffer ).set( headerBin, 0 );
@@ -170,19 +170,20 @@
 					const colors = geometry.getAttribute( 'color' );
 					const colors = geometry.getAttribute( 'color' );
 					const indices = geometry.getIndex();
 					const indices = geometry.getIndex();
 					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
 					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
 					for ( let i = 0, l = vertices.count; i < l; i ++ ) {
 					for ( let i = 0, l = vertices.count; i < l; i ++ ) {
 
 
 						vertex.fromBufferAttribute( vertices, i );
 						vertex.fromBufferAttribute( vertices, i );
-						vertex.applyMatrix4( mesh.matrixWorld ); // Position information
+						vertex.applyMatrix4( mesh.matrixWorld );
 
 
+						// Position information
 						output.setFloat32( vOffset, vertex.x, options.littleEndian );
 						output.setFloat32( vOffset, vertex.x, options.littleEndian );
 						vOffset += 4;
 						vOffset += 4;
 						output.setFloat32( vOffset, vertex.y, options.littleEndian );
 						output.setFloat32( vOffset, vertex.y, options.littleEndian );
 						vOffset += 4;
 						vOffset += 4;
 						output.setFloat32( vOffset, vertex.z, options.littleEndian );
 						output.setFloat32( vOffset, vertex.z, options.littleEndian );
-						vOffset += 4; // Normal information
+						vOffset += 4;
 
 
+						// Normal information
 						if ( includeNormals === true ) {
 						if ( includeNormals === true ) {
 
 
 							if ( normals != null ) {
 							if ( normals != null ) {
@@ -207,9 +208,9 @@
 
 
 							}
 							}
 
 
-						} // UV information
-
+						}
 
 
+						// UV information
 						if ( includeUVs === true ) {
 						if ( includeUVs === true ) {
 
 
 							if ( uvs != null ) {
 							if ( uvs != null ) {
@@ -228,9 +229,9 @@
 
 
 							}
 							}
 
 
-						} // THREE.Color information
-
+						}
 
 
+						// THREE.Color information
 						if ( includeColors === true ) {
 						if ( includeColors === true ) {
 
 
 							if ( colors != null ) {
 							if ( colors != null ) {
@@ -261,6 +262,7 @@
 					if ( includeIndices === true ) {
 					if ( includeIndices === true ) {
 
 
 						// Create the face list
 						// Create the face list
+
 						if ( indices !== null ) {
 						if ( indices !== null ) {
 
 
 							for ( let i = 0, l = indices.count; i < l; i += 3 ) {
 							for ( let i = 0, l = indices.count; i < l; i += 3 ) {
@@ -293,10 +295,10 @@
 
 
 						}
 						}
 
 
-					} // Save the amount of verts we've already written so we can offset
-					// the face index on the next mesh
-
+					}
 
 
+					// Save the amount of verts we've already written so we can offset
+					// the face index on the next mesh
 					writtenVertices += vertices.count;
 					writtenVertices += vertices.count;
 
 
 				} );
 				} );
@@ -316,15 +318,18 @@
 					const uvs = geometry.getAttribute( 'uv' );
 					const uvs = geometry.getAttribute( 'uv' );
 					const colors = geometry.getAttribute( 'color' );
 					const colors = geometry.getAttribute( 'color' );
 					const indices = geometry.getIndex();
 					const indices = geometry.getIndex();
-					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld ); // form each line
+					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
 
 
+					// form each line
 					for ( let i = 0, l = vertices.count; i < l; i ++ ) {
 					for ( let i = 0, l = vertices.count; i < l; i ++ ) {
 
 
 						vertex.fromBufferAttribute( vertices, i );
 						vertex.fromBufferAttribute( vertices, i );
-						vertex.applyMatrix4( mesh.matrixWorld ); // Position information
+						vertex.applyMatrix4( mesh.matrixWorld );
 
 
-						let line = vertex.x + ' ' + vertex.y + ' ' + vertex.z; // Normal information
+						// Position information
+						let line = vertex.x + ' ' + vertex.y + ' ' + vertex.z;
 
 
+						// Normal information
 						if ( includeNormals === true ) {
 						if ( includeNormals === true ) {
 
 
 							if ( normals != null ) {
 							if ( normals != null ) {
@@ -339,9 +344,9 @@
 
 
 							}
 							}
 
 
-						} // UV information
-
+						}
 
 
+						// UV information
 						if ( includeUVs === true ) {
 						if ( includeUVs === true ) {
 
 
 							if ( uvs != null ) {
 							if ( uvs != null ) {
@@ -354,9 +359,9 @@
 
 
 							}
 							}
 
 
-						} // THREE.Color information
-
+						}
 
 
+						// THREE.Color information
 						if ( includeColors === true ) {
 						if ( includeColors === true ) {
 
 
 							if ( colors != null ) {
 							if ( colors != null ) {
@@ -374,9 +379,9 @@
 
 
 						vertexList += line + '\n';
 						vertexList += line + '\n';
 
 
-					} // Create the face list
-
+					}
 
 
+					// Create the face list
 					if ( includeIndices === true ) {
 					if ( includeIndices === true ) {
 
 
 						if ( indices !== null ) {
 						if ( indices !== null ) {

+ 5 - 7
examples/js/exporters/STLExporter.js

@@ -13,7 +13,9 @@
 
 
 		parse( scene, options = {} ) {
 		parse( scene, options = {} ) {
 
 
-			const binary = options.binary !== undefined ? options.binary : false; //
+			const binary = options.binary !== undefined ? options.binary : false;
+
+			//
 
 
 			const objects = [];
 			const objects = [];
 			let triangles = 0;
 			let triangles = 0;
@@ -57,17 +59,16 @@
 			const cb = new THREE.Vector3();
 			const cb = new THREE.Vector3();
 			const ab = new THREE.Vector3();
 			const ab = new THREE.Vector3();
 			const normal = new THREE.Vector3();
 			const normal = new THREE.Vector3();
-
 			for ( let i = 0, il = objects.length; i < il; i ++ ) {
 			for ( let i = 0, il = objects.length; i < il; i ++ ) {
 
 
 				const object = objects[ i ].object3d;
 				const object = objects[ i ].object3d;
 				const geometry = objects[ i ].geometry;
 				const geometry = objects[ i ].geometry;
 				const index = geometry.index;
 				const index = geometry.index;
 				const positionAttribute = geometry.getAttribute( 'position' );
 				const positionAttribute = geometry.getAttribute( 'position' );
-
 				if ( index !== null ) {
 				if ( index !== null ) {
 
 
 					// indexed geometry
 					// indexed geometry
+
 					for ( let j = 0; j < index.count; j += 3 ) {
 					for ( let j = 0; j < index.count; j += 3 ) {
 
 
 						const a = index.getX( j + 0 );
 						const a = index.getX( j + 0 );
@@ -80,6 +81,7 @@
 				} else {
 				} else {
 
 
 					// non-indexed geometry
 					// non-indexed geometry
+
 					for ( let j = 0; j < positionAttribute.count; j += 3 ) {
 					for ( let j = 0; j < positionAttribute.count; j += 3 ) {
 
 
 						const a = j + 0;
 						const a = j + 0;
@@ -100,13 +102,11 @@
 			}
 			}
 
 
 			return output;
 			return output;
-
 			function writeFace( a, b, c, positionAttribute, object ) {
 			function writeFace( a, b, c, positionAttribute, object ) {
 
 
 				vA.fromBufferAttribute( positionAttribute, a );
 				vA.fromBufferAttribute( positionAttribute, a );
 				vB.fromBufferAttribute( positionAttribute, b );
 				vB.fromBufferAttribute( positionAttribute, b );
 				vC.fromBufferAttribute( positionAttribute, c );
 				vC.fromBufferAttribute( positionAttribute, c );
-
 				if ( object.isSkinnedMesh === true ) {
 				if ( object.isSkinnedMesh === true ) {
 
 
 					object.boneTransform( a, vA );
 					object.boneTransform( a, vA );
@@ -122,7 +122,6 @@
 				writeVertex( vA );
 				writeVertex( vA );
 				writeVertex( vB );
 				writeVertex( vB );
 				writeVertex( vC );
 				writeVertex( vC );
-
 				if ( binary === true ) {
 				if ( binary === true ) {
 
 
 					output.setUint16( offset, 0, true );
 					output.setUint16( offset, 0, true );
@@ -143,7 +142,6 @@
 				ab.subVectors( vA, vB );
 				ab.subVectors( vA, vB );
 				cb.cross( ab ).normalize();
 				cb.cross( ab ).normalize();
 				normal.copy( cb ).normalize();
 				normal.copy( cb ).normalize();
-
 				if ( binary === true ) {
 				if ( binary === true ) {
 
 
 					output.setFloat32( offset, normal.x, true );
 					output.setFloat32( offset, normal.x, true );

+ 14 - 24
examples/js/exporters/USDZExporter.js

@@ -5,8 +5,9 @@
 		async parse( scene ) {
 		async parse( scene ) {
 
 
 			const files = {};
 			const files = {};
-			const modelFileName = 'model.usda'; // model file should be first in USDZ archive so we init it here
+			const modelFileName = 'model.usda';
 
 
+			// model file should be first in USDZ archive so we init it here
 			files[ modelFileName ] = null;
 			files[ modelFileName ] = null;
 			let output = buildHeader();
 			let output = buildHeader();
 			const materials = {};
 			const materials = {};
@@ -17,11 +18,9 @@
 
 
 					const geometry = object.geometry;
 					const geometry = object.geometry;
 					const material = object.material;
 					const material = object.material;
-
 					if ( material.isMeshStandardMaterial ) {
 					if ( material.isMeshStandardMaterial ) {
 
 
 						const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usd';
 						const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usd';
-
 						if ( ! ( geometryFileName in files ) ) {
 						if ( ! ( geometryFileName in files ) ) {
 
 
 							const meshObject = buildMeshObject( geometry );
 							const meshObject = buildMeshObject( geometry );
@@ -49,7 +48,6 @@
 			output += buildMaterials( materials, textures );
 			output += buildMaterials( materials, textures );
 			files[ modelFileName ] = fflate.strToU8( output );
 			files[ modelFileName ] = fflate.strToU8( output );
 			output = null;
 			output = null;
-
 			for ( const id in textures ) {
 			for ( const id in textures ) {
 
 
 				const texture = textures[ id ];
 				const texture = textures[ id ];
@@ -59,19 +57,18 @@
 				const blob = await new Promise( resolve => canvas.toBlob( resolve, isRGBA ? 'image/png' : 'image/jpeg', 1 ) );
 				const blob = await new Promise( resolve => canvas.toBlob( resolve, isRGBA ? 'image/png' : 'image/jpeg', 1 ) );
 				files[ `textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}` ] = new Uint8Array( await blob.arrayBuffer() );
 				files[ `textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}` ] = new Uint8Array( await blob.arrayBuffer() );
 
 
-			} // 64 byte alignment
-			// https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109
+			}
 
 
+			// 64 byte alignment
+			// https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109
 
 
 			let offset = 0;
 			let offset = 0;
-
 			for ( const filename in files ) {
 			for ( const filename in files ) {
 
 
 				const file = files[ filename ];
 				const file = files[ filename ];
 				const headerSize = 34 + filename.length;
 				const headerSize = 34 + filename.length;
 				offset += headerSize;
 				offset += headerSize;
 				const offsetMod64 = offset & 63;
 				const offsetMod64 = offset & 63;
-
 				if ( offsetMod64 !== 4 ) {
 				if ( offsetMod64 !== 4 ) {
 
 
 					const padLength = 64 - offsetMod64;
 					const padLength = 64 - offsetMod64;
@@ -95,7 +92,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function imageToCanvas( image, color ) {
 	function imageToCanvas( image, color ) {
 
 
 		if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) {
 		if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) {
@@ -106,7 +102,6 @@
 			canvas.height = image.height * Math.min( 1, scale );
 			canvas.height = image.height * Math.min( 1, scale );
 			const context = canvas.getContext( '2d' );
 			const context = canvas.getContext( '2d' );
 			context.drawImage( image, 0, 0, canvas.width, canvas.height );
 			context.drawImage( image, 0, 0, canvas.width, canvas.height );
-
 			if ( color !== undefined ) {
 			if ( color !== undefined ) {
 
 
 				const hex = parseInt( color, 16 );
 				const hex = parseInt( color, 16 );
@@ -115,7 +110,6 @@
 				const b = ( hex & 255 ) / 255;
 				const b = ( hex & 255 ) / 255;
 				const imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
 				const imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
 				const data = imagedata.data;
 				const data = imagedata.data;
-
 				for ( let i = 0; i < data.length; i += 4 ) {
 				for ( let i = 0; i < data.length; i += 4 ) {
 
 
 					data[ i + 0 ] = data[ i + 0 ] * r;
 					data[ i + 0 ] = data[ i + 0 ] * r;
@@ -132,11 +126,11 @@
 
 
 		}
 		}
 
 
-	} //
+	}
 
 
+	//
 
 
 	const PRECISION = 7;
 	const PRECISION = 7;
-
 	function buildHeader() {
 	function buildHeader() {
 
 
 		return `#usda 1.0
 		return `#usda 1.0
@@ -158,14 +152,14 @@
 		output += dataToInsert;
 		output += dataToInsert;
 		return fflate.strToU8( output );
 		return fflate.strToU8( output );
 
 
-	} // Xform
+	}
 
 
+	// Xform
 
 
 	function buildXform( object, geometry, material ) {
 	function buildXform( object, geometry, material ) {
 
 
 		const name = 'Object_' + object.id;
 		const name = 'Object_' + object.id;
 		const transform = buildMatrix( object.matrixWorld );
 		const transform = buildMatrix( object.matrixWorld );
-
 		if ( object.matrixWorld.determinant() < 0 ) {
 		if ( object.matrixWorld.determinant() < 0 ) {
 
 
 			console.warn( 'THREE.USDZExporter: USDZ does not support negative scales', object );
 			console.warn( 'THREE.USDZExporter: USDZ does not support negative scales', object );
@@ -197,8 +191,9 @@
 
 
 		return `(${array[ offset + 0 ]}, ${array[ offset + 1 ]}, ${array[ offset + 2 ]}, ${array[ offset + 3 ]})`;
 		return `(${array[ offset + 0 ]}, ${array[ offset + 1 ]}, ${array[ offset + 2 ]}, ${array[ offset + 3 ]})`;
 
 
-	} // Mesh
+	}
 
 
+	// Mesh
 
 
 	function buildMeshObject( geometry ) {
 	function buildMeshObject( geometry ) {
 
 
@@ -246,7 +241,6 @@ def "Geometry"
 
 
 		const index = geometry.index;
 		const index = geometry.index;
 		const array = [];
 		const array = [];
-
 		if ( index !== null ) {
 		if ( index !== null ) {
 
 
 			for ( let i = 0; i < index.count; i ++ ) {
 			for ( let i = 0; i < index.count; i ++ ) {
@@ -258,7 +252,6 @@ def "Geometry"
 		} else {
 		} else {
 
 
 			const length = geometry.attributes.position.count;
 			const length = geometry.attributes.position.count;
-
 			for ( let i = 0; i < length; i ++ ) {
 			for ( let i = 0; i < length; i ++ ) {
 
 
 				array.push( i );
 				array.push( i );
@@ -281,7 +274,6 @@ def "Geometry"
 		}
 		}
 
 
 		const array = [];
 		const array = [];
-
 		for ( let i = 0; i < attribute.count; i ++ ) {
 		for ( let i = 0; i < attribute.count; i ++ ) {
 
 
 			const x = attribute.getX( i );
 			const x = attribute.getX( i );
@@ -305,7 +297,6 @@ def "Geometry"
 		}
 		}
 
 
 		const array = [];
 		const array = [];
-
 		for ( let i = 0; i < attribute.count; i ++ ) {
 		for ( let i = 0; i < attribute.count; i ++ ) {
 
 
 			const x = attribute.getX( i );
 			const x = attribute.getX( i );
@@ -316,13 +307,13 @@ def "Geometry"
 
 
 		return array.join( ', ' );
 		return array.join( ', ' );
 
 
-	} // Materials
+	}
 
 
+	// Materials
 
 
 	function buildMaterials( materials, textures ) {
 	function buildMaterials( materials, textures ) {
 
 
 		const array = [];
 		const array = [];
-
 		for ( const uuid in materials ) {
 		for ( const uuid in materials ) {
 
 
 			const material = materials[ uuid ];
 			const material = materials[ uuid ];
@@ -342,10 +333,10 @@ ${array.join( '' )}
 	function buildMaterial( material, textures ) {
 	function buildMaterial( material, textures ) {
 
 
 		// https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
 		// https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
+
 		const pad = '            ';
 		const pad = '            ';
 		const inputs = [];
 		const inputs = [];
 		const samplers = [];
 		const samplers = [];
-
 		function buildTexture( texture, mapType, color ) {
 		function buildTexture( texture, mapType, color ) {
 
 
 			const id = texture.id + ( color ? '_' + color.getHexString() : '' );
 			const id = texture.id + ( color ? '_' + color.getHexString() : '' );
@@ -390,7 +381,6 @@ ${array.join( '' )}
 		if ( material.map !== null ) {
 		if ( material.map !== null ) {
 
 
 			inputs.push( `${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:rgb>` );
 			inputs.push( `${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:rgb>` );
-
 			if ( material.transparent ) {
 			if ( material.transparent ) {
 
 
 				inputs.push( `${pad}float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>` );
 				inputs.push( `${pad}float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>` );

+ 0 - 1
examples/js/geometries/BoxLineGeometry.js

@@ -18,7 +18,6 @@
 			let x = - widthHalf;
 			let x = - widthHalf;
 			let y = - heightHalf;
 			let y = - heightHalf;
 			let z = - depthHalf;
 			let z = - depthHalf;
-
 			for ( let i = 0; i <= widthSegments; i ++ ) {
 			for ( let i = 0; i <= widthSegments; i ++ ) {
 
 
 				vertices.push( x, - heightHalf, - depthHalf, x, heightHalf, - depthHalf );
 				vertices.push( x, - heightHalf, - depthHalf, x, heightHalf, - depthHalf );

+ 11 - 6
examples/js/geometries/ConvexGeometry.js

@@ -4,25 +4,29 @@
 
 
 		constructor( points = [] ) {
 		constructor( points = [] ) {
 
 
-			super(); // buffers
+			super();
+
+			// buffers
 
 
 			const vertices = [];
 			const vertices = [];
 			const normals = [];
 			const normals = [];
-
 			if ( THREE.ConvexHull === undefined ) {
 			if ( THREE.ConvexHull === undefined ) {
 
 
 				console.error( 'THREE.ConvexGeometry: ConvexGeometry relies on THREE.ConvexHull' );
 				console.error( 'THREE.ConvexGeometry: ConvexGeometry relies on THREE.ConvexHull' );
 
 
 			}
 			}
 
 
-			const convexHull = new THREE.ConvexHull().setFromPoints( points ); // generate vertices and normals
+			const convexHull = new THREE.ConvexHull().setFromPoints( points );
 
 
-			const faces = convexHull.faces;
+			// generate vertices and normals
 
 
+			const faces = convexHull.faces;
 			for ( let i = 0; i < faces.length; i ++ ) {
 			for ( let i = 0; i < faces.length; i ++ ) {
 
 
 				const face = faces[ i ];
 				const face = faces[ i ];
-				let edge = face.edge; // we move along a doubly-connected edge list to access all face points (see HalfEdge docs)
+				let edge = face.edge;
+
+				// we move along a doubly-connected edge list to access all face points (see HalfEdge docs)
 
 
 				do {
 				do {
 
 
@@ -33,8 +37,9 @@
 
 
 				} while ( edge !== face.edge );
 				} while ( edge !== face.edge );
 
 
-			} // build geometry
+			}
 
 
+			// build geometry
 
 
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 			this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
 			this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );

+ 53 - 20
examples/js/geometries/DecalGeometry.js

@@ -19,35 +19,48 @@
 
 
 		constructor( mesh, position, orientation, size ) {
 		constructor( mesh, position, orientation, size ) {
 
 
-			super(); // buffers
+			super();
+
+			// buffers
 
 
 			const vertices = [];
 			const vertices = [];
 			const normals = [];
 			const normals = [];
-			const uvs = []; // helpers
+			const uvs = [];
+
+			// helpers
 
 
-			const plane = new THREE.Vector3(); // this matrix represents the transformation of the decal projector
+			const plane = new THREE.Vector3();
+
+			// this matrix represents the transformation of the decal projector
 
 
 			const projectorMatrix = new THREE.Matrix4();
 			const projectorMatrix = new THREE.Matrix4();
 			projectorMatrix.makeRotationFromEuler( orientation );
 			projectorMatrix.makeRotationFromEuler( orientation );
 			projectorMatrix.setPosition( position );
 			projectorMatrix.setPosition( position );
 			const projectorMatrixInverse = new THREE.Matrix4();
 			const projectorMatrixInverse = new THREE.Matrix4();
-			projectorMatrixInverse.copy( projectorMatrix ).invert(); // generate buffers
+			projectorMatrixInverse.copy( projectorMatrix ).invert();
+
+			// generate buffers
 
 
-			generate(); // build geometry
+			generate();
+
+			// build geometry
 
 
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 			this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
 			this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
 			this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
 			this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
-
 			function generate() {
 			function generate() {
 
 
 				let decalVertices = [];
 				let decalVertices = [];
 				const vertex = new THREE.Vector3();
 				const vertex = new THREE.Vector3();
-				const normal = new THREE.Vector3(); // handle different geometry types
+				const normal = new THREE.Vector3();
+
+				// handle different geometry types
 
 
 				const geometry = mesh.geometry;
 				const geometry = mesh.geometry;
 				const positionAttribute = geometry.attributes.position;
 				const positionAttribute = geometry.attributes.position;
-				const normalAttribute = geometry.attributes.normal; // first, create an array of 'DecalVertex' objects
+				const normalAttribute = geometry.attributes.normal;
+
+				// first, create an array of 'DecalVertex' objects
 				// three consecutive 'DecalVertex' objects represent a single face
 				// three consecutive 'DecalVertex' objects represent a single face
 				//
 				//
 				// this data structure will be later used to perform the clipping
 				// this data structure will be later used to perform the clipping
@@ -55,8 +68,8 @@
 				if ( geometry.index !== null ) {
 				if ( geometry.index !== null ) {
 
 
 					// indexed THREE.BufferGeometry
 					// indexed THREE.BufferGeometry
-					const index = geometry.index;
 
 
+					const index = geometry.index;
 					for ( let i = 0; i < index.count; i ++ ) {
 					for ( let i = 0; i < index.count; i ++ ) {
 
 
 						vertex.fromBufferAttribute( positionAttribute, index.getX( i ) );
 						vertex.fromBufferAttribute( positionAttribute, index.getX( i ) );
@@ -68,6 +81,7 @@
 				} else {
 				} else {
 
 
 					// non-indexed THREE.BufferGeometry
 					// non-indexed THREE.BufferGeometry
+
 					for ( let i = 0; i < positionAttribute.count; i ++ ) {
 					for ( let i = 0; i < positionAttribute.count; i ++ ) {
 
 
 						vertex.fromBufferAttribute( positionAttribute, i );
 						vertex.fromBufferAttribute( positionAttribute, i );
@@ -76,23 +90,32 @@
 
 
 					}
 					}
 
 
-				} // second, clip the geometry so that it doesn't extend out from the projector
+				}
 
 
+				// second, clip the geometry so that it doesn't extend out from the projector
 
 
 				decalVertices = clipGeometry( decalVertices, plane.set( 1, 0, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( 1, 0, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( - 1, 0, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( - 1, 0, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( 0, 1, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( 0, 1, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( 0, - 1, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( 0, - 1, 0 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, 1 ) );
 				decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, 1 ) );
-				decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, - 1 ) ); // third, generate final vertices, normals and uvs
+				decalVertices = clipGeometry( decalVertices, plane.set( 0, 0, - 1 ) );
+
+				// third, generate final vertices, normals and uvs
 
 
 				for ( let i = 0; i < decalVertices.length; i ++ ) {
 				for ( let i = 0; i < decalVertices.length; i ++ ) {
 
 
-					const decalVertex = decalVertices[ i ]; // create texture coordinates (we are still in projector space)
+					const decalVertex = decalVertices[ i ];
+
+					// create texture coordinates (we are still in projector space)
 
 
-					uvs.push( 0.5 + decalVertex.position.x / size.x, 0.5 + decalVertex.position.y / size.y ); // transform the vertex back to world space
+					uvs.push( 0.5 + decalVertex.position.x / size.x, 0.5 + decalVertex.position.y / size.y );
 
 
-					decalVertex.position.applyMatrix4( projectorMatrix ); // now create vertex and normal buffer data
+					// transform the vertex back to world space
+
+					decalVertex.position.applyMatrix4( projectorMatrix );
+
+					// now create vertex and normal buffer data
 
 
 					vertices.push( decalVertex.position.x, decalVertex.position.y, decalVertex.position.z );
 					vertices.push( decalVertex.position.x, decalVertex.position.y, decalVertex.position.z );
 					normals.push( decalVertex.normal.x, decalVertex.normal.y, decalVertex.normal.z );
 					normals.push( decalVertex.normal.x, decalVertex.normal.y, decalVertex.normal.z );
@@ -104,6 +127,7 @@
 			function pushDecalVertex( decalVertices, vertex, normal ) {
 			function pushDecalVertex( decalVertices, vertex, normal ) {
 
 
 				// transform the vertex to world space, then to projector space
 				// transform the vertex to world space, then to projector space
+
 				vertex.applyMatrix4( mesh.matrixWorld );
 				vertex.applyMatrix4( mesh.matrixWorld );
 				vertex.applyMatrix4( projectorMatrixInverse );
 				vertex.applyMatrix4( projectorMatrixInverse );
 				normal.transformDirection( mesh.matrixWorld );
 				normal.transformDirection( mesh.matrixWorld );
@@ -114,7 +138,9 @@
 			function clipGeometry( inVertices, plane ) {
 			function clipGeometry( inVertices, plane ) {
 
 
 				const outVertices = [];
 				const outVertices = [];
-				const s = 0.5 * Math.abs( size.dot( plane ) ); // a single iteration clips one face,
+				const s = 0.5 * Math.abs( size.dot( plane ) );
+
+				// a single iteration clips one face,
 				// which consists of three consecutive 'DecalVertex' objects
 				// which consists of three consecutive 'DecalVertex' objects
 
 
 				for ( let i = 0; i < inVertices.length; i += 3 ) {
 				for ( let i = 0; i < inVertices.length; i += 3 ) {
@@ -129,16 +155,18 @@
 					const d3 = inVertices[ i + 2 ].position.dot( plane ) - s;
 					const d3 = inVertices[ i + 2 ].position.dot( plane ) - s;
 					const v1Out = d1 > 0;
 					const v1Out = d1 > 0;
 					const v2Out = d2 > 0;
 					const v2Out = d2 > 0;
-					const v3Out = d3 > 0; // calculate, how many vertices of the face lie outside of the clipping plane
+					const v3Out = d3 > 0;
 
 
-					total = ( v1Out ? 1 : 0 ) + ( v2Out ? 1 : 0 ) + ( v3Out ? 1 : 0 );
+					// calculate, how many vertices of the face lie outside of the clipping plane
 
 
+					total = ( v1Out ? 1 : 0 ) + ( v2Out ? 1 : 0 ) + ( v3Out ? 1 : 0 );
 					switch ( total ) {
 					switch ( total ) {
 
 
 						case 0:
 						case 0:
 						{
 						{
 
 
 							// the entire face lies inside of the plane, no clipping needed
 							// the entire face lies inside of the plane, no clipping needed
+
 							outVertices.push( inVertices[ i ] );
 							outVertices.push( inVertices[ i ] );
 							outVertices.push( inVertices[ i + 1 ] );
 							outVertices.push( inVertices[ i + 1 ] );
 							outVertices.push( inVertices[ i + 2 ] );
 							outVertices.push( inVertices[ i + 2 ] );
@@ -150,6 +178,7 @@
 						{
 						{
 
 
 							// one vertex lies outside of the plane, perform clipping
 							// one vertex lies outside of the plane, perform clipping
+
 							if ( v1Out ) {
 							if ( v1Out ) {
 
 
 								nV1 = inVertices[ i + 1 ];
 								nV1 = inVertices[ i + 1 ];
@@ -198,6 +227,7 @@
 						{
 						{
 
 
 							// two vertices lies outside of the plane, perform clipping
 							// two vertices lies outside of the plane, perform clipping
+
 							if ( ! v1Out ) {
 							if ( ! v1Out ) {
 
 
 								nV1 = inVertices[ i ].clone();
 								nV1 = inVertices[ i ].clone();
@@ -239,6 +269,7 @@
 						{
 						{
 
 
 							// the entire face lies outside of the plane, so let's discard the corresponding vertices
 							// the entire face lies outside of the plane, so let's discard the corresponding vertices
+
 							break;
 							break;
 
 
 						}
 						}
@@ -256,7 +287,9 @@
 				const d0 = v0.position.dot( p ) - s;
 				const d0 = v0.position.dot( p ) - s;
 				const d1 = v1.position.dot( p ) - s;
 				const d1 = v1.position.dot( p ) - s;
 				const s0 = d0 / ( d0 - d1 );
 				const s0 = d0 / ( d0 - d1 );
-				const v = new DecalVertex( new THREE.Vector3( v0.position.x + s0 * ( v1.position.x - v0.position.x ), v0.position.y + s0 * ( v1.position.y - v0.position.y ), v0.position.z + s0 * ( v1.position.z - v0.position.z ) ), new THREE.Vector3( v0.normal.x + s0 * ( v1.normal.x - v0.normal.x ), v0.normal.y + s0 * ( v1.normal.y - v0.normal.y ), v0.normal.z + s0 * ( v1.normal.z - v0.normal.z ) ) ); // need to clip more values (texture coordinates)? do it this way:
+				const v = new DecalVertex( new THREE.Vector3( v0.position.x + s0 * ( v1.position.x - v0.position.x ), v0.position.y + s0 * ( v1.position.y - v0.position.y ), v0.position.z + s0 * ( v1.position.z - v0.position.z ) ), new THREE.Vector3( v0.normal.x + s0 * ( v1.normal.x - v0.normal.x ), v0.normal.y + s0 * ( v1.normal.y - v0.normal.y ), v0.normal.z + s0 * ( v1.normal.z - v0.normal.z ) ) );
+
+				// need to clip more values (texture coordinates)? do it this way:
 				// intersectpoint.value = a.value + s * ( b.value - a.value );
 				// intersectpoint.value = a.value + s * ( b.value - a.value );
 
 
 				return v;
 				return v;
@@ -265,8 +298,9 @@
 
 
 		}
 		}
 
 
-	} // helper
+	}
 
 
+	// helper
 
 
 	class DecalVertex {
 	class DecalVertex {
 
 
@@ -276,7 +310,6 @@
 			this.normal = normal;
 			this.normal = normal;
 
 
 		}
 		}
-
 		clone() {
 		clone() {
 
 
 			return new this.constructor( this.position.clone(), this.normal.clone() );
 			return new this.constructor( this.position.clone(), this.normal.clone() );

+ 54 - 67
examples/js/geometries/LightningStrike.js

@@ -107,19 +107,19 @@
 
 
 			super();
 			super();
 			this.isLightningStrike = true;
 			this.isLightningStrike = true;
-			this.type = 'LightningStrike'; // Set parameters, and set undefined parameters to default values
+			this.type = 'LightningStrike';
 
 
-			this.init( LightningStrike.copyParameters( rayParameters, rayParameters ) ); // Creates and populates the mesh
+			// Set parameters, and set undefined parameters to default values
+			this.init( LightningStrike.copyParameters( rayParameters, rayParameters ) );
 
 
+			// Creates and populates the mesh
 			this.createMesh();
 			this.createMesh();
 
 
 		}
 		}
-
 		static createRandomGenerator() {
 		static createRandomGenerator() {
 
 
 			const numSeeds = 2053;
 			const numSeeds = 2053;
 			const seeds = [];
 			const seeds = [];
-
 			for ( let i = 0; i < numSeeds; i ++ ) {
 			for ( let i = 0; i < numSeeds; i ++ ) {
 
 
 				seeds.push( Math.random() );
 				seeds.push( Math.random() );
@@ -149,7 +149,6 @@
 			return generator;
 			return generator;
 
 
 		}
 		}
-
 		static copyParameters( dest = {}, source = {} ) {
 		static copyParameters( dest = {}, source = {} ) {
 
 
 			const vecCopy = function ( v ) {
 			const vecCopy = function ( v ) {
@@ -167,8 +166,12 @@
 			};
 			};
 
 
 			dest.sourceOffset = source.sourceOffset !== undefined ? vecCopy( source.sourceOffset ) : new THREE.Vector3( 0, 100, 0 ), dest.destOffset = source.destOffset !== undefined ? vecCopy( source.destOffset ) : new THREE.Vector3( 0, 0, 0 ), dest.timeScale = source.timeScale !== undefined ? source.timeScale : 1, dest.roughness = source.roughness !== undefined ? source.roughness : 0.9, dest.straightness = source.straightness !== undefined ? source.straightness : 0.7, dest.up0 = source.up0 !== undefined ? vecCopy( source.up0 ) : new THREE.Vector3( 0, 0, 1 );
 			dest.sourceOffset = source.sourceOffset !== undefined ? vecCopy( source.sourceOffset ) : new THREE.Vector3( 0, 100, 0 ), dest.destOffset = source.destOffset !== undefined ? vecCopy( source.destOffset ) : new THREE.Vector3( 0, 0, 0 ), dest.timeScale = source.timeScale !== undefined ? source.timeScale : 1, dest.roughness = source.roughness !== undefined ? source.roughness : 0.9, dest.straightness = source.straightness !== undefined ? source.straightness : 0.7, dest.up0 = source.up0 !== undefined ? vecCopy( source.up0 ) : new THREE.Vector3( 0, 0, 1 );
-			dest.up1 = source.up1 !== undefined ? vecCopy( source.up1 ) : new THREE.Vector3( 0, 0, 1 ), dest.radius0 = source.radius0 !== undefined ? source.radius0 : 1, dest.radius1 = source.radius1 !== undefined ? source.radius1 : 1, dest.radius0Factor = source.radius0Factor !== undefined ? source.radius0Factor : 0.5, dest.radius1Factor = source.radius1Factor !== undefined ? source.radius1Factor : 0.2, dest.minRadius = source.minRadius !== undefined ? source.minRadius : 0.2, // These parameters should not be changed after lightning creation. They can be changed but the ray will change its form abruptly:
-			dest.isEternal = source.isEternal !== undefined ? source.isEternal : source.birthTime === undefined || source.deathTime === undefined, dest.birthTime = source.birthTime, dest.deathTime = source.deathTime, dest.propagationTimeFactor = source.propagationTimeFactor !== undefined ? source.propagationTimeFactor : 0.1, dest.vanishingTimeFactor = source.vanishingTimeFactor !== undefined ? source.vanishingTimeFactor : 0.9, dest.subrayPeriod = source.subrayPeriod !== undefined ? source.subrayPeriod : 4, dest.subrayDutyCycle = source.subrayDutyCycle !== undefined ? source.subrayDutyCycle : 0.6; // These parameters cannot change after lightning creation:
+			dest.up1 = source.up1 !== undefined ? vecCopy( source.up1 ) : new THREE.Vector3( 0, 0, 1 ), dest.radius0 = source.radius0 !== undefined ? source.radius0 : 1, dest.radius1 = source.radius1 !== undefined ? source.radius1 : 1, dest.radius0Factor = source.radius0Factor !== undefined ? source.radius0Factor : 0.5, dest.radius1Factor = source.radius1Factor !== undefined ? source.radius1Factor : 0.2, dest.minRadius = source.minRadius !== undefined ? source.minRadius : 0.2,
+			// These parameters should not be changed after lightning creation. They can be changed but the ray will change its form abruptly:
+
+			dest.isEternal = source.isEternal !== undefined ? source.isEternal : source.birthTime === undefined || source.deathTime === undefined, dest.birthTime = source.birthTime, dest.deathTime = source.deathTime, dest.propagationTimeFactor = source.propagationTimeFactor !== undefined ? source.propagationTimeFactor : 0.1, dest.vanishingTimeFactor = source.vanishingTimeFactor !== undefined ? source.vanishingTimeFactor : 0.9, dest.subrayPeriod = source.subrayPeriod !== undefined ? source.subrayPeriod : 4, dest.subrayDutyCycle = source.subrayDutyCycle !== undefined ? source.subrayDutyCycle : 0.6;
+
+			// These parameters cannot change after lightning creation:
 
 
 			dest.maxIterations = source.maxIterations !== undefined ? source.maxIterations : 9;
 			dest.maxIterations = source.maxIterations !== undefined ? source.maxIterations : 9;
 			dest.isStatic = source.isStatic !== undefined ? source.isStatic : false;
 			dest.isStatic = source.isStatic !== undefined ? source.isStatic : false;
@@ -180,15 +183,12 @@
 			return dest;
 			return dest;
 
 
 		}
 		}
-
 		update( time ) {
 		update( time ) {
 
 
 			if ( this.isStatic ) return;
 			if ( this.isStatic ) return;
-
 			if ( this.rayParameters.isEternal || this.rayParameters.birthTime <= time && time <= this.rayParameters.deathTime ) {
 			if ( this.rayParameters.isEternal || this.rayParameters.birthTime <= time && time <= this.rayParameters.deathTime ) {
 
 
 				this.updateMesh( time );
 				this.updateMesh( time );
-
 				if ( time < this.subrays[ 0 ].endPropagationTime ) {
 				if ( time < this.subrays[ 0 ].endPropagationTime ) {
 
 
 					this.state = LightningStrike.RAY_PROPAGATING;
 					this.state = LightningStrike.RAY_PROPAGATING;
@@ -208,7 +208,6 @@
 			} else {
 			} else {
 
 
 				this.visible = false;
 				this.visible = false;
-
 				if ( time < this.rayParameters.birthTime ) {
 				if ( time < this.rayParameters.birthTime ) {
 
 
 					this.state = LightningStrike.RAY_UNBORN;
 					this.state = LightningStrike.RAY_UNBORN;
@@ -222,11 +221,13 @@
 			}
 			}
 
 
 		}
 		}
-
 		init( rayParameters ) {
 		init( rayParameters ) {
 
 
 			// Init all the state from the parameters
 			// Init all the state from the parameters
-			this.rayParameters = rayParameters; // These parameters cannot change after lightning creation:
+
+			this.rayParameters = rayParameters;
+
+			// These parameters cannot change after lightning creation:
 
 
 			this.maxIterations = rayParameters.maxIterations !== undefined ? Math.floor( rayParameters.maxIterations ) : 9;
 			this.maxIterations = rayParameters.maxIterations !== undefined ? Math.floor( rayParameters.maxIterations ) : 9;
 			rayParameters.maxIterations = this.maxIterations;
 			rayParameters.maxIterations = this.maxIterations;
@@ -239,13 +240,13 @@
 			this.recursionProbability = rayParameters.recursionProbability !== undefined ? rayParameters.recursionProbability : 0.6;
 			this.recursionProbability = rayParameters.recursionProbability !== undefined ? rayParameters.recursionProbability : 0.6;
 			rayParameters.recursionProbability = this.recursionProbability;
 			rayParameters.recursionProbability = this.recursionProbability;
 			this.generateUVs = rayParameters.generateUVs !== undefined ? rayParameters.generateUVs : false;
 			this.generateUVs = rayParameters.generateUVs !== undefined ? rayParameters.generateUVs : false;
-			rayParameters.generateUVs = this.generateUVs; // Random generator
+			rayParameters.generateUVs = this.generateUVs;
 
 
+			// Random generator
 			if ( rayParameters.randomGenerator !== undefined ) {
 			if ( rayParameters.randomGenerator !== undefined ) {
 
 
 				this.randomGenerator = rayParameters.randomGenerator;
 				this.randomGenerator = rayParameters.randomGenerator;
 				this.seedGenerator = rayParameters.randomGenerator;
 				this.seedGenerator = rayParameters.randomGenerator;
-
 				if ( rayParameters.noiseSeed !== undefined ) {
 				if ( rayParameters.noiseSeed !== undefined ) {
 
 
 					this.seedGenerator.setSeed( rayParameters.noiseSeed );
 					this.seedGenerator.setSeed( rayParameters.noiseSeed );
@@ -257,9 +258,9 @@
 				this.randomGenerator = LightningStrike.createRandomGenerator();
 				this.randomGenerator = LightningStrike.createRandomGenerator();
 				this.seedGenerator = Math;
 				this.seedGenerator = Math;
 
 
-			} // Ray creation callbacks
-
+			}
 
 
+			// Ray creation callbacks
 			if ( rayParameters.onDecideSubrayCreation !== undefined ) {
 			if ( rayParameters.onDecideSubrayCreation !== undefined ) {
 
 
 				this.onDecideSubrayCreation = rayParameters.onDecideSubrayCreation;
 				this.onDecideSubrayCreation = rayParameters.onDecideSubrayCreation;
@@ -267,22 +268,21 @@
 			} else {
 			} else {
 
 
 				this.createDefaultSubrayCreationCallbacks();
 				this.createDefaultSubrayCreationCallbacks();
-
 				if ( rayParameters.onSubrayCreation !== undefined ) {
 				if ( rayParameters.onSubrayCreation !== undefined ) {
 
 
 					this.onSubrayCreation = rayParameters.onSubrayCreation;
 					this.onSubrayCreation = rayParameters.onSubrayCreation;
 
 
 				}
 				}
 
 
-			} // Internal state
+			}
 
 
+			// Internal state
 
 
 			this.state = LightningStrike.RAY_INITIALIZED;
 			this.state = LightningStrike.RAY_INITIALIZED;
 			this.maxSubrays = Math.ceil( 1 + Math.pow( this.ramification, Math.max( 0, this.maxSubrayRecursion - 1 ) ) );
 			this.maxSubrays = Math.ceil( 1 + Math.pow( this.ramification, Math.max( 0, this.maxSubrayRecursion - 1 ) ) );
 			rayParameters.maxSubrays = this.maxSubrays;
 			rayParameters.maxSubrays = this.maxSubrays;
 			this.maxRaySegments = 2 * ( 1 << this.maxIterations );
 			this.maxRaySegments = 2 * ( 1 << this.maxIterations );
 			this.subrays = [];
 			this.subrays = [];
-
 			for ( let i = 0; i < this.maxSubrays; i ++ ) {
 			for ( let i = 0; i < this.maxSubrays; i ++ ) {
 
 
 				this.subrays.push( this.createSubray() );
 				this.subrays.push( this.createSubray() );
@@ -290,7 +290,6 @@
 			}
 			}
 
 
 			this.raySegments = [];
 			this.raySegments = [];
-
 			for ( let i = 0; i < this.maxRaySegments; i ++ ) {
 			for ( let i = 0; i < this.maxRaySegments; i ++ ) {
 
 
 				this.raySegments.push( this.createSegment() );
 				this.raySegments.push( this.createSegment() );
@@ -317,8 +316,9 @@
 			this.uvsAttribute = null;
 			this.uvsAttribute = null;
 			this.simplexX = new THREE.SimplexNoise( this.seedGenerator );
 			this.simplexX = new THREE.SimplexNoise( this.seedGenerator );
 			this.simplexY = new THREE.SimplexNoise( this.seedGenerator );
 			this.simplexY = new THREE.SimplexNoise( this.seedGenerator );
-			this.simplexZ = new THREE.SimplexNoise( this.seedGenerator ); // Temp vectors
+			this.simplexZ = new THREE.SimplexNoise( this.seedGenerator );
 
 
+			// Temp vectors
 			this.forwards = new THREE.Vector3();
 			this.forwards = new THREE.Vector3();
 			this.forwardsFill = new THREE.Vector3();
 			this.forwardsFill = new THREE.Vector3();
 			this.side = new THREE.Vector3();
 			this.side = new THREE.Vector3();
@@ -330,7 +330,6 @@
 			this.cross1 = new THREE.Vector3();
 			this.cross1 = new THREE.Vector3();
 
 
 		}
 		}
-
 		createMesh() {
 		createMesh() {
 
 
 			const maxDrawableSegmentsPerSubRay = 1 << this.maxIterations;
 			const maxDrawableSegmentsPerSubRay = 1 << this.maxIterations;
@@ -338,19 +337,17 @@
 			const maxIndices = 18 * maxDrawableSegmentsPerSubRay * this.maxSubrays;
 			const maxIndices = 18 * maxDrawableSegmentsPerSubRay * this.maxSubrays;
 			this.vertices = new Float32Array( maxVerts * 3 );
 			this.vertices = new Float32Array( maxVerts * 3 );
 			this.indices = new Uint32Array( maxIndices );
 			this.indices = new Uint32Array( maxIndices );
-
 			if ( this.generateUVs ) {
 			if ( this.generateUVs ) {
 
 
 				this.uvs = new Float32Array( maxVerts * 2 );
 				this.uvs = new Float32Array( maxVerts * 2 );
 
 
-			} // Populate the mesh
-
+			}
 
 
+			// Populate the mesh
 			this.fillMesh( 0 );
 			this.fillMesh( 0 );
 			this.setIndex( new THREE.Uint32BufferAttribute( this.indices, 1 ) );
 			this.setIndex( new THREE.Uint32BufferAttribute( this.indices, 1 ) );
 			this.positionAttribute = new THREE.Float32BufferAttribute( this.vertices, 3 );
 			this.positionAttribute = new THREE.Float32BufferAttribute( this.vertices, 3 );
 			this.setAttribute( 'position', this.positionAttribute );
 			this.setAttribute( 'position', this.positionAttribute );
-
 			if ( this.generateUVs ) {
 			if ( this.generateUVs ) {
 
 
 				this.uvsAttribute = new THREE.Float32BufferAttribute( new Float32Array( this.uvs ), 2 );
 				this.uvsAttribute = new THREE.Float32BufferAttribute( new Float32Array( this.uvs ), 2 );
@@ -362,19 +359,17 @@
 
 
 				this.index.usage = THREE.DynamicDrawUsage;
 				this.index.usage = THREE.DynamicDrawUsage;
 				this.positionAttribute.usage = THREE.DynamicDrawUsage;
 				this.positionAttribute.usage = THREE.DynamicDrawUsage;
-
 				if ( this.generateUVs ) {
 				if ( this.generateUVs ) {
 
 
 					this.uvsAttribute.usage = THREE.DynamicDrawUsage;
 					this.uvsAttribute.usage = THREE.DynamicDrawUsage;
 
 
 				}
 				}
 
 
-			} // Store buffers for later modification
-
+			}
 
 
+			// Store buffers for later modification
 			this.vertices = this.positionAttribute.array;
 			this.vertices = this.positionAttribute.array;
 			this.indices = this.index.array;
 			this.indices = this.index.array;
-
 			if ( this.generateUVs ) {
 			if ( this.generateUVs ) {
 
 
 				this.uvs = this.uvsAttribute.array;
 				this.uvs = this.uvsAttribute.array;
@@ -382,14 +377,12 @@
 			}
 			}
 
 
 		}
 		}
-
 		updateMesh( time ) {
 		updateMesh( time ) {
 
 
 			this.fillMesh( time );
 			this.fillMesh( time );
 			this.drawRange.count = this.currentIndex;
 			this.drawRange.count = this.currentIndex;
 			this.index.needsUpdate = true;
 			this.index.needsUpdate = true;
 			this.positionAttribute.needsUpdate = true;
 			this.positionAttribute.needsUpdate = true;
-
 			if ( this.generateUVs ) {
 			if ( this.generateUVs ) {
 
 
 				this.uvsAttribute.needsUpdate = true;
 				this.uvsAttribute.needsUpdate = true;
@@ -397,7 +390,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		fillMesh( time ) {
 		fillMesh( time ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -408,15 +400,16 @@
 			this.fractalRay( time, function fillVertices( segment ) {
 			this.fractalRay( time, function fillVertices( segment ) {
 
 
 				const subray = scope.currentSubray;
 				const subray = scope.currentSubray;
-
 				if ( time < subray.birthTime ) {
 				if ( time < subray.birthTime ) {
 
 
 					//&& ( ! this.rayParameters.isEternal || scope.currentSubray.recursion > 0 ) ) {
 					//&& ( ! this.rayParameters.isEternal || scope.currentSubray.recursion > 0 ) ) {
+
 					return;
 					return;
 
 
 				} else if ( this.rayParameters.isEternal && scope.currentSubray.recursion == 0 ) {
 				} else if ( this.rayParameters.isEternal && scope.currentSubray.recursion == 0 ) {
 
 
 					// Eternal rays don't propagate nor vanish, but its subrays do
 					// Eternal rays don't propagate nor vanish, but its subrays do
+
 					scope.createPrism( segment );
 					scope.createPrism( segment );
 					scope.onDecideSubrayCreation( segment, scope );
 					scope.onDecideSubrayCreation( segment, scope );
 
 
@@ -425,6 +418,7 @@
 					if ( scope.timeFraction >= segment.fraction0 * subray.propagationTimeFactor ) {
 					if ( scope.timeFraction >= segment.fraction0 * subray.propagationTimeFactor ) {
 
 
 						// Ray propagation has arrived to this segment
 						// Ray propagation has arrived to this segment
+
 						scope.createPrism( segment );
 						scope.createPrism( segment );
 						scope.onDecideSubrayCreation( segment, scope );
 						scope.onDecideSubrayCreation( segment, scope );
 
 
@@ -433,6 +427,7 @@
 				} else if ( time < subray.beginVanishingTime ) {
 				} else if ( time < subray.beginVanishingTime ) {
 
 
 					// Ray is steady (nor propagating nor vanishing)
 					// Ray is steady (nor propagating nor vanishing)
+
 					scope.createPrism( segment );
 					scope.createPrism( segment );
 					scope.onDecideSubrayCreation( segment, scope );
 					scope.onDecideSubrayCreation( segment, scope );
 
 
@@ -441,6 +436,7 @@
 					if ( scope.timeFraction <= subray.vanishingTimeFactor + segment.fraction1 * ( 1 - subray.vanishingTimeFactor ) ) {
 					if ( scope.timeFraction <= subray.vanishingTimeFactor + segment.fraction1 * ( 1 - subray.vanishingTimeFactor ) ) {
 
 
 						// Segment has not yet vanished
 						// Segment has not yet vanished
+
 						scope.createPrism( segment );
 						scope.createPrism( segment );
 
 
 					}
 					}
@@ -452,13 +448,11 @@
 			} );
 			} );
 
 
 		}
 		}
-
 		addNewSubray() {
 		addNewSubray() {
 
 
 			return this.subrays[ this.numSubrays ++ ];
 			return this.subrays[ this.numSubrays ++ ];
 
 
 		}
 		}
-
 		initSubray( subray, rayParameters ) {
 		initSubray( subray, rayParameters ) {
 
 
 			subray.pos0.copy( rayParameters.sourceOffset );
 			subray.pos0.copy( rayParameters.sourceOffset );
@@ -479,15 +473,16 @@
 			subray.recursion = 0;
 			subray.recursion = 0;
 
 
 		}
 		}
-
 		fractalRay( time, segmentCallback ) {
 		fractalRay( time, segmentCallback ) {
 
 
 			this.time = time;
 			this.time = time;
 			this.currentSegmentCallback = segmentCallback;
 			this.currentSegmentCallback = segmentCallback;
-			this.numSubrays = 0; // Add the top level subray
+			this.numSubrays = 0;
 
 
-			this.initSubray( this.addNewSubray(), this.rayParameters ); // Process all subrays that are being generated until consuming all of them
+			// Add the top level subray
+			this.initSubray( this.addNewSubray(), this.rayParameters );
 
 
+			// Process all subrays that are being generated until consuming all of them
 			for ( let subrayIndex = 0; subrayIndex < this.numSubrays; subrayIndex ++ ) {
 			for ( let subrayIndex = 0; subrayIndex < this.numSubrays; subrayIndex ++ ) {
 
 
 				const subray = this.subrays[ subrayIndex ];
 				const subray = this.subrays[ subrayIndex ];
@@ -523,7 +518,6 @@
 			this.currentSubray = null;
 			this.currentSubray = null;
 
 
 		}
 		}
-
 		fractalRayRecursive( segment ) {
 		fractalRayRecursive( segment ) {
 
 
 			// Leave recursion condition
 			// Leave recursion condition
@@ -532,12 +526,11 @@
 				this.currentSegmentCallback( segment );
 				this.currentSegmentCallback( segment );
 				return;
 				return;
 
 
-			} // Interpolation
-
+			}
 
 
+			// Interpolation
 			this.forwards.subVectors( segment.pos1, segment.pos0 );
 			this.forwards.subVectors( segment.pos1, segment.pos0 );
 			let lForwards = this.forwards.length();
 			let lForwards = this.forwards.length();
-
 			if ( lForwards < 0.000001 ) {
 			if ( lForwards < 0.000001 ) {
 
 
 				this.forwards.set( 0, 0, 0.01 );
 				this.forwards.set( 0, 0, 0.01 );
@@ -550,11 +543,14 @@
 			const timeDimension = this.time * this.currentSubray.timeScale * Math.pow( 2, segment.iteration );
 			const timeDimension = this.time * this.currentSubray.timeScale * Math.pow( 2, segment.iteration );
 			this.middlePos.lerpVectors( segment.pos0, segment.pos1, 0.5 );
 			this.middlePos.lerpVectors( segment.pos0, segment.pos1, 0.5 );
 			this.middleLinPos.lerpVectors( segment.linPos0, segment.linPos1, 0.5 );
 			this.middleLinPos.lerpVectors( segment.linPos0, segment.linPos1, 0.5 );
-			const p = this.middleLinPos; // Noise
+			const p = this.middleLinPos;
 
 
+			// Noise
 			this.newPos.set( this.simplexX.noise4d( p.x, p.y, p.z, timeDimension ), this.simplexY.noise4d( p.x, p.y, p.z, timeDimension ), this.simplexZ.noise4d( p.x, p.y, p.z, timeDimension ) );
 			this.newPos.set( this.simplexX.noise4d( p.x, p.y, p.z, timeDimension ), this.simplexY.noise4d( p.x, p.y, p.z, timeDimension ), this.simplexZ.noise4d( p.x, p.y, p.z, timeDimension ) );
 			this.newPos.multiplyScalar( segment.positionVariationFactor * lForwards );
 			this.newPos.multiplyScalar( segment.positionVariationFactor * lForwards );
-			this.newPos.add( this.middlePos ); // Recursion
+			this.newPos.add( this.middlePos );
+
+			// Recursion
 
 
 			const newSegment1 = this.getNewSegment();
 			const newSegment1 = this.getNewSegment();
 			newSegment1.pos0.copy( segment.pos0 );
 			newSegment1.pos0.copy( segment.pos0 );
@@ -587,12 +583,11 @@
 			this.fractalRayRecursive( newSegment2 );
 			this.fractalRayRecursive( newSegment2 );
 
 
 		}
 		}
-
 		createPrism( segment ) {
 		createPrism( segment ) {
 
 
 			// Creates one triangular prism and its vertices at the segment
 			// Creates one triangular prism and its vertices at the segment
-			this.forwardsFill.subVectors( segment.pos1, segment.pos0 ).normalize();
 
 
+			this.forwardsFill.subVectors( segment.pos1, segment.pos0 ).normalize();
 			if ( this.isInitialSegment ) {
 			if ( this.isInitialSegment ) {
 
 
 				this.currentCreateTriangleVertices( segment.pos0, segment.up0, this.forwardsFill, segment.radius0, 0 );
 				this.currentCreateTriangleVertices( segment.pos0, segment.up0, this.forwardsFill, segment.radius0, 0 );
@@ -604,10 +599,10 @@
 			this.createPrismFaces();
 			this.createPrismFaces();
 
 
 		}
 		}
-
 		createTriangleVerticesWithoutUVs( pos, up, forwards, radius ) {
 		createTriangleVerticesWithoutUVs( pos, up, forwards, radius ) {
 
 
 			// Create an equilateral triangle (only vertices)
 			// Create an equilateral triangle (only vertices)
+
 			this.side.crossVectors( up, forwards ).multiplyScalar( radius * LightningStrike.COS30DEG );
 			this.side.crossVectors( up, forwards ).multiplyScalar( radius * LightningStrike.COS30DEG );
 			this.down.copy( up ).multiplyScalar( - radius * LightningStrike.SIN30DEG );
 			this.down.copy( up ).multiplyScalar( - radius * LightningStrike.SIN30DEG );
 			const p = this.vPos;
 			const p = this.vPos;
@@ -627,10 +622,10 @@
 			this.currentVertex += 3;
 			this.currentVertex += 3;
 
 
 		}
 		}
-
 		createTriangleVerticesWithUVs( pos, up, forwards, radius, u ) {
 		createTriangleVerticesWithUVs( pos, up, forwards, radius, u ) {
 
 
 			// Create an equilateral triangle (only vertices)
 			// Create an equilateral triangle (only vertices)
+
 			this.side.crossVectors( up, forwards ).multiplyScalar( radius * LightningStrike.COS30DEG );
 			this.side.crossVectors( up, forwards ).multiplyScalar( radius * LightningStrike.COS30DEG );
 			this.down.copy( up ).multiplyScalar( - radius * LightningStrike.SIN30DEG );
 			this.down.copy( up ).multiplyScalar( - radius * LightningStrike.SIN30DEG );
 			const p = this.vPos;
 			const p = this.vPos;
@@ -657,10 +652,7 @@
 			this.currentVertex += 3;
 			this.currentVertex += 3;
 
 
 		}
 		}
-
-		createPrismFaces( vertex
-			/*, index*/
-		) {
+		createPrismFaces( vertex /*, index*/ ) {
 
 
 			const indices = this.indices;
 			const indices = this.indices;
 			vertex = this.currentVertex - 6;
 			vertex = this.currentVertex - 6;
@@ -684,14 +676,13 @@
 			indices[ this.currentIndex ++ ] = vertex + 5;
 			indices[ this.currentIndex ++ ] = vertex + 5;
 
 
 		}
 		}
-
 		createDefaultSubrayCreationCallbacks() {
 		createDefaultSubrayCreationCallbacks() {
 
 
 			const random1 = this.randomGenerator.random;
 			const random1 = this.randomGenerator.random;
-
 			this.onDecideSubrayCreation = function ( segment, lightningStrike ) {
 			this.onDecideSubrayCreation = function ( segment, lightningStrike ) {
 
 
 				// Decide subrays creation at parent (sub)ray segment
 				// Decide subrays creation at parent (sub)ray segment
+
 				const subray = lightningStrike.currentSubray;
 				const subray = lightningStrike.currentSubray;
 				const period = lightningStrike.rayParameters.subrayPeriod;
 				const period = lightningStrike.rayParameters.subrayPeriod;
 				const dutyCycle = lightningStrike.rayParameters.subrayDutyCycle;
 				const dutyCycle = lightningStrike.rayParameters.subrayDutyCycle;
@@ -701,10 +692,10 @@
 				const childSubraySeed = random1() * ( currentCycle + 1 );
 				const childSubraySeed = random1() * ( currentCycle + 1 );
 				const isActive = phase % period <= dutyCycle * period;
 				const isActive = phase % period <= dutyCycle * period;
 				let probability = 0;
 				let probability = 0;
-
 				if ( isActive ) {
 				if ( isActive ) {
 
 
-					probability = lightningStrike.subrayProbability; // Distribution test: probability *= segment.fraction0 > 0.5 && segment.fraction0 < 0.9 ? 1 / 0.4 : 0;
+					probability = lightningStrike.subrayProbability;
+					// Distribution test: probability *= segment.fraction0 > 0.5 && segment.fraction0 < 0.9 ? 1 / 0.4 : 0;
 
 
 				}
 				}
 
 
@@ -724,7 +715,6 @@
 					childSubray.radius1 = Math.min( lightningStrike.rayParameters.minRadius, segment.radius1 * lightningStrike.rayParameters.radius1Factor );
 					childSubray.radius1 = Math.min( lightningStrike.rayParameters.minRadius, segment.radius1 * lightningStrike.rayParameters.radius1Factor );
 					childSubray.birthTime = phase0 + currentCycle * period;
 					childSubray.birthTime = phase0 + currentCycle * period;
 					childSubray.deathTime = childSubray.birthTime + period * dutyCycle;
 					childSubray.deathTime = childSubray.birthTime + period * dutyCycle;
-
 					if ( ! lightningStrike.rayParameters.isEternal && subray.recursion == 0 ) {
 					if ( ! lightningStrike.rayParameters.isEternal && subray.recursion == 0 ) {
 
 
 						childSubray.birthTime = Math.max( childSubray.birthTime, subray.birthTime );
 						childSubray.birthTime = Math.max( childSubray.birthTime, subray.birthTime );
@@ -748,10 +738,10 @@
 			const vec2Forward = new THREE.Vector3();
 			const vec2Forward = new THREE.Vector3();
 			const vec3Side = new THREE.Vector3();
 			const vec3Side = new THREE.Vector3();
 			const vec4Up = new THREE.Vector3();
 			const vec4Up = new THREE.Vector3();
-
 			this.onSubrayCreation = function ( segment, parentSubray, childSubray, lightningStrike ) {
 			this.onSubrayCreation = function ( segment, parentSubray, childSubray, lightningStrike ) {
 
 
 				// Decide childSubray origin and destination positions (pos0 and pos1) and possibly other properties of childSubray
 				// Decide childSubray origin and destination positions (pos0 and pos1) and possibly other properties of childSubray
+
 				// Just use the default cone position generator
 				// Just use the default cone position generator
 				lightningStrike.subrayCylinderPosition( segment, parentSubray, childSubray, 0.5, 0.6, 0.2 );
 				lightningStrike.subrayCylinderPosition( segment, parentSubray, childSubray, 0.5, 0.6, 0.2 );
 
 
@@ -760,6 +750,7 @@
 			this.subrayConePosition = function ( segment, parentSubray, childSubray, heightFactor, sideWidthFactor, minSideWidthFactor ) {
 			this.subrayConePosition = function ( segment, parentSubray, childSubray, heightFactor, sideWidthFactor, minSideWidthFactor ) {
 
 
 				// Sets childSubray pos0 and pos1 in a cone
 				// Sets childSubray pos0 and pos1 in a cone
+
 				childSubray.pos0.copy( segment.pos0 );
 				childSubray.pos0.copy( segment.pos0 );
 				vec1Pos.subVectors( parentSubray.pos1, parentSubray.pos0 );
 				vec1Pos.subVectors( parentSubray.pos1, parentSubray.pos0 );
 				vec2Forward.copy( vec1Pos ).normalize();
 				vec2Forward.copy( vec1Pos ).normalize();
@@ -776,6 +767,7 @@
 			this.subrayCylinderPosition = function ( segment, parentSubray, childSubray, heightFactor, sideWidthFactor, minSideWidthFactor ) {
 			this.subrayCylinderPosition = function ( segment, parentSubray, childSubray, heightFactor, sideWidthFactor, minSideWidthFactor ) {
 
 
 				// Sets childSubray pos0 and pos1 in a cylinder
 				// Sets childSubray pos0 and pos1 in a cylinder
+
 				childSubray.pos0.copy( segment.pos0 );
 				childSubray.pos0.copy( segment.pos0 );
 				vec1Pos.subVectors( parentSubray.pos1, parentSubray.pos0 );
 				vec1Pos.subVectors( parentSubray.pos1, parentSubray.pos0 );
 				vec2Forward.copy( vec1Pos ).normalize();
 				vec2Forward.copy( vec1Pos ).normalize();
@@ -790,7 +782,6 @@
 			};
 			};
 
 
 		}
 		}
-
 		createSubray() {
 		createSubray() {
 
 
 			return {
 			return {
@@ -817,7 +808,6 @@
 			};
 			};
 
 
 		}
 		}
-
 		createSegment() {
 		createSegment() {
 
 
 			return {
 			return {
@@ -836,13 +826,11 @@
 			};
 			};
 
 
 		}
 		}
-
 		getNewSegment() {
 		getNewSegment() {
 
 
 			return this.raySegments[ this.currentSegmentIndex ++ ];
 			return this.raySegments[ this.currentSegmentIndex ++ ];
 
 
 		}
 		}
-
 		copy( source ) {
 		copy( source ) {
 
 
 			super.copy( source );
 			super.copy( source );
@@ -850,16 +838,15 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		clone() {
 		clone() {
 
 
 			return new this.constructor( LightningStrike.copyParameters( {}, this.rayParameters ) );
 			return new this.constructor( LightningStrike.copyParameters( {}, this.rayParameters ) );
 
 
 		}
 		}
 
 
-	} // Ray states
-
+	}
 
 
+	// Ray states
 	LightningStrike.RAY_INITIALIZED = 0;
 	LightningStrike.RAY_INITIALIZED = 0;
 	LightningStrike.RAY_UNBORN = 1;
 	LightningStrike.RAY_UNBORN = 1;
 	LightningStrike.RAY_PROPAGATING = 2;
 	LightningStrike.RAY_PROPAGATING = 2;

+ 8 - 7
examples/js/geometries/ParametricGeometries.js

@@ -11,7 +11,6 @@
 			v *= 2 * Math.PI;
 			v *= 2 * Math.PI;
 			u = u * 2;
 			u = u * 2;
 			let x, z;
 			let x, z;
-
 			if ( u < Math.PI ) {
 			if ( u < Math.PI ) {
 
 
 				x = 3 * Math.cos( u ) * ( 1 + Math.sin( u ) ) + 2 * ( 1 - Math.cos( u ) / 2 ) * Math.cos( u ) * Math.cos( v );
 				x = 3 * Math.cos( u ) * ( 1 + Math.sin( u ) ) + 2 * ( 1 - Math.cos( u ) / 2 ) * Math.cos( u ) * Math.cos( v );
@@ -56,6 +55,7 @@
 		mobius3d: function ( u, t, target ) {
 		mobius3d: function ( u, t, target ) {
 
 
 			// volumetric mobius strip
 			// volumetric mobius strip
+
 			u *= Math.PI;
 			u *= Math.PI;
 			t *= 2 * Math.PI;
 			t *= 2 * Math.PI;
 			u = u * 2;
 			u = u * 2;
@@ -71,6 +71,7 @@
 
 
 		}
 		}
 	};
 	};
+
 	/*********************************************
 	/*********************************************
  *
  *
  * Parametric Replacement for TubeGeometry
  * Parametric Replacement for TubeGeometry
@@ -87,7 +88,6 @@
 				normals = frames.normals,
 				normals = frames.normals,
 				binormals = frames.binormals;
 				binormals = frames.binormals;
 			const position = new THREE.Vector3();
 			const position = new THREE.Vector3();
-
 			function ParametricTube( u, v, target ) {
 			function ParametricTube( u, v, target ) {
 
 
 				v *= 2 * Math.PI;
 				v *= 2 * Math.PI;
@@ -96,7 +96,6 @@
 				const normal = normals[ i ];
 				const normal = normals[ i ];
 				const binormal = binormals[ i ];
 				const binormal = binormals[ i ];
 				const cx = - radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
 				const cx = - radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
-
 				const cy = radius * Math.sin( v );
 				const cy = radius * Math.sin( v );
 				position.x += cx * normal.x + cy * binormal.x;
 				position.x += cx * normal.x + cy * binormal.x;
 				position.y += cx * normal.y + cy * binormal.y;
 				position.y += cx * normal.y + cy * binormal.y;
@@ -105,7 +104,9 @@
 
 
 			}
 			}
 
 
-			super( ParametricTube, segments, segmentsRadius ); // proxy internals
+			super( ParametricTube, segments, segmentsRadius );
+
+			// proxy internals
 
 
 			this.tangents = tangents;
 			this.tangents = tangents;
 			this.normals = normals;
 			this.normals = normals;
@@ -119,12 +120,12 @@
 		}
 		}
 
 
 	};
 	};
+
 	/*********************************************
 	/*********************************************
   *
   *
   * Parametric Replacement for TorusKnotGeometry
   * Parametric Replacement for TorusKnotGeometry
   *
   *
   *********************************************/
   *********************************************/
-
 	ParametricGeometries.TorusKnotGeometry = class TorusKnotGeometry extends ParametricGeometries.TubeGeometry {
 	ParametricGeometries.TorusKnotGeometry = class TorusKnotGeometry extends ParametricGeometries.TubeGeometry {
 
 
 		constructor( radius = 200, tube = 40, segmentsT = 64, segmentsR = 8, p = 2, q = 3 ) {
 		constructor( radius = 200, tube = 40, segmentsT = 64, segmentsR = 8, p = 2, q = 3 ) {
@@ -144,7 +145,6 @@
 				}
 				}
 
 
 			}
 			}
-
 			const segments = segmentsT;
 			const segments = segmentsT;
 			const radiusSegments = segmentsR;
 			const radiusSegments = segmentsR;
 			const extrudePath = new TorusKnotCurve();
 			const extrudePath = new TorusKnotCurve();
@@ -159,12 +159,12 @@
 		}
 		}
 
 
 	};
 	};
+
 	/*********************************************
 	/*********************************************
   *
   *
   * Parametric Replacement for SphereGeometry
   * Parametric Replacement for SphereGeometry
   *
   *
   *********************************************/
   *********************************************/
-
 	ParametricGeometries.SphereGeometry = class SphereGeometry extends THREE.ParametricGeometry {
 	ParametricGeometries.SphereGeometry = class SphereGeometry extends THREE.ParametricGeometry {
 
 
 		constructor( size, u, v ) {
 		constructor( size, u, v ) {
@@ -185,6 +185,7 @@
 		}
 		}
 
 
 	};
 	};
+
 	/*********************************************
 	/*********************************************
   *
   *
   * Parametric Replacement for PlaneGeometry
   * Parametric Replacement for PlaneGeometry

+ 25 - 12
examples/js/geometries/ParametricGeometry.js

@@ -4,7 +4,6 @@
  * Parametric Surfaces Geometry
  * Parametric Surfaces Geometry
  * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html
  * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html
  */
  */
-
 	class ParametricGeometry extends THREE.BufferGeometry {
 	class ParametricGeometry extends THREE.BufferGeometry {
 
 
 		constructor( func = ( u, v, target ) => target.set( u, v, Math.cos( u ) * Math.sin( v ) ), slices = 8, stacks = 8 ) {
 		constructor( func = ( u, v, target ) => target.set( u, v, Math.cos( u ) * Math.sin( v ) ), slices = 8, stacks = 8 ) {
@@ -15,7 +14,9 @@
 				func: func,
 				func: func,
 				slices: slices,
 				slices: slices,
 				stacks: stacks
 				stacks: stacks
-			}; // buffers
+			};
+
+			// buffers
 
 
 			const indices = [];
 			const indices = [];
 			const vertices = [];
 			const vertices = [];
@@ -26,20 +27,25 @@
 			const p0 = new THREE.Vector3(),
 			const p0 = new THREE.Vector3(),
 				p1 = new THREE.Vector3();
 				p1 = new THREE.Vector3();
 			const pu = new THREE.Vector3(),
 			const pu = new THREE.Vector3(),
-				pv = new THREE.Vector3(); // generate vertices, normals and uvs
+				pv = new THREE.Vector3();
 
 
-			const sliceCount = slices + 1;
+			// generate vertices, normals and uvs
 
 
+			const sliceCount = slices + 1;
 			for ( let i = 0; i <= stacks; i ++ ) {
 			for ( let i = 0; i <= stacks; i ++ ) {
 
 
 				const v = i / stacks;
 				const v = i / stacks;
-
 				for ( let j = 0; j <= slices; j ++ ) {
 				for ( let j = 0; j <= slices; j ++ ) {
 
 
-					const u = j / slices; // vertex
+					const u = j / slices;
+
+					// vertex
 
 
 					func( u, v, p0 );
 					func( u, v, p0 );
-					vertices.push( p0.x, p0.y, p0.z ); // normal
+					vertices.push( p0.x, p0.y, p0.z );
+
+					// normal
+
 					// approximate tangent vectors via finite differences
 					// approximate tangent vectors via finite differences
 
 
 					if ( u - EPS >= 0 ) {
 					if ( u - EPS >= 0 ) {
@@ -64,18 +70,22 @@
 						func( u, v + EPS, p1 );
 						func( u, v + EPS, p1 );
 						pv.subVectors( p1, p0 );
 						pv.subVectors( p1, p0 );
 
 
-					} // cross product of tangent vectors returns surface normal
+					}
 
 
+					// cross product of tangent vectors returns surface normal
 
 
 					normal.crossVectors( pu, pv ).normalize();
 					normal.crossVectors( pu, pv ).normalize();
-					normals.push( normal.x, normal.y, normal.z ); // uv
+					normals.push( normal.x, normal.y, normal.z );
+
+					// uv
 
 
 					uvs.push( u, v );
 					uvs.push( u, v );
 
 
 				}
 				}
 
 
-			} // generate indices
+			}
 
 
+			// generate indices
 
 
 			for ( let i = 0; i < stacks; i ++ ) {
 			for ( let i = 0; i < stacks; i ++ ) {
 
 
@@ -84,15 +94,18 @@
 					const a = i * sliceCount + j;
 					const a = i * sliceCount + j;
 					const b = i * sliceCount + j + 1;
 					const b = i * sliceCount + j + 1;
 					const c = ( i + 1 ) * sliceCount + j + 1;
 					const c = ( i + 1 ) * sliceCount + j + 1;
-					const d = ( i + 1 ) * sliceCount + j; // faces one and two
+					const d = ( i + 1 ) * sliceCount + j;
+
+					// faces one and two
 
 
 					indices.push( a, b, d );
 					indices.push( a, b, d );
 					indices.push( b, c, d );
 					indices.push( b, c, d );
 
 
 				}
 				}
 
 
-			} // build geometry
+			}
 
 
+			// build geometry
 
 
 			this.setIndex( indices );
 			this.setIndex( indices );
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );

+ 21 - 19
examples/js/geometries/RoundedBoxGeometry.js

@@ -1,25 +1,24 @@
 ( function () {
 ( function () {
 
 
 	const _tempNormal = new THREE.Vector3();
 	const _tempNormal = new THREE.Vector3();
-
 	function getUv( faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength ) {
 	function getUv( faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength ) {
 
 
-		const totArcLength = 2 * Math.PI * radius / 4; // length of the planes between the arcs on each axis
+		const totArcLength = 2 * Math.PI * radius / 4;
 
 
+		// length of the planes between the arcs on each axis
 		const centerLength = Math.max( sideLength - 2 * radius, 0 );
 		const centerLength = Math.max( sideLength - 2 * radius, 0 );
-		const halfArc = Math.PI / 4; // Get the vector projected onto the Y plane
+		const halfArc = Math.PI / 4;
 
 
+		// Get the vector projected onto the Y plane
 		_tempNormal.copy( normal );
 		_tempNormal.copy( normal );
-
 		_tempNormal[ projectionAxis ] = 0;
 		_tempNormal[ projectionAxis ] = 0;
+		_tempNormal.normalize();
 
 
-		_tempNormal.normalize(); // total amount of UV space alloted to a single arc
-
-
-		const arcUvRatio = 0.5 * totArcLength / ( totArcLength + centerLength ); // the distance along one arc the point is at
+		// total amount of UV space alloted to a single arc
+		const arcUvRatio = 0.5 * totArcLength / ( totArcLength + centerLength );
 
 
+		// the distance along one arc the point is at
 		const arcAngleRatio = 1.0 - _tempNormal.angleTo( faceDirVector ) / halfArc;
 		const arcAngleRatio = 1.0 - _tempNormal.angleTo( faceDirVector ) / halfArc;
-
 		if ( Math.sign( _tempNormal[ uvAxis ] ) === 1 ) {
 		if ( Math.sign( _tempNormal[ uvAxis ] ) === 1 ) {
 
 
 			return arcAngleRatio * arcUvRatio;
 			return arcAngleRatio * arcUvRatio;
@@ -39,17 +38,21 @@
 		constructor( width = 1, height = 1, depth = 1, segments = 2, radius = 0.1 ) {
 		constructor( width = 1, height = 1, depth = 1, segments = 2, radius = 0.1 ) {
 
 
 			// ensure segments is odd so we have a plane connecting the rounded corners
 			// ensure segments is odd so we have a plane connecting the rounded corners
-			segments = segments * 2 + 1; // ensure radius isn't bigger than shortest side
+			segments = segments * 2 + 1;
 
 
+			// ensure radius isn't bigger than shortest side
 			radius = Math.min( width / 2, height / 2, depth / 2, radius );
 			radius = Math.min( width / 2, height / 2, depth / 2, radius );
-			super( 1, 1, 1, segments, segments, segments ); // if we just have one segment we're the same as a regular box
+			super( 1, 1, 1, segments, segments, segments );
 
 
+			// if we just have one segment we're the same as a regular box
 			if ( segments === 1 ) return;
 			if ( segments === 1 ) return;
 			const geometry2 = this.toNonIndexed();
 			const geometry2 = this.toNonIndexed();
 			this.index = null;
 			this.index = null;
 			this.attributes.position = geometry2.attributes.position;
 			this.attributes.position = geometry2.attributes.position;
 			this.attributes.normal = geometry2.attributes.normal;
 			this.attributes.normal = geometry2.attributes.normal;
-			this.attributes.uv = geometry2.attributes.uv; //
+			this.attributes.uv = geometry2.attributes.uv;
+
+			//
 
 
 			const position = new THREE.Vector3();
 			const position = new THREE.Vector3();
 			const normal = new THREE.Vector3();
 			const normal = new THREE.Vector3();
@@ -60,7 +63,6 @@
 			const faceTris = positions.length / 6;
 			const faceTris = positions.length / 6;
 			const faceDirVector = new THREE.Vector3();
 			const faceDirVector = new THREE.Vector3();
 			const halfSegmentSize = 0.5 / segments;
 			const halfSegmentSize = 0.5 / segments;
-
 			for ( let i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
 			for ( let i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
 
 
 				position.fromArray( positions, i );
 				position.fromArray( positions, i );
@@ -76,51 +78,51 @@
 				normals[ i + 1 ] = normal.y;
 				normals[ i + 1 ] = normal.y;
 				normals[ i + 2 ] = normal.z;
 				normals[ i + 2 ] = normal.z;
 				const side = Math.floor( i / faceTris );
 				const side = Math.floor( i / faceTris );
-
 				switch ( side ) {
 				switch ( side ) {
 
 
 					case 0:
 					case 0:
 						// right
 						// right
+
 						// generate UVs along Z then Y
 						// generate UVs along Z then Y
 						faceDirVector.set( 1, 0, 0 );
 						faceDirVector.set( 1, 0, 0 );
 						uvs[ j + 0 ] = getUv( faceDirVector, normal, 'z', 'y', radius, depth );
 						uvs[ j + 0 ] = getUv( faceDirVector, normal, 'z', 'y', radius, depth );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
 						break;
 						break;
-
 					case 1:
 					case 1:
 						// left
 						// left
+
 						// generate UVs along Z then Y
 						// generate UVs along Z then Y
 						faceDirVector.set( - 1, 0, 0 );
 						faceDirVector.set( - 1, 0, 0 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'y', radius, depth );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'y', radius, depth );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
 						break;
 						break;
-
 					case 2:
 					case 2:
 						// top
 						// top
+
 						// generate UVs along X then Z
 						// generate UVs along X then Z
 						faceDirVector.set( 0, 1, 0 );
 						faceDirVector.set( 0, 1, 0 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
 						uvs[ j + 1 ] = getUv( faceDirVector, normal, 'z', 'x', radius, depth );
 						uvs[ j + 1 ] = getUv( faceDirVector, normal, 'z', 'x', radius, depth );
 						break;
 						break;
-
 					case 3:
 					case 3:
 						// bottom
 						// bottom
+
 						// generate UVs along X then Z
 						// generate UVs along X then Z
 						faceDirVector.set( 0, - 1, 0 );
 						faceDirVector.set( 0, - 1, 0 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'x', radius, depth );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'x', radius, depth );
 						break;
 						break;
-
 					case 4:
 					case 4:
 						// front
 						// front
+
 						// generate UVs along X then Y
 						// generate UVs along X then Y
 						faceDirVector.set( 0, 0, 1 );
 						faceDirVector.set( 0, 0, 1 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'y', radius, width );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'y', radius, width );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height );
 						break;
 						break;
-
 					case 5:
 					case 5:
 						// back
 						// back
+
 						// generate UVs along X then Y
 						// generate UVs along X then Y
 						faceDirVector.set( 0, 0, - 1 );
 						faceDirVector.set( 0, 0, - 1 );
 						uvs[ j + 0 ] = getUv( faceDirVector, normal, 'x', 'y', radius, width );
 						uvs[ j + 0 ] = getUv( faceDirVector, normal, 'x', 'y', radius, width );

文件差異過大導致無法顯示
+ 6 - 12
examples/js/geometries/TeapotGeometry.js


+ 6 - 4
examples/js/geometries/TextGeometry.js

@@ -16,22 +16,24 @@
  *  bevelOffset: <float> // how far from text outline does bevel start
  *  bevelOffset: <float> // how far from text outline does bevel start
  * }
  * }
  */
  */
-
 	class TextGeometry extends THREE.ExtrudeGeometry {
 	class TextGeometry extends THREE.ExtrudeGeometry {
 
 
 		constructor( text, parameters = {} ) {
 		constructor( text, parameters = {} ) {
 
 
 			const font = parameters.font;
 			const font = parameters.font;
-
 			if ( font === undefined ) {
 			if ( font === undefined ) {
 
 
 				super(); // generate default extrude geometry
 				super(); // generate default extrude geometry
 
 
 			} else {
 			} else {
 
 
-				const shapes = font.generateShapes( text, parameters.size ); // translate parameters to THREE.ExtrudeGeometry API
+				const shapes = font.generateShapes( text, parameters.size );
+
+				// translate parameters to THREE.ExtrudeGeometry API
+
+				parameters.depth = parameters.height !== undefined ? parameters.height : 50;
 
 
-				parameters.depth = parameters.height !== undefined ? parameters.height : 50; // defaults
+				// defaults
 
 
 				if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
 				if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
 				if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
 				if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;

+ 1 - 2
examples/js/helpers/LightProbeHelper.js

@@ -11,6 +11,7 @@
 						value: lightProbe.sh.coefficients
 						value: lightProbe.sh.coefficients
 					},
 					},
 					// by reference
 					// by reference
+
 					intensity: {
 					intensity: {
 						value: lightProbe.intensity
 						value: lightProbe.intensity
 					}
 					}
@@ -26,14 +27,12 @@
 			this.onBeforeRender();
 			this.onBeforeRender();
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.geometry.dispose();
 			this.geometry.dispose();
 			this.material.dispose();
 			this.material.dispose();
 
 
 		}
 		}
-
 		onBeforeRender() {
 		onBeforeRender() {
 
 
 			this.position.copy( this.lightProbe.position );
 			this.position.copy( this.lightProbe.position );

+ 0 - 12
examples/js/helpers/OctreeHelper.js

@@ -14,11 +14,9 @@
 			this.update();
 			this.update();
 
 
 		}
 		}
-
 		update() {
 		update() {
 
 
 			const vertices = [];
 			const vertices = [];
-
 			function traverse( tree ) {
 			function traverse( tree ) {
 
 
 				for ( let i = 0; i < tree.length; i ++ ) {
 				for ( let i = 0; i < tree.length; i ++ ) {
@@ -27,37 +25,28 @@
 					const max = tree[ i ].box.max;
 					const max = tree[ i ].box.max;
 					vertices.push( max.x, max.y, max.z );
 					vertices.push( max.x, max.y, max.z );
 					vertices.push( min.x, max.y, max.z ); // 0, 1
 					vertices.push( min.x, max.y, max.z ); // 0, 1
-
 					vertices.push( min.x, max.y, max.z );
 					vertices.push( min.x, max.y, max.z );
 					vertices.push( min.x, min.y, max.z ); // 1, 2
 					vertices.push( min.x, min.y, max.z ); // 1, 2
-
 					vertices.push( min.x, min.y, max.z );
 					vertices.push( min.x, min.y, max.z );
 					vertices.push( max.x, min.y, max.z ); // 2, 3
 					vertices.push( max.x, min.y, max.z ); // 2, 3
-
 					vertices.push( max.x, min.y, max.z );
 					vertices.push( max.x, min.y, max.z );
 					vertices.push( max.x, max.y, max.z ); // 3, 0
 					vertices.push( max.x, max.y, max.z ); // 3, 0
 
 
 					vertices.push( max.x, max.y, min.z );
 					vertices.push( max.x, max.y, min.z );
 					vertices.push( min.x, max.y, min.z ); // 4, 5
 					vertices.push( min.x, max.y, min.z ); // 4, 5
-
 					vertices.push( min.x, max.y, min.z );
 					vertices.push( min.x, max.y, min.z );
 					vertices.push( min.x, min.y, min.z ); // 5, 6
 					vertices.push( min.x, min.y, min.z ); // 5, 6
-
 					vertices.push( min.x, min.y, min.z );
 					vertices.push( min.x, min.y, min.z );
 					vertices.push( max.x, min.y, min.z ); // 6, 7
 					vertices.push( max.x, min.y, min.z ); // 6, 7
-
 					vertices.push( max.x, min.y, min.z );
 					vertices.push( max.x, min.y, min.z );
 					vertices.push( max.x, max.y, min.z ); // 7, 4
 					vertices.push( max.x, max.y, min.z ); // 7, 4
 
 
 					vertices.push( max.x, max.y, max.z );
 					vertices.push( max.x, max.y, max.z );
 					vertices.push( max.x, max.y, min.z ); // 0, 4
 					vertices.push( max.x, max.y, min.z ); // 0, 4
-
 					vertices.push( min.x, max.y, max.z );
 					vertices.push( min.x, max.y, max.z );
 					vertices.push( min.x, max.y, min.z ); // 1, 5
 					vertices.push( min.x, max.y, min.z ); // 1, 5
-
 					vertices.push( min.x, min.y, max.z );
 					vertices.push( min.x, min.y, max.z );
 					vertices.push( min.x, min.y, min.z ); // 2, 6
 					vertices.push( min.x, min.y, min.z ); // 2, 6
-
 					vertices.push( max.x, min.y, max.z );
 					vertices.push( max.x, min.y, max.z );
 					vertices.push( max.x, min.y, min.z ); // 3, 7
 					vertices.push( max.x, min.y, min.z ); // 3, 7
 
 
@@ -73,7 +62,6 @@
 			this.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 			this.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.geometry.dispose();
 			this.geometry.dispose();

+ 8 - 6
examples/js/helpers/PositionalAudioHelper.js

@@ -23,7 +23,6 @@
 			this.update();
 			this.update();
 
 
 		}
 		}
-
 		update() {
 		update() {
 
 
 			const audio = this.audio;
 			const audio = this.audio;
@@ -40,14 +39,15 @@
 			let stride;
 			let stride;
 			const geometry = this.geometry;
 			const geometry = this.geometry;
 			const positionAttribute = geometry.attributes.position;
 			const positionAttribute = geometry.attributes.position;
-			geometry.clearGroups(); //
+			geometry.clearGroups();
+
+			//
 
 
 			function generateSegment( from, to, divisions, materialIndex ) {
 			function generateSegment( from, to, divisions, materialIndex ) {
 
 
 				const step = ( to - from ) / divisions;
 				const step = ( to - from ) / divisions;
 				positionAttribute.setXYZ( start, 0, 0, 0 );
 				positionAttribute.setXYZ( start, 0, 0, 0 );
 				count ++;
 				count ++;
-
 				for ( i = from; i < to; i += step ) {
 				for ( i = from; i < to; i += step ) {
 
 
 					stride = start + count;
 					stride = start + count;
@@ -62,18 +62,20 @@
 				start += count;
 				start += count;
 				count = 0;
 				count = 0;
 
 
-			} //
+			}
 
 
+			//
 
 
 			generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 );
 			generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 );
 			generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 );
 			generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 );
-			generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 ); //
+			generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 );
+
+			//
 
 
 			positionAttribute.needsUpdate = true;
 			positionAttribute.needsUpdate = true;
 			if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false;
 			if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false;
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.geometry.dispose();
 			this.geometry.dispose();

+ 6 - 7
examples/js/helpers/RectAreaLightHelper.js

@@ -18,8 +18,9 @@
 			super( geometry, material );
 			super( geometry, material );
 			this.light = light;
 			this.light = light;
 			this.color = color; // optional hardwired color for the helper
 			this.color = color; // optional hardwired color for the helper
+			this.type = 'RectAreaLightHelper';
 
 
-			this.type = 'RectAreaLightHelper'; //
+			//
 
 
 			const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
 			const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
 			const geometry2 = new THREE.BufferGeometry();
 			const geometry2 = new THREE.BufferGeometry();
@@ -31,11 +32,9 @@
 			} ) ) );
 			} ) ) );
 
 
 		}
 		}
-
 		updateMatrixWorld() {
 		updateMatrixWorld() {
 
 
 			this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 );
 			this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 );
-
 			if ( this.color !== undefined ) {
 			if ( this.color !== undefined ) {
 
 
 				this.material.color.set( this.color );
 				this.material.color.set( this.color );
@@ -43,21 +42,21 @@
 
 
 			} else {
 			} else {
 
 
-				this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); // prevent hue shift
+				this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
 
 
+				// prevent hue shift
 				const c = this.material.color;
 				const c = this.material.color;
 				const max = Math.max( c.r, c.g, c.b );
 				const max = Math.max( c.r, c.g, c.b );
 				if ( max > 1 ) c.multiplyScalar( 1 / max );
 				if ( max > 1 ) c.multiplyScalar( 1 / max );
 				this.children[ 0 ].material.color.copy( this.material.color );
 				this.children[ 0 ].material.color.copy( this.material.color );
 
 
-			} // ignore world scale on light
-
+			}
 
 
+			// ignore world scale on light
 			this.matrixWorld.extractRotation( this.light.matrixWorld ).scale( this.scale ).copyPosition( this.light.matrixWorld );
 			this.matrixWorld.extractRotation( this.light.matrixWorld ).scale( this.scale ).copyPosition( this.light.matrixWorld );
 			this.children[ 0 ].matrixWorld.copy( this.matrixWorld );
 			this.children[ 0 ].matrixWorld.copy( this.matrixWorld );
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.geometry.dispose();
 			this.geometry.dispose();

+ 9 - 14
examples/js/helpers/VertexNormalsHelper.js

@@ -1,11 +1,8 @@
 ( function () {
 ( function () {
 
 
 	const _v1 = new THREE.Vector3();
 	const _v1 = new THREE.Vector3();
-
 	const _v2 = new THREE.Vector3();
 	const _v2 = new THREE.Vector3();
-
 	const _normalMatrix = new THREE.Matrix3();
 	const _normalMatrix = new THREE.Matrix3();
-
 	class VertexNormalsHelper extends THREE.LineSegments {
 	class VertexNormalsHelper extends THREE.LineSegments {
 
 
 		constructor( object, size = 1, color = 0xff0000 ) {
 		constructor( object, size = 1, color = 0xff0000 ) {
@@ -20,38 +17,37 @@
 			} ) );
 			} ) );
 			this.object = object;
 			this.object = object;
 			this.size = size;
 			this.size = size;
-			this.type = 'VertexNormalsHelper'; //
+			this.type = 'VertexNormalsHelper';
+
+			//
 
 
 			this.matrixAutoUpdate = false;
 			this.matrixAutoUpdate = false;
 			this.update();
 			this.update();
 
 
 		}
 		}
-
 		update() {
 		update() {
 
 
 			this.object.updateMatrixWorld( true );
 			this.object.updateMatrixWorld( true );
-
 			_normalMatrix.getNormalMatrix( this.object.matrixWorld );
 			_normalMatrix.getNormalMatrix( this.object.matrixWorld );
-
 			const matrixWorld = this.object.matrixWorld;
 			const matrixWorld = this.object.matrixWorld;
-			const position = this.geometry.attributes.position; //
+			const position = this.geometry.attributes.position;
 
 
-			const objGeometry = this.object.geometry;
+			//
 
 
+			const objGeometry = this.object.geometry;
 			if ( objGeometry ) {
 			if ( objGeometry ) {
 
 
 				const objPos = objGeometry.attributes.position;
 				const objPos = objGeometry.attributes.position;
 				const objNorm = objGeometry.attributes.normal;
 				const objNorm = objGeometry.attributes.normal;
-				let idx = 0; // for simplicity, ignore index and drawcalls, and render every normal
+				let idx = 0;
+
+				// for simplicity, ignore index and drawcalls, and render every normal
 
 
 				for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
 				for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
 
 
 					_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
 					_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
-
 					_v2.fromBufferAttribute( objNorm, j );
 					_v2.fromBufferAttribute( objNorm, j );
-
 					_v2.applyMatrix3( _normalMatrix ).normalize().multiplyScalar( this.size ).add( _v1 );
 					_v2.applyMatrix3( _normalMatrix ).normalize().multiplyScalar( this.size ).add( _v1 );
-
 					position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
 					position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
 					idx = idx + 1;
 					idx = idx + 1;
 					position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
 					position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
@@ -64,7 +60,6 @@
 			position.needsUpdate = true;
 			position.needsUpdate = true;
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.geometry.dispose();
 			this.geometry.dispose();

+ 9 - 10
examples/js/helpers/VertexTangentsHelper.js

@@ -1,9 +1,7 @@
 ( function () {
 ( function () {
 
 
 	const _v1 = new THREE.Vector3();
 	const _v1 = new THREE.Vector3();
-
 	const _v2 = new THREE.Vector3();
 	const _v2 = new THREE.Vector3();
-
 	class VertexTangentsHelper extends THREE.LineSegments {
 	class VertexTangentsHelper extends THREE.LineSegments {
 
 
 		constructor( object, size = 1, color = 0x00ffff ) {
 		constructor( object, size = 1, color = 0x00ffff ) {
@@ -18,32 +16,34 @@
 			} ) );
 			} ) );
 			this.object = object;
 			this.object = object;
 			this.size = size;
 			this.size = size;
-			this.type = 'VertexTangentsHelper'; //
+			this.type = 'VertexTangentsHelper';
+
+			//
 
 
 			this.matrixAutoUpdate = false;
 			this.matrixAutoUpdate = false;
 			this.update();
 			this.update();
 
 
 		}
 		}
-
 		update() {
 		update() {
 
 
 			this.object.updateMatrixWorld( true );
 			this.object.updateMatrixWorld( true );
 			const matrixWorld = this.object.matrixWorld;
 			const matrixWorld = this.object.matrixWorld;
-			const position = this.geometry.attributes.position; //
+			const position = this.geometry.attributes.position;
+
+			//
 
 
 			const objGeometry = this.object.geometry;
 			const objGeometry = this.object.geometry;
 			const objPos = objGeometry.attributes.position;
 			const objPos = objGeometry.attributes.position;
 			const objTan = objGeometry.attributes.tangent;
 			const objTan = objGeometry.attributes.tangent;
-			let idx = 0; // for simplicity, ignore index and drawcalls, and render every tangent
+			let idx = 0;
+
+			// for simplicity, ignore index and drawcalls, and render every tangent
 
 
 			for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
 			for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
 
 
 				_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
 				_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
-
 				_v2.fromBufferAttribute( objTan, j );
 				_v2.fromBufferAttribute( objTan, j );
-
 				_v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( _v1 );
 				_v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( _v1 );
-
 				position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
 				position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
 				idx = idx + 1;
 				idx = idx + 1;
 				position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
 				position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
@@ -54,7 +54,6 @@
 			position.needsUpdate = true;
 			position.needsUpdate = true;
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.geometry.dispose();
 			this.geometry.dispose();

+ 10 - 16
examples/js/helpers/ViewHelper.js

@@ -1,7 +1,6 @@
 ( function () {
 ( function () {
 
 
 	const vpTemp = new THREE.Vector4();
 	const vpTemp = new THREE.Vector4();
-
 	class ViewHelper extends THREE.Object3D {
 	class ViewHelper extends THREE.Object3D {
 
 
 		constructor( editorCamera, dom ) {
 		constructor( editorCamera, dom ) {
@@ -71,7 +70,6 @@
 				this.updateMatrixWorld();
 				this.updateMatrixWorld();
 				point.set( 0, 0, 1 );
 				point.set( 0, 0, 1 );
 				point.applyQuaternion( editorCamera.quaternion );
 				point.applyQuaternion( editorCamera.quaternion );
-
 				if ( point.x >= 0 ) {
 				if ( point.x >= 0 ) {
 
 
 					posXAxisHelper.material.opacity = 1;
 					posXAxisHelper.material.opacity = 1;
@@ -106,8 +104,9 @@
 					posZAxisHelper.material.opacity = 0.5;
 					posZAxisHelper.material.opacity = 0.5;
 					negZAxisHelper.material.opacity = 1;
 					negZAxisHelper.material.opacity = 1;
 
 
-				} //
+				}
 
 
+				//
 
 
 				const x = dom.offsetWidth - dim;
 				const x = dom.offsetWidth - dim;
 				renderer.clearDepth();
 				renderer.clearDepth();
@@ -123,7 +122,6 @@
 			const q1 = new THREE.Quaternion();
 			const q1 = new THREE.Quaternion();
 			const q2 = new THREE.Quaternion();
 			const q2 = new THREE.Quaternion();
 			let radius = 0;
 			let radius = 0;
-
 			this.handleClick = function ( event ) {
 			this.handleClick = function ( event ) {
 
 
 				if ( this.animating === true ) return false;
 				if ( this.animating === true ) return false;
@@ -134,7 +132,6 @@
 				mouse.y = - ( ( event.clientY - offsetY ) / ( rect.bottom - offsetY ) ) * 2 + 1;
 				mouse.y = - ( ( event.clientY - offsetY ) / ( rect.bottom - offsetY ) ) * 2 + 1;
 				raycaster.setFromCamera( mouse, camera );
 				raycaster.setFromCamera( mouse, camera );
 				const intersects = raycaster.intersectObjects( interactiveObjects );
 				const intersects = raycaster.intersectObjects( interactiveObjects );
-
 				if ( intersects.length > 0 ) {
 				if ( intersects.length > 0 ) {
 
 
 					const intersection = intersects[ 0 ];
 					const intersection = intersects[ 0 ];
@@ -154,13 +151,16 @@
 			this.update = function ( delta ) {
 			this.update = function ( delta ) {
 
 
 				const step = delta * turnRate;
 				const step = delta * turnRate;
-				const focusPoint = this.controls.center; // animate position by doing a slerp and then scaling the position on the unit sphere
+				const focusPoint = this.controls.center;
+
+				// animate position by doing a slerp and then scaling the position on the unit sphere
 
 
 				q1.rotateTowards( q2, step );
 				q1.rotateTowards( q2, step );
-				editorCamera.position.set( 0, 0, 1 ).applyQuaternion( q1 ).multiplyScalar( radius ).add( focusPoint ); // animate orientation
+				editorCamera.position.set( 0, 0, 1 ).applyQuaternion( q1 ).multiplyScalar( radius ).add( focusPoint );
 
 
-				editorCamera.quaternion.rotateTowards( targetQuaternion, step );
+				// animate orientation
 
 
+				editorCamera.quaternion.rotateTowards( targetQuaternion, step );
 				if ( q1.angleTo( q2 ) === 0 ) {
 				if ( q1.angleTo( q2 ) === 0 ) {
 
 
 					this.animating = false;
 					this.animating = false;
@@ -198,37 +198,32 @@
 						targetPosition.set( 1, 0, 0 );
 						targetPosition.set( 1, 0, 0 );
 						targetQuaternion.setFromEuler( new THREE.Euler( 0, Math.PI * 0.5, 0 ) );
 						targetQuaternion.setFromEuler( new THREE.Euler( 0, Math.PI * 0.5, 0 ) );
 						break;
 						break;
-
 					case 'posY':
 					case 'posY':
 						targetPosition.set( 0, 1, 0 );
 						targetPosition.set( 0, 1, 0 );
 						targetQuaternion.setFromEuler( new THREE.Euler( - Math.PI * 0.5, 0, 0 ) );
 						targetQuaternion.setFromEuler( new THREE.Euler( - Math.PI * 0.5, 0, 0 ) );
 						break;
 						break;
-
 					case 'posZ':
 					case 'posZ':
 						targetPosition.set( 0, 0, 1 );
 						targetPosition.set( 0, 0, 1 );
 						targetQuaternion.setFromEuler( new THREE.Euler() );
 						targetQuaternion.setFromEuler( new THREE.Euler() );
 						break;
 						break;
-
 					case 'negX':
 					case 'negX':
 						targetPosition.set( - 1, 0, 0 );
 						targetPosition.set( - 1, 0, 0 );
 						targetQuaternion.setFromEuler( new THREE.Euler( 0, - Math.PI * 0.5, 0 ) );
 						targetQuaternion.setFromEuler( new THREE.Euler( 0, - Math.PI * 0.5, 0 ) );
 						break;
 						break;
-
 					case 'negY':
 					case 'negY':
 						targetPosition.set( 0, - 1, 0 );
 						targetPosition.set( 0, - 1, 0 );
 						targetQuaternion.setFromEuler( new THREE.Euler( Math.PI * 0.5, 0, 0 ) );
 						targetQuaternion.setFromEuler( new THREE.Euler( Math.PI * 0.5, 0, 0 ) );
 						break;
 						break;
-
 					case 'negZ':
 					case 'negZ':
 						targetPosition.set( 0, 0, - 1 );
 						targetPosition.set( 0, 0, - 1 );
 						targetQuaternion.setFromEuler( new THREE.Euler( 0, Math.PI, 0 ) );
 						targetQuaternion.setFromEuler( new THREE.Euler( 0, Math.PI, 0 ) );
 						break;
 						break;
-
 					default:
 					default:
 						console.error( 'ViewHelper: Invalid axis.' );
 						console.error( 'ViewHelper: Invalid axis.' );
 
 
-				} //
+				}
 
 
+				//
 
 
 				radius = editorCamera.position.distanceTo( focusPoint );
 				radius = editorCamera.position.distanceTo( focusPoint );
 				targetPosition.multiplyScalar( radius ).add( focusPoint );
 				targetPosition.multiplyScalar( radius ).add( focusPoint );
@@ -260,7 +255,6 @@
 				context.closePath();
 				context.closePath();
 				context.fillStyle = color.getStyle();
 				context.fillStyle = color.getStyle();
 				context.fill();
 				context.fill();
-
 				if ( text !== null ) {
 				if ( text !== null ) {
 
 
 					context.font = '24px Arial';
 					context.font = '24px Arial';

+ 21 - 33
examples/js/interactive/HTMLMesh.js

@@ -12,7 +12,6 @@
 				transparent: true
 				transparent: true
 			} );
 			} );
 			super( geometry, material );
 			super( geometry, material );
-
 			function onEvent( event ) {
 			function onEvent( event ) {
 
 
 				material.map.dispatchDOMEvent( event );
 				material.map.dispatchDOMEvent( event );
@@ -23,7 +22,6 @@
 			this.addEventListener( 'mousemove', onEvent );
 			this.addEventListener( 'mousemove', onEvent );
 			this.addEventListener( 'mouseup', onEvent );
 			this.addEventListener( 'mouseup', onEvent );
 			this.addEventListener( 'click', onEvent );
 			this.addEventListener( 'click', onEvent );
-
 			this.dispose = function () {
 			this.dispose = function () {
 
 
 				geometry.dispose();
 				geometry.dispose();
@@ -40,7 +38,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	class HTMLTexture extends THREE.CanvasTexture {
 	class HTMLTexture extends THREE.CanvasTexture {
 
 
 		constructor( dom ) {
 		constructor( dom ) {
@@ -50,8 +47,9 @@
 			this.anisotropy = 16;
 			this.anisotropy = 16;
 			this.encoding = THREE.sRGBEncoding;
 			this.encoding = THREE.sRGBEncoding;
 			this.minFilter = THREE.LinearFilter;
 			this.minFilter = THREE.LinearFilter;
-			this.magFilter = THREE.LinearFilter; // Create an observer on the DOM, and run html2canvas update in the next loop
+			this.magFilter = THREE.LinearFilter;
 
 
+			// Create an observer on the DOM, and run html2canvas update in the next loop
 			const observer = new MutationObserver( () => {
 			const observer = new MutationObserver( () => {
 
 
 				if ( ! this.scheduleUpdate ) {
 				if ( ! this.scheduleUpdate ) {
@@ -72,7 +70,6 @@
 			this.observer = observer;
 			this.observer = observer;
 
 
 		}
 		}
-
 		dispatchDOMEvent( event ) {
 		dispatchDOMEvent( event ) {
 
 
 			if ( event.data ) {
 			if ( event.data ) {
@@ -82,7 +79,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		update() {
 		update() {
 
 
 			this.image = html2canvas( this.dom );
 			this.image = html2canvas( this.dom );
@@ -90,7 +86,6 @@
 			this.scheduleUpdate = null;
 			this.scheduleUpdate = null;
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			if ( this.observer ) {
 			if ( this.observer ) {
@@ -104,21 +99,19 @@
 
 
 		}
 		}
 
 
-	} //
+	}
 
 
+	//
 
 
 	const canvases = new WeakMap();
 	const canvases = new WeakMap();
-
 	function html2canvas( element ) {
 	function html2canvas( element ) {
 
 
 		const range = document.createRange();
 		const range = document.createRange();
 		const color = new THREE.Color();
 		const color = new THREE.Color();
-
 		function Clipper( context ) {
 		function Clipper( context ) {
 
 
 			const clips = [];
 			const clips = [];
 			let isClipping = false;
 			let isClipping = false;
-
 			function doClip() {
 			function doClip() {
 
 
 				if ( isClipping ) {
 				if ( isClipping ) {
@@ -133,7 +126,6 @@
 					minY = - Infinity;
 					minY = - Infinity;
 				let maxX = Infinity,
 				let maxX = Infinity,
 					maxY = Infinity;
 					maxY = Infinity;
-
 				for ( let i = 0; i < clips.length; i ++ ) {
 				for ( let i = 0; i < clips.length; i ++ ) {
 
 
 					const clip = clips[ i ];
 					const clip = clips[ i ];
@@ -207,7 +199,6 @@
 			const borderWidth = style[ which + 'Width' ];
 			const borderWidth = style[ which + 'Width' ];
 			const borderStyle = style[ which + 'Style' ];
 			const borderStyle = style[ which + 'Style' ];
 			const borderColor = style[ which + 'Color' ];
 			const borderColor = style[ which + 'Color' ];
-
 			if ( borderWidth !== '0px' && borderStyle !== 'none' && borderColor !== 'transparent' && borderColor !== 'rgba(0, 0, 0, 0)' ) {
 			if ( borderWidth !== '0px' && borderStyle !== 'none' && borderColor !== 'transparent' && borderColor !== 'rgba(0, 0, 0, 0)' ) {
 
 
 				context.strokeStyle = borderColor;
 				context.strokeStyle = borderColor;
@@ -227,10 +218,10 @@
 				y = 0,
 				y = 0,
 				width = 0,
 				width = 0,
 				height = 0;
 				height = 0;
-
 			if ( element.nodeType === Node.TEXT_NODE ) {
 			if ( element.nodeType === Node.TEXT_NODE ) {
 
 
 				// text
 				// text
+
 				range.selectNode( element );
 				range.selectNode( element );
 				const rect = range.getBoundingClientRect();
 				const rect = range.getBoundingClientRect();
 				x = rect.left - offset.left - 0.5;
 				x = rect.left - offset.left - 0.5;
@@ -261,23 +252,24 @@
 				y = rect.top - offset.top - 0.5;
 				y = rect.top - offset.top - 0.5;
 				width = rect.width;
 				width = rect.width;
 				height = rect.height;
 				height = rect.height;
-				style = window.getComputedStyle( element ); // Get the border of the element used for fill and border
+				style = window.getComputedStyle( element );
+
+				// Get the border of the element used for fill and border
 
 
 				buildRectPath( x, y, width, height, parseFloat( style.borderRadius ) );
 				buildRectPath( x, y, width, height, parseFloat( style.borderRadius ) );
 				const backgroundColor = style.backgroundColor;
 				const backgroundColor = style.backgroundColor;
-
 				if ( backgroundColor !== 'transparent' && backgroundColor !== 'rgba(0, 0, 0, 0)' ) {
 				if ( backgroundColor !== 'transparent' && backgroundColor !== 'rgba(0, 0, 0, 0)' ) {
 
 
 					context.fillStyle = backgroundColor;
 					context.fillStyle = backgroundColor;
 					context.fill();
 					context.fill();
 
 
-				} // If all the borders match then stroke the round rectangle
+				}
 
 
+				// If all the borders match then stroke the round rectangle
 
 
 				const borders = [ 'borderTop', 'borderLeft', 'borderBottom', 'borderRight' ];
 				const borders = [ 'borderTop', 'borderLeft', 'borderBottom', 'borderRight' ];
 				let match = true;
 				let match = true;
 				let prevBorder = null;
 				let prevBorder = null;
-
 				for ( const border of borders ) {
 				for ( const border of borders ) {
 
 
 					if ( prevBorder !== null ) {
 					if ( prevBorder !== null ) {
@@ -294,8 +286,8 @@
 				if ( match === true ) {
 				if ( match === true ) {
 
 
 					// They all match so stroke the rectangle from before allows for border-radius
 					// They all match so stroke the rectangle from before allows for border-radius
-					const width = parseFloat( style.borderTopWidth );
 
 
+					const width = parseFloat( style.borderTopWidth );
 					if ( style.borderTopWidth !== '0px' && style.borderTopStyle !== 'none' && style.borderTopColor !== 'transparent' && style.borderTopColor !== 'rgba(0, 0, 0, 0)' ) {
 					if ( style.borderTopWidth !== '0px' && style.borderTopStyle !== 'none' && style.borderTopColor !== 'transparent' && style.borderTopColor !== 'rgba(0, 0, 0, 0)' ) {
 
 
 						context.strokeStyle = style.borderTopColor;
 						context.strokeStyle = style.borderTopColor;
@@ -307,6 +299,7 @@
 				} else {
 				} else {
 
 
 					// Otherwise draw individual borders
 					// Otherwise draw individual borders
+
 					drawBorder( style, 'borderTop', x, y, width, 0 );
 					drawBorder( style, 'borderTop', x, y, width, 0 );
 					drawBorder( style, 'borderLeft', x, y, 0, height );
 					drawBorder( style, 'borderLeft', x, y, 0, height );
 					drawBorder( style, 'borderBottom', x, y + height, width, 0 );
 					drawBorder( style, 'borderBottom', x, y + height, width, 0 );
@@ -321,7 +314,6 @@
 					color.set( accentColor );
 					color.set( accentColor );
 					const luminance = Math.sqrt( 0.299 * color.r ** 2 + 0.587 * color.g ** 2 + 0.114 * color.b ** 2 );
 					const luminance = Math.sqrt( 0.299 * color.r ** 2 + 0.587 * color.g ** 2 + 0.114 * color.b ** 2 );
 					const accentTextColor = luminance < 0.5 ? 'white' : '#111111';
 					const accentTextColor = luminance < 0.5 ? 'white' : '#111111';
-
 					if ( element.type === 'radio' ) {
 					if ( element.type === 'radio' ) {
 
 
 						buildRectPath( x, y, width, height, height );
 						buildRectPath( x, y, width, height, height );
@@ -330,7 +322,6 @@
 						context.lineWidth = 1;
 						context.lineWidth = 1;
 						context.fill();
 						context.fill();
 						context.stroke();
 						context.stroke();
-
 						if ( element.checked ) {
 						if ( element.checked ) {
 
 
 							buildRectPath( x + 2, y + 2, width - 4, height - 4, height );
 							buildRectPath( x + 2, y + 2, width - 4, height - 4, height );
@@ -352,7 +343,6 @@
 						context.lineWidth = 1;
 						context.lineWidth = 1;
 						context.stroke();
 						context.stroke();
 						context.fill();
 						context.fill();
-
 						if ( element.checked ) {
 						if ( element.checked ) {
 
 
 							const currentTextAlign = context.textAlign;
 							const currentTextAlign = context.textAlign;
@@ -405,13 +395,13 @@
 				}
 				}
 
 
 			}
 			}
+
 			/*
 			/*
     // debug
     // debug
     context.strokeStyle = '#' + Math.random().toString( 16 ).slice( - 3 );
     context.strokeStyle = '#' + Math.random().toString( 16 ).slice( - 3 );
     context.strokeRect( x - 0.5, y - 0.5, width + 1, height + 1 );
     context.strokeRect( x - 0.5, y - 0.5, width + 1, height + 1 );
     */
     */
 
 
-
 			const isClipping = style.overflow === 'auto' || style.overflow === 'hidden';
 			const isClipping = style.overflow === 'auto' || style.overflow === 'hidden';
 			if ( isClipping ) clipper.add( {
 			if ( isClipping ) clipper.add( {
 				x: x,
 				x: x,
@@ -419,7 +409,6 @@
 				width: width,
 				width: width,
 				height: height
 				height: height
 			} );
 			} );
-
 			for ( let i = 0; i < element.childNodes.length; i ++ ) {
 			for ( let i = 0; i < element.childNodes.length; i ++ ) {
 
 
 				drawElement( element.childNodes[ i ], style );
 				drawElement( element.childNodes[ i ], style );
@@ -432,7 +421,6 @@
 
 
 		const offset = element.getBoundingClientRect();
 		const offset = element.getBoundingClientRect();
 		let canvas = canvases.get( element );
 		let canvas = canvases.get( element );
-
 		if ( canvas === undefined ) {
 		if ( canvas === undefined ) {
 
 
 			canvas = document.createElement( 'canvas' );
 			canvas = document.createElement( 'canvas' );
@@ -442,12 +430,15 @@
 
 
 		}
 		}
 
 
-		const context = canvas.getContext( '2d'
-			/*, { alpha: false }*/
-		);
-		const clipper = new Clipper( context ); // console.time( 'drawElement' );
+		const context = canvas.getContext( '2d' /*, { alpha: false }*/ );
+
+		const clipper = new Clipper( context );
+
+		// console.time( 'drawElement' );
 
 
-		drawElement( element ); // console.timeEnd( 'drawElement' );
+		drawElement( element );
+
+		// console.timeEnd( 'drawElement' );
 
 
 		return canvas;
 		return canvas;
 
 
@@ -464,17 +455,14 @@
 		const rect = element.getBoundingClientRect();
 		const rect = element.getBoundingClientRect();
 		x = x * rect.width + rect.left;
 		x = x * rect.width + rect.left;
 		y = y * rect.height + rect.top;
 		y = y * rect.height + rect.top;
-
 		function traverse( element ) {
 		function traverse( element ) {
 
 
 			if ( element.nodeType !== Node.TEXT_NODE && element.nodeType !== Node.COMMENT_NODE ) {
 			if ( element.nodeType !== Node.TEXT_NODE && element.nodeType !== Node.COMMENT_NODE ) {
 
 
 				const rect = element.getBoundingClientRect();
 				const rect = element.getBoundingClientRect();
-
 				if ( x > rect.left && x < rect.right && y > rect.top && y < rect.bottom ) {
 				if ( x > rect.left && x < rect.right && y > rect.top && y < rect.bottom ) {
 
 
 					element.dispatchEvent( new MouseEvent( event, mouseEventInit ) );
 					element.dispatchEvent( new MouseEvent( event, mouseEventInit ) );
-
 					if ( element instanceof HTMLInputElement && element.type === 'range' && ( event === 'mousedown' || event === 'click' ) ) {
 					if ( element instanceof HTMLInputElement && element.type === 'range' && ( event === 'mousedown' || event === 'click' ) ) {
 
 
 						const [ min, max ] = [ 'min', 'max' ].map( property => parseFloat( element[ property ] ) );
 						const [ min, max ] = [ 'min', 'max' ].map( property => parseFloat( element[ property ] ) );

+ 6 - 12
examples/js/interactive/InteractiveGroup.js

@@ -1,12 +1,10 @@
 ( function () {
 ( function () {
 
 
 	const _pointer = new THREE.Vector2();
 	const _pointer = new THREE.Vector2();
-
 	const _event = {
 	const _event = {
 		type: '',
 		type: '',
 		data: _pointer
 		data: _pointer
 	};
 	};
-
 	class InteractiveGroup extends THREE.Group {
 	class InteractiveGroup extends THREE.Group {
 
 
 		constructor( renderer, camera ) {
 		constructor( renderer, camera ) {
@@ -14,10 +12,11 @@
 			super();
 			super();
 			const scope = this;
 			const scope = this;
 			const raycaster = new THREE.Raycaster();
 			const raycaster = new THREE.Raycaster();
-			const tempMatrix = new THREE.Matrix4(); // Pointer Events
+			const tempMatrix = new THREE.Matrix4();
 
 
-			const element = renderer.domElement;
+			// Pointer Events
 
 
+			const element = renderer.domElement;
 			function onPointerEvent( event ) {
 			function onPointerEvent( event ) {
 
 
 				event.stopPropagation();
 				event.stopPropagation();
@@ -26,16 +25,13 @@
 				_pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
 				_pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
 				raycaster.setFromCamera( _pointer, camera );
 				raycaster.setFromCamera( _pointer, camera );
 				const intersects = raycaster.intersectObjects( scope.children, false );
 				const intersects = raycaster.intersectObjects( scope.children, false );
-
 				if ( intersects.length > 0 ) {
 				if ( intersects.length > 0 ) {
 
 
 					const intersection = intersects[ 0 ];
 					const intersection = intersects[ 0 ];
 					const object = intersection.object;
 					const object = intersection.object;
 					const uv = intersection.uv;
 					const uv = intersection.uv;
 					_event.type = event.type;
 					_event.type = event.type;
-
 					_event.data.set( uv.x, 1 - uv.y );
 					_event.data.set( uv.x, 1 - uv.y );
-
 					object.dispatchEvent( _event );
 					object.dispatchEvent( _event );
 
 
 				}
 				}
@@ -48,7 +44,9 @@
 			element.addEventListener( 'mousedown', onPointerEvent );
 			element.addEventListener( 'mousedown', onPointerEvent );
 			element.addEventListener( 'mouseup', onPointerEvent );
 			element.addEventListener( 'mouseup', onPointerEvent );
 			element.addEventListener( 'mousemove', onPointerEvent );
 			element.addEventListener( 'mousemove', onPointerEvent );
-			element.addEventListener( 'click', onPointerEvent ); // WebXR Controller Events
+			element.addEventListener( 'click', onPointerEvent );
+
+			// WebXR Controller Events
 			// TODO: Dispatch pointerevents too
 			// TODO: Dispatch pointerevents too
 
 
 			const events = {
 			const events = {
@@ -57,7 +55,6 @@
 				'selectstart': 'mousedown',
 				'selectstart': 'mousedown',
 				'selectend': 'mouseup'
 				'selectend': 'mouseup'
 			};
 			};
-
 			function onXRControllerEvent( event ) {
 			function onXRControllerEvent( event ) {
 
 
 				const controller = event.target;
 				const controller = event.target;
@@ -65,16 +62,13 @@
 				raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
 				raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
 				raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
 				raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
 				const intersections = raycaster.intersectObjects( scope.children, false );
 				const intersections = raycaster.intersectObjects( scope.children, false );
-
 				if ( intersections.length > 0 ) {
 				if ( intersections.length > 0 ) {
 
 
 					const intersection = intersections[ 0 ];
 					const intersection = intersections[ 0 ];
 					const object = intersection.object;
 					const object = intersection.object;
 					const uv = intersection.uv;
 					const uv = intersection.uv;
 					_event.type = events[ event.type ];
 					_event.type = events[ event.type ];
-
 					_event.data.set( uv.x, 1 - uv.y );
 					_event.data.set( uv.x, 1 - uv.y );
-
 					object.dispatchEvent( _event );
 					object.dispatchEvent( _event );
 
 
 				}
 				}

+ 3 - 70
examples/js/interactive/SelectionBox.js

@@ -5,41 +5,23 @@
  */
  */
 
 
 	const _frustum = new THREE.Frustum();
 	const _frustum = new THREE.Frustum();
-
 	const _center = new THREE.Vector3();
 	const _center = new THREE.Vector3();
-
 	const _tmpPoint = new THREE.Vector3();
 	const _tmpPoint = new THREE.Vector3();
-
 	const _vecNear = new THREE.Vector3();
 	const _vecNear = new THREE.Vector3();
-
 	const _vecTopLeft = new THREE.Vector3();
 	const _vecTopLeft = new THREE.Vector3();
-
 	const _vecTopRight = new THREE.Vector3();
 	const _vecTopRight = new THREE.Vector3();
-
 	const _vecDownRight = new THREE.Vector3();
 	const _vecDownRight = new THREE.Vector3();
-
 	const _vecDownLeft = new THREE.Vector3();
 	const _vecDownLeft = new THREE.Vector3();
-
 	const _vecFarTopLeft = new THREE.Vector3();
 	const _vecFarTopLeft = new THREE.Vector3();
-
 	const _vecFarTopRight = new THREE.Vector3();
 	const _vecFarTopRight = new THREE.Vector3();
-
 	const _vecFarDownRight = new THREE.Vector3();
 	const _vecFarDownRight = new THREE.Vector3();
-
 	const _vecFarDownLeft = new THREE.Vector3();
 	const _vecFarDownLeft = new THREE.Vector3();
-
 	const _vectemp1 = new THREE.Vector3();
 	const _vectemp1 = new THREE.Vector3();
-
 	const _vectemp2 = new THREE.Vector3();
 	const _vectemp2 = new THREE.Vector3();
-
 	const _vectemp3 = new THREE.Vector3();
 	const _vectemp3 = new THREE.Vector3();
-
 	const _matrix = new THREE.Matrix4();
 	const _matrix = new THREE.Matrix4();
-
 	const _quaternion = new THREE.Quaternion();
 	const _quaternion = new THREE.Quaternion();
-
 	const _scale = new THREE.Vector3();
 	const _scale = new THREE.Vector3();
-
 	class SelectionBox {
 	class SelectionBox {
 
 
 		constructor( camera, scene, deep = Number.MAX_VALUE ) {
 		constructor( camera, scene, deep = Number.MAX_VALUE ) {
@@ -53,7 +35,6 @@
 			this.deep = deep;
 			this.deep = deep;
 
 
 		}
 		}
-
 		select( startPoint, endPoint ) {
 		select( startPoint, endPoint ) {
 
 
 			this.startPoint = startPoint || this.startPoint;
 			this.startPoint = startPoint || this.startPoint;
@@ -64,11 +45,12 @@
 			return this.collection;
 			return this.collection;
 
 
 		}
 		}
-
 		updateFrustum( startPoint, endPoint ) {
 		updateFrustum( startPoint, endPoint ) {
 
 
 			startPoint = startPoint || this.startPoint;
 			startPoint = startPoint || this.startPoint;
-			endPoint = endPoint || this.endPoint; // Avoid invalid frustum
+			endPoint = endPoint || this.endPoint;
+
+			// Avoid invalid frustum
 
 
 			if ( startPoint.x === endPoint.x ) {
 			if ( startPoint.x === endPoint.x ) {
 
 
@@ -84,58 +66,34 @@
 
 
 			this.camera.updateProjectionMatrix();
 			this.camera.updateProjectionMatrix();
 			this.camera.updateMatrixWorld();
 			this.camera.updateMatrixWorld();
-
 			if ( this.camera.isPerspectiveCamera ) {
 			if ( this.camera.isPerspectiveCamera ) {
 
 
 				_tmpPoint.copy( startPoint );
 				_tmpPoint.copy( startPoint );
-
 				_tmpPoint.x = Math.min( startPoint.x, endPoint.x );
 				_tmpPoint.x = Math.min( startPoint.x, endPoint.x );
 				_tmpPoint.y = Math.max( startPoint.y, endPoint.y );
 				_tmpPoint.y = Math.max( startPoint.y, endPoint.y );
 				endPoint.x = Math.max( startPoint.x, endPoint.x );
 				endPoint.x = Math.max( startPoint.x, endPoint.x );
 				endPoint.y = Math.min( startPoint.y, endPoint.y );
 				endPoint.y = Math.min( startPoint.y, endPoint.y );
-
 				_vecNear.setFromMatrixPosition( this.camera.matrixWorld );
 				_vecNear.setFromMatrixPosition( this.camera.matrixWorld );
-
 				_vecTopLeft.copy( _tmpPoint );
 				_vecTopLeft.copy( _tmpPoint );
-
 				_vecTopRight.set( endPoint.x, _tmpPoint.y, 0 );
 				_vecTopRight.set( endPoint.x, _tmpPoint.y, 0 );
-
 				_vecDownRight.copy( endPoint );
 				_vecDownRight.copy( endPoint );
-
 				_vecDownLeft.set( _tmpPoint.x, endPoint.y, 0 );
 				_vecDownLeft.set( _tmpPoint.x, endPoint.y, 0 );
-
 				_vecTopLeft.unproject( this.camera );
 				_vecTopLeft.unproject( this.camera );
-
 				_vecTopRight.unproject( this.camera );
 				_vecTopRight.unproject( this.camera );
-
 				_vecDownRight.unproject( this.camera );
 				_vecDownRight.unproject( this.camera );
-
 				_vecDownLeft.unproject( this.camera );
 				_vecDownLeft.unproject( this.camera );
-
 				_vectemp1.copy( _vecTopLeft ).sub( _vecNear );
 				_vectemp1.copy( _vecTopLeft ).sub( _vecNear );
-
 				_vectemp2.copy( _vecTopRight ).sub( _vecNear );
 				_vectemp2.copy( _vecTopRight ).sub( _vecNear );
-
 				_vectemp3.copy( _vecDownRight ).sub( _vecNear );
 				_vectemp3.copy( _vecDownRight ).sub( _vecNear );
-
 				_vectemp1.normalize();
 				_vectemp1.normalize();
-
 				_vectemp2.normalize();
 				_vectemp2.normalize();
-
 				_vectemp3.normalize();
 				_vectemp3.normalize();
-
 				_vectemp1.multiplyScalar( this.deep );
 				_vectemp1.multiplyScalar( this.deep );
-
 				_vectemp2.multiplyScalar( this.deep );
 				_vectemp2.multiplyScalar( this.deep );
-
 				_vectemp3.multiplyScalar( this.deep );
 				_vectemp3.multiplyScalar( this.deep );
-
 				_vectemp1.add( _vecNear );
 				_vectemp1.add( _vecNear );
-
 				_vectemp2.add( _vecNear );
 				_vectemp2.add( _vecNear );
-
 				_vectemp3.add( _vecNear );
 				_vectemp3.add( _vecNear );
-
 				const planes = _frustum.planes;
 				const planes = _frustum.planes;
 				planes[ 0 ].setFromCoplanarPoints( _vecNear, _vecTopLeft, _vecTopRight );
 				planes[ 0 ].setFromCoplanarPoints( _vecNear, _vecTopLeft, _vecTopRight );
 				planes[ 1 ].setFromCoplanarPoints( _vecNear, _vecTopRight, _vecDownRight );
 				planes[ 1 ].setFromCoplanarPoints( _vecNear, _vecTopRight, _vecDownRight );
@@ -151,39 +109,22 @@
 				const top = Math.max( startPoint.y, endPoint.y );
 				const top = Math.max( startPoint.y, endPoint.y );
 				const right = Math.max( startPoint.x, endPoint.x );
 				const right = Math.max( startPoint.x, endPoint.x );
 				const down = Math.min( startPoint.y, endPoint.y );
 				const down = Math.min( startPoint.y, endPoint.y );
-
 				_vecTopLeft.set( left, top, - 1 );
 				_vecTopLeft.set( left, top, - 1 );
-
 				_vecTopRight.set( right, top, - 1 );
 				_vecTopRight.set( right, top, - 1 );
-
 				_vecDownRight.set( right, down, - 1 );
 				_vecDownRight.set( right, down, - 1 );
-
 				_vecDownLeft.set( left, down, - 1 );
 				_vecDownLeft.set( left, down, - 1 );
-
 				_vecFarTopLeft.set( left, top, 1 );
 				_vecFarTopLeft.set( left, top, 1 );
-
 				_vecFarTopRight.set( right, top, 1 );
 				_vecFarTopRight.set( right, top, 1 );
-
 				_vecFarDownRight.set( right, down, 1 );
 				_vecFarDownRight.set( right, down, 1 );
-
 				_vecFarDownLeft.set( left, down, 1 );
 				_vecFarDownLeft.set( left, down, 1 );
-
 				_vecTopLeft.unproject( this.camera );
 				_vecTopLeft.unproject( this.camera );
-
 				_vecTopRight.unproject( this.camera );
 				_vecTopRight.unproject( this.camera );
-
 				_vecDownRight.unproject( this.camera );
 				_vecDownRight.unproject( this.camera );
-
 				_vecDownLeft.unproject( this.camera );
 				_vecDownLeft.unproject( this.camera );
-
 				_vecFarTopLeft.unproject( this.camera );
 				_vecFarTopLeft.unproject( this.camera );
-
 				_vecFarTopRight.unproject( this.camera );
 				_vecFarTopRight.unproject( this.camera );
-
 				_vecFarDownRight.unproject( this.camera );
 				_vecFarDownRight.unproject( this.camera );
-
 				_vecFarDownLeft.unproject( this.camera );
 				_vecFarDownLeft.unproject( this.camera );
-
 				const planes = _frustum.planes;
 				const planes = _frustum.planes;
 				planes[ 0 ].setFromCoplanarPoints( _vecTopLeft, _vecFarTopLeft, _vecFarTopRight );
 				planes[ 0 ].setFromCoplanarPoints( _vecTopLeft, _vecFarTopLeft, _vecFarTopRight );
 				planes[ 1 ].setFromCoplanarPoints( _vecTopRight, _vecFarTopRight, _vecFarDownRight );
 				planes[ 1 ].setFromCoplanarPoints( _vecTopRight, _vecFarTopRight, _vecFarDownRight );
@@ -200,7 +141,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		searchChildInFrustum( frustum, object ) {
 		searchChildInFrustum( frustum, object ) {
 
 
 			if ( object.isMesh || object.isLine || object.isPoints ) {
 			if ( object.isMesh || object.isLine || object.isPoints ) {
@@ -208,15 +148,11 @@
 				if ( object.isInstancedMesh ) {
 				if ( object.isInstancedMesh ) {
 
 
 					this.instances[ object.uuid ] = [];
 					this.instances[ object.uuid ] = [];
-
 					for ( let instanceId = 0; instanceId < object.count; instanceId ++ ) {
 					for ( let instanceId = 0; instanceId < object.count; instanceId ++ ) {
 
 
 						object.getMatrixAt( instanceId, _matrix );
 						object.getMatrixAt( instanceId, _matrix );
-
 						_matrix.decompose( _center, _quaternion, _scale );
 						_matrix.decompose( _center, _quaternion, _scale );
-
 						_center.applyMatrix4( object.matrixWorld );
 						_center.applyMatrix4( object.matrixWorld );
-
 						if ( frustum.containsPoint( _center ) ) {
 						if ( frustum.containsPoint( _center ) ) {
 
 
 							this.instances[ object.uuid ].push( instanceId );
 							this.instances[ object.uuid ].push( instanceId );
@@ -228,11 +164,8 @@
 				} else {
 				} else {
 
 
 					if ( object.geometry.boundingSphere === null ) object.geometry.computeBoundingSphere();
 					if ( object.geometry.boundingSphere === null ) object.geometry.computeBoundingSphere();
-
 					_center.copy( object.geometry.boundingSphere.center );
 					_center.copy( object.geometry.boundingSphere.center );
-
 					_center.applyMatrix4( object.matrixWorld );
 					_center.applyMatrix4( object.matrixWorld );
-
 					if ( frustum.containsPoint( _center ) ) {
 					if ( frustum.containsPoint( _center ) ) {
 
 
 						this.collection.push( object );
 						this.collection.push( object );

+ 0 - 8
examples/js/interactive/SelectionHelper.js

@@ -12,14 +12,12 @@
 			this.pointTopLeft = new THREE.Vector2();
 			this.pointTopLeft = new THREE.Vector2();
 			this.pointBottomRight = new THREE.Vector2();
 			this.pointBottomRight = new THREE.Vector2();
 			this.isDown = false;
 			this.isDown = false;
-
 			this.onPointerDown = function ( event ) {
 			this.onPointerDown = function ( event ) {
 
 
 				this.isDown = true;
 				this.isDown = true;
 				this.onSelectStart( event );
 				this.onSelectStart( event );
 
 
 			}.bind( this );
 			}.bind( this );
-
 			this.onPointerMove = function ( event ) {
 			this.onPointerMove = function ( event ) {
 
 
 				if ( this.isDown ) {
 				if ( this.isDown ) {
@@ -29,20 +27,17 @@
 				}
 				}
 
 
 			}.bind( this );
 			}.bind( this );
-
 			this.onPointerUp = function () {
 			this.onPointerUp = function () {
 
 
 				this.isDown = false;
 				this.isDown = false;
 				this.onSelectOver();
 				this.onSelectOver();
 
 
 			}.bind( this );
 			}.bind( this );
-
 			this.renderer.domElement.addEventListener( 'pointerdown', this.onPointerDown );
 			this.renderer.domElement.addEventListener( 'pointerdown', this.onPointerDown );
 			this.renderer.domElement.addEventListener( 'pointermove', this.onPointerMove );
 			this.renderer.domElement.addEventListener( 'pointermove', this.onPointerMove );
 			this.renderer.domElement.addEventListener( 'pointerup', this.onPointerUp );
 			this.renderer.domElement.addEventListener( 'pointerup', this.onPointerUp );
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			this.renderer.domElement.removeEventListener( 'pointerdown', this.onPointerDown );
 			this.renderer.domElement.removeEventListener( 'pointerdown', this.onPointerDown );
@@ -50,7 +45,6 @@
 			this.renderer.domElement.removeEventListener( 'pointerup', this.onPointerUp );
 			this.renderer.domElement.removeEventListener( 'pointerup', this.onPointerUp );
 
 
 		}
 		}
-
 		onSelectStart( event ) {
 		onSelectStart( event ) {
 
 
 			this.element.style.display = 'none';
 			this.element.style.display = 'none';
@@ -63,7 +57,6 @@
 			this.startPoint.y = event.clientY;
 			this.startPoint.y = event.clientY;
 
 
 		}
 		}
-
 		onSelectMove( event ) {
 		onSelectMove( event ) {
 
 
 			this.element.style.display = 'block';
 			this.element.style.display = 'block';
@@ -77,7 +70,6 @@
 			this.element.style.height = this.pointBottomRight.y - this.pointTopLeft.y + 'px';
 			this.element.style.height = this.pointBottomRight.y - this.pointTopLeft.y + 'px';
 
 
 		}
 		}
-
 		onSelectOver() {
 		onSelectOver() {
 
 
 			this.element.parentElement.removeChild( this.element );
 			this.element.parentElement.removeChild( this.element );

+ 32 - 39
examples/js/lights/LightProbeGenerator.js

@@ -12,7 +12,6 @@
 			const shBasis = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
 			const shBasis = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
 			const sh = new THREE.SphericalHarmonics3();
 			const sh = new THREE.SphericalHarmonics3();
 			const shCoefficients = sh.coefficients;
 			const shCoefficients = sh.coefficients;
-
 			for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
 			for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
 
 
 				const image = cubeTexture.image[ faceIndex ];
 				const image = cubeTexture.image[ faceIndex ];
@@ -28,56 +27,57 @@
 				const imageWidth = imageData.width; // assumed to be square
 				const imageWidth = imageData.width; // assumed to be square
 
 
 				const pixelSize = 2 / imageWidth;
 				const pixelSize = 2 / imageWidth;
-
 				for ( let i = 0, il = data.length; i < il; i += 4 ) {
 				for ( let i = 0, il = data.length; i < il; i += 4 ) {
 
 
 					// RGBA assumed
 					// RGBA assumed
+
 					// pixel color
 					// pixel color
-					color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); // convert to linear color space
+					color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 );
 
 
-					convertColorToLinear( color, cubeTexture.encoding ); // pixel coordinate on unit cube
+					// convert to linear color space
+					convertColorToLinear( color, cubeTexture.encoding );
+
+					// pixel coordinate on unit cube
 
 
 					const pixelIndex = i / 4;
 					const pixelIndex = i / 4;
 					const col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize;
 					const col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize;
 					const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize;
 					const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize;
-
 					switch ( faceIndex ) {
 					switch ( faceIndex ) {
 
 
 						case 0:
 						case 0:
 							coord.set( - 1, row, - col );
 							coord.set( - 1, row, - col );
 							break;
 							break;
-
 						case 1:
 						case 1:
 							coord.set( 1, row, col );
 							coord.set( 1, row, col );
 							break;
 							break;
-
 						case 2:
 						case 2:
 							coord.set( - col, 1, - row );
 							coord.set( - col, 1, - row );
 							break;
 							break;
-
 						case 3:
 						case 3:
 							coord.set( - col, - 1, row );
 							coord.set( - col, - 1, row );
 							break;
 							break;
-
 						case 4:
 						case 4:
 							coord.set( - col, row, 1 );
 							coord.set( - col, row, 1 );
 							break;
 							break;
-
 						case 5:
 						case 5:
 							coord.set( col, row, - 1 );
 							coord.set( col, row, - 1 );
 							break;
 							break;
 
 
-					} // weight assigned to this pixel
+					}
 
 
+					// weight assigned to this pixel
 
 
 					const lengthSq = coord.lengthSq();
 					const lengthSq = coord.lengthSq();
 					const weight = 4 / ( Math.sqrt( lengthSq ) * lengthSq );
 					const weight = 4 / ( Math.sqrt( lengthSq ) * lengthSq );
-					totalWeight += weight; // direction vector to this pixel
+					totalWeight += weight;
 
 
-					dir.copy( coord ).normalize(); // evaluate SH basis functions in direction dir
+					// direction vector to this pixel
+					dir.copy( coord ).normalize();
 
 
-					THREE.SphericalHarmonics3.getBasisAt( dir, shBasis ); // accummuulate
+					// evaluate SH basis functions in direction dir
+					THREE.SphericalHarmonics3.getBasisAt( dir, shBasis );
 
 
+					// accummuulate
 					for ( let j = 0; j < 9; j ++ ) {
 					for ( let j = 0; j < 9; j ++ ) {
 
 
 						shCoefficients[ j ].x += shBasis[ j ] * color.r * weight;
 						shCoefficients[ j ].x += shBasis[ j ] * color.r * weight;
@@ -88,11 +88,10 @@
 
 
 				}
 				}
 
 
-			} // normalize
-
+			}
 
 
+			// normalize
 			const norm = 4 * Math.PI / totalWeight;
 			const norm = 4 * Math.PI / totalWeight;
-
 			for ( let j = 0; j < 9; j ++ ) {
 			for ( let j = 0; j < 9; j ++ ) {
 
 
 				shCoefficients[ j ].x *= norm;
 				shCoefficients[ j ].x *= norm;
@@ -104,7 +103,6 @@
 			return new THREE.LightProbe( sh );
 			return new THREE.LightProbe( sh );
 
 
 		}
 		}
-
 		static fromCubeRenderTarget( renderer, cubeRenderTarget ) {
 		static fromCubeRenderTarget( renderer, cubeRenderTarget ) {
 
 
 			// The renderTarget must be set to RGBA in order to make readRenderTargetPixels works
 			// The renderTarget must be set to RGBA in order to make readRenderTargetPixels works
@@ -115,64 +113,63 @@
 			const shBasis = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
 			const shBasis = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
 			const sh = new THREE.SphericalHarmonics3();
 			const sh = new THREE.SphericalHarmonics3();
 			const shCoefficients = sh.coefficients;
 			const shCoefficients = sh.coefficients;
-
 			for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
 			for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
 
 
 				const imageWidth = cubeRenderTarget.width; // assumed to be square
 				const imageWidth = cubeRenderTarget.width; // assumed to be square
-
 				const data = new Uint8Array( imageWidth * imageWidth * 4 );
 				const data = new Uint8Array( imageWidth * imageWidth * 4 );
 				renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex );
 				renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex );
 				const pixelSize = 2 / imageWidth;
 				const pixelSize = 2 / imageWidth;
-
 				for ( let i = 0, il = data.length; i < il; i += 4 ) {
 				for ( let i = 0, il = data.length; i < il; i += 4 ) {
 
 
 					// RGBA assumed
 					// RGBA assumed
+
 					// pixel color
 					// pixel color
-					color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); // convert to linear color space
+					color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 );
 
 
-					convertColorToLinear( color, cubeRenderTarget.texture.encoding ); // pixel coordinate on unit cube
+					// convert to linear color space
+					convertColorToLinear( color, cubeRenderTarget.texture.encoding );
+
+					// pixel coordinate on unit cube
 
 
 					const pixelIndex = i / 4;
 					const pixelIndex = i / 4;
 					const col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize;
 					const col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize;
 					const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize;
 					const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize;
-
 					switch ( faceIndex ) {
 					switch ( faceIndex ) {
 
 
 						case 0:
 						case 0:
 							coord.set( 1, row, - col );
 							coord.set( 1, row, - col );
 							break;
 							break;
-
 						case 1:
 						case 1:
 							coord.set( - 1, row, col );
 							coord.set( - 1, row, col );
 							break;
 							break;
-
 						case 2:
 						case 2:
 							coord.set( col, 1, - row );
 							coord.set( col, 1, - row );
 							break;
 							break;
-
 						case 3:
 						case 3:
 							coord.set( col, - 1, row );
 							coord.set( col, - 1, row );
 							break;
 							break;
-
 						case 4:
 						case 4:
 							coord.set( col, row, 1 );
 							coord.set( col, row, 1 );
 							break;
 							break;
-
 						case 5:
 						case 5:
 							coord.set( - col, row, - 1 );
 							coord.set( - col, row, - 1 );
 							break;
 							break;
 
 
-					} // weight assigned to this pixel
+					}
 
 
+					// weight assigned to this pixel
 
 
 					const lengthSq = coord.lengthSq();
 					const lengthSq = coord.lengthSq();
 					const weight = 4 / ( Math.sqrt( lengthSq ) * lengthSq );
 					const weight = 4 / ( Math.sqrt( lengthSq ) * lengthSq );
-					totalWeight += weight; // direction vector to this pixel
+					totalWeight += weight;
 
 
-					dir.copy( coord ).normalize(); // evaluate SH basis functions in direction dir
+					// direction vector to this pixel
+					dir.copy( coord ).normalize();
 
 
-					THREE.SphericalHarmonics3.getBasisAt( dir, shBasis ); // accummuulate
+					// evaluate SH basis functions in direction dir
+					THREE.SphericalHarmonics3.getBasisAt( dir, shBasis );
 
 
+					// accummuulate
 					for ( let j = 0; j < 9; j ++ ) {
 					for ( let j = 0; j < 9; j ++ ) {
 
 
 						shCoefficients[ j ].x += shBasis[ j ] * color.r * weight;
 						shCoefficients[ j ].x += shBasis[ j ] * color.r * weight;
@@ -183,11 +180,10 @@
 
 
 				}
 				}
 
 
-			} // normalize
-
+			}
 
 
+			// normalize
 			const norm = 4 * Math.PI / totalWeight;
 			const norm = 4 * Math.PI / totalWeight;
-
 			for ( let j = 0; j < 9; j ++ ) {
 			for ( let j = 0; j < 9; j ++ ) {
 
 
 				shCoefficients[ j ].x *= norm;
 				shCoefficients[ j ].x *= norm;
@@ -201,7 +197,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function convertColorToLinear( color, encoding ) {
 	function convertColorToLinear( color, encoding ) {
 
 
 		switch ( encoding ) {
 		switch ( encoding ) {
@@ -209,10 +204,8 @@
 			case THREE.sRGBEncoding:
 			case THREE.sRGBEncoding:
 				color.convertSRGBToLinear();
 				color.convertSRGBToLinear();
 				break;
 				break;
-
 			case THREE.LinearEncoding:
 			case THREE.LinearEncoding:
 				break;
 				break;
-
 			default:
 			default:
 				console.warn( 'WARNING: LightProbeGenerator convertColorToLinear() encountered an unsupported encoding.' );
 				console.warn( 'WARNING: LightProbeGenerator convertColorToLinear() encountered an unsupported encoding.' );
 				break;
 				break;

文件差異過大導致無法顯示
+ 2 - 0
examples/js/lights/RectAreaLightUniformsLib.js


+ 3 - 5
examples/js/lines/LineGeometry.js

@@ -9,13 +9,12 @@
 			this.type = 'LineGeometry';
 			this.type = 'LineGeometry';
 
 
 		}
 		}
-
 		setPositions( array ) {
 		setPositions( array ) {
 
 
 			// converts [ x1, y1, z1,  x2, y2, z2, ... ] to pairs format
 			// converts [ x1, y1, z1,  x2, y2, z2, ... ] to pairs format
+
 			const length = array.length - 3;
 			const length = array.length - 3;
 			const points = new Float32Array( 2 * length );
 			const points = new Float32Array( 2 * length );
-
 			for ( let i = 0; i < length; i += 3 ) {
 			for ( let i = 0; i < length; i += 3 ) {
 
 
 				points[ 2 * i ] = array[ i ];
 				points[ 2 * i ] = array[ i ];
@@ -31,13 +30,12 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setColors( array ) {
 		setColors( array ) {
 
 
 			// converts [ r1, g1, b1,  r2, g2, b2, ... ] to pairs format
 			// converts [ r1, g1, b1,  r2, g2, b2, ... ] to pairs format
+
 			const length = array.length - 3;
 			const length = array.length - 3;
 			const colors = new Float32Array( 2 * length );
 			const colors = new Float32Array( 2 * length );
-
 			for ( let i = 0; i < length; i += 3 ) {
 			for ( let i = 0; i < length; i += 3 ) {
 
 
 				colors[ 2 * i ] = array[ i ];
 				colors[ 2 * i ] = array[ i ];
@@ -53,11 +51,11 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		fromLine( line ) {
 		fromLine( line ) {
 
 
 			const geometry = line.geometry;
 			const geometry = line.geometry;
 			this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
 			this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
+
 			// set colors, maybe
 			// set colors, maybe
 
 
 			return this;
 			return this;

+ 4 - 11
examples/js/lines/LineMaterial.js

@@ -34,13 +34,11 @@
 		gapSize: {
 		gapSize: {
 			value: 1
 			value: 1
 		} // todo FIX - maybe change to totalSize
 		} // todo FIX - maybe change to totalSize
-
 	};
 	};
+
 	THREE.ShaderLib[ 'line' ] = {
 	THREE.ShaderLib[ 'line' ] = {
 		uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib.common, THREE.UniformsLib.fog, THREE.UniformsLib.line ] ),
 		uniforms: THREE.UniformsUtils.merge( [ THREE.UniformsLib.common, THREE.UniformsLib.fog, THREE.UniformsLib.line ] ),
-		vertexShader:
-  /* glsl */
-  `
+		vertexShader: /* glsl */`
 		#include <common>
 		#include <common>
 		#include <color_pars_vertex>
 		#include <color_pars_vertex>
 		#include <fog_pars_vertex>
 		#include <fog_pars_vertex>
@@ -269,9 +267,7 @@
 
 
 		}
 		}
 		`,
 		`,
-		fragmentShader:
-  /* glsl */
-  `
+		fragmentShader: /* glsl */`
 		uniform vec3 diffuse;
 		uniform vec3 diffuse;
 		uniform float opacity;
 		uniform float opacity;
 		uniform float linewidth;
 		uniform float linewidth;
@@ -432,7 +428,6 @@
 		}
 		}
 		`
 		`
 	};
 	};
-
 	class LineMaterial extends THREE.ShaderMaterial {
 	class LineMaterial extends THREE.ShaderMaterial {
 
 
 		constructor( parameters ) {
 		constructor( parameters ) {
@@ -443,8 +438,8 @@
 				vertexShader: THREE.ShaderLib[ 'line' ].vertexShader,
 				vertexShader: THREE.ShaderLib[ 'line' ].vertexShader,
 				fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader,
 				fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader,
 				clipping: true // required for clipping support
 				clipping: true // required for clipping support
-
 			} );
 			} );
+
 			this.isLineMaterial = true;
 			this.isLineMaterial = true;
 			Object.defineProperties( this, {
 			Object.defineProperties( this, {
 				color: {
 				color: {
@@ -501,7 +496,6 @@
 						return Boolean( 'USE_DASH' in this.defines );
 						return Boolean( 'USE_DASH' in this.defines );
 
 
 					},
 					},
-
 					set( value ) {
 					set( value ) {
 
 
 						if ( Boolean( value ) !== Boolean( 'USE_DASH' in this.defines ) ) {
 						if ( Boolean( value ) !== Boolean( 'USE_DASH' in this.defines ) ) {
@@ -521,7 +515,6 @@
 						}
 						}
 
 
 					}
 					}
-
 				},
 				},
 				dashScale: {
 				dashScale: {
 					enumerable: true,
 					enumerable: true,

+ 38 - 89
examples/js/lines/LineSegments2.js

@@ -1,49 +1,32 @@
 ( function () {
 ( function () {
 
 
 	const _start = new THREE.Vector3();
 	const _start = new THREE.Vector3();
-
 	const _end = new THREE.Vector3();
 	const _end = new THREE.Vector3();
-
 	const _start4 = new THREE.Vector4();
 	const _start4 = new THREE.Vector4();
-
 	const _end4 = new THREE.Vector4();
 	const _end4 = new THREE.Vector4();
-
 	const _ssOrigin = new THREE.Vector4();
 	const _ssOrigin = new THREE.Vector4();
-
 	const _ssOrigin3 = new THREE.Vector3();
 	const _ssOrigin3 = new THREE.Vector3();
-
 	const _mvMatrix = new THREE.Matrix4();
 	const _mvMatrix = new THREE.Matrix4();
-
 	const _line = new THREE.Line3();
 	const _line = new THREE.Line3();
-
 	const _closestPoint = new THREE.Vector3();
 	const _closestPoint = new THREE.Vector3();
-
 	const _box = new THREE.Box3();
 	const _box = new THREE.Box3();
-
 	const _sphere = new THREE.Sphere();
 	const _sphere = new THREE.Sphere();
-
 	const _clipToWorldVector = new THREE.Vector4();
 	const _clipToWorldVector = new THREE.Vector4();
+	let _ray, _instanceStart, _instanceEnd, _lineWidth;
 
 
-	let _ray, _instanceStart, _instanceEnd, _lineWidth; // Returns the margin required to expand by in world space given the distance from the camera,
+	// Returns the margin required to expand by in world space given the distance from the camera,
 	// line width, resolution, and camera projection
 	// line width, resolution, and camera projection
-
-
 	function getWorldSpaceHalfWidth( camera, distance, resolution ) {
 	function getWorldSpaceHalfWidth( camera, distance, resolution ) {
 
 
 		// transform into clip space, adjust the x and y values by the pixel width offset, then
 		// transform into clip space, adjust the x and y values by the pixel width offset, then
 		// transform back into world space to get world offset. Note clip space is [-1, 1] so full
 		// transform back into world space to get world offset. Note clip space is [-1, 1] so full
 		// width does not need to be halved.
 		// width does not need to be halved.
 		_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
 		_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
-
 		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
 		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
-
 		_clipToWorldVector.x = _lineWidth / resolution.width;
 		_clipToWorldVector.x = _lineWidth / resolution.width;
 		_clipToWorldVector.y = _lineWidth / resolution.height;
 		_clipToWorldVector.y = _lineWidth / resolution.height;
-
 		_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
 		_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
-
 		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
 		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
-
 		return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );
 		return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );
 
 
 	}
 	}
@@ -53,16 +36,11 @@
 		for ( let i = 0, l = _instanceStart.count; i < l; i ++ ) {
 		for ( let i = 0, l = _instanceStart.count; i < l; i ++ ) {
 
 
 			_line.start.fromBufferAttribute( _instanceStart, i );
 			_line.start.fromBufferAttribute( _instanceStart, i );
-
 			_line.end.fromBufferAttribute( _instanceEnd, i );
 			_line.end.fromBufferAttribute( _instanceEnd, i );
-
 			const pointOnLine = new THREE.Vector3();
 			const pointOnLine = new THREE.Vector3();
 			const point = new THREE.Vector3();
 			const point = new THREE.Vector3();
-
 			_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
 			_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
-
 			const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;
 			const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;
-
 			if ( isInside ) {
 			if ( isInside ) {
 
 
 				intersects.push( {
 				intersects.push( {
@@ -91,119 +69,98 @@
 		const geometry = lineSegments.geometry;
 		const geometry = lineSegments.geometry;
 		const instanceStart = geometry.attributes.instanceStart;
 		const instanceStart = geometry.attributes.instanceStart;
 		const instanceEnd = geometry.attributes.instanceEnd;
 		const instanceEnd = geometry.attributes.instanceEnd;
-		const near = - camera.near; //
+		const near = - camera.near;
+
+		//
+
 		// pick a point 1 unit out along the ray to avoid the ray origin
 		// pick a point 1 unit out along the ray to avoid the ray origin
 		// sitting at the camera origin which will cause "w" to be 0 when
 		// sitting at the camera origin which will cause "w" to be 0 when
 		// applying the projection matrix.
 		// applying the projection matrix.
+		_ray.at( 1, _ssOrigin );
 
 
-		_ray.at( 1, _ssOrigin ); // ndc space [ - 1.0, 1.0 ]
-
-
+		// ndc space [ - 1.0, 1.0 ]
 		_ssOrigin.w = 1;
 		_ssOrigin.w = 1;
-
 		_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
 		_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
-
 		_ssOrigin.applyMatrix4( projectionMatrix );
 		_ssOrigin.applyMatrix4( projectionMatrix );
+		_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
 
 
-		_ssOrigin.multiplyScalar( 1 / _ssOrigin.w ); // screen space
-
-
+		// screen space
 		_ssOrigin.x *= resolution.x / 2;
 		_ssOrigin.x *= resolution.x / 2;
 		_ssOrigin.y *= resolution.y / 2;
 		_ssOrigin.y *= resolution.y / 2;
 		_ssOrigin.z = 0;
 		_ssOrigin.z = 0;
-
 		_ssOrigin3.copy( _ssOrigin );
 		_ssOrigin3.copy( _ssOrigin );
-
 		_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
 		_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
-
 		for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
 		for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
 
 
 			_start4.fromBufferAttribute( instanceStart, i );
 			_start4.fromBufferAttribute( instanceStart, i );
-
 			_end4.fromBufferAttribute( instanceEnd, i );
 			_end4.fromBufferAttribute( instanceEnd, i );
-
 			_start4.w = 1;
 			_start4.w = 1;
-			_end4.w = 1; // camera space
+			_end4.w = 1;
 
 
+			// camera space
 			_start4.applyMatrix4( _mvMatrix );
 			_start4.applyMatrix4( _mvMatrix );
+			_end4.applyMatrix4( _mvMatrix );
 
 
-			_end4.applyMatrix4( _mvMatrix ); // skip the segment if it's entirely behind the camera
-
-
+			// skip the segment if it's entirely behind the camera
 			const isBehindCameraNear = _start4.z > near && _end4.z > near;
 			const isBehindCameraNear = _start4.z > near && _end4.z > near;
-
 			if ( isBehindCameraNear ) {
 			if ( isBehindCameraNear ) {
 
 
 				continue;
 				continue;
 
 
-			} // trim the segment if it extends behind camera near
-
+			}
 
 
+			// trim the segment if it extends behind camera near
 			if ( _start4.z > near ) {
 			if ( _start4.z > near ) {
 
 
 				const deltaDist = _start4.z - _end4.z;
 				const deltaDist = _start4.z - _end4.z;
 				const t = ( _start4.z - near ) / deltaDist;
 				const t = ( _start4.z - near ) / deltaDist;
-
 				_start4.lerp( _end4, t );
 				_start4.lerp( _end4, t );
 
 
 			} else if ( _end4.z > near ) {
 			} else if ( _end4.z > near ) {
 
 
 				const deltaDist = _end4.z - _start4.z;
 				const deltaDist = _end4.z - _start4.z;
 				const t = ( _end4.z - near ) / deltaDist;
 				const t = ( _end4.z - near ) / deltaDist;
-
 				_end4.lerp( _start4, t );
 				_end4.lerp( _start4, t );
 
 
-			} // clip space
-
+			}
 
 
+			// clip space
 			_start4.applyMatrix4( projectionMatrix );
 			_start4.applyMatrix4( projectionMatrix );
+			_end4.applyMatrix4( projectionMatrix );
 
 
-			_end4.applyMatrix4( projectionMatrix ); // ndc space [ - 1.0, 1.0 ]
-
-
+			// ndc space [ - 1.0, 1.0 ]
 			_start4.multiplyScalar( 1 / _start4.w );
 			_start4.multiplyScalar( 1 / _start4.w );
+			_end4.multiplyScalar( 1 / _end4.w );
 
 
-			_end4.multiplyScalar( 1 / _end4.w ); // screen space
-
-
+			// screen space
 			_start4.x *= resolution.x / 2;
 			_start4.x *= resolution.x / 2;
 			_start4.y *= resolution.y / 2;
 			_start4.y *= resolution.y / 2;
 			_end4.x *= resolution.x / 2;
 			_end4.x *= resolution.x / 2;
-			_end4.y *= resolution.y / 2; // create 2d segment
+			_end4.y *= resolution.y / 2;
 
 
+			// create 2d segment
 			_line.start.copy( _start4 );
 			_line.start.copy( _start4 );
-
 			_line.start.z = 0;
 			_line.start.z = 0;
-
 			_line.end.copy( _end4 );
 			_line.end.copy( _end4 );
+			_line.end.z = 0;
 
 
-			_line.end.z = 0; // get closest point on ray to segment
-
+			// get closest point on ray to segment
 			const param = _line.closestPointToPointParameter( _ssOrigin3, true );
 			const param = _line.closestPointToPointParameter( _ssOrigin3, true );
+			_line.at( param, _closestPoint );
 
 
-			_line.at( param, _closestPoint ); // check if the intersection point is within clip space
-
-
+			// check if the intersection point is within clip space
 			const zPos = THREE.MathUtils.lerp( _start4.z, _end4.z, param );
 			const zPos = THREE.MathUtils.lerp( _start4.z, _end4.z, param );
 			const isInClipSpace = zPos >= - 1 && zPos <= 1;
 			const isInClipSpace = zPos >= - 1 && zPos <= 1;
-
 			const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;
 			const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;
-
 			if ( isInClipSpace && isInside ) {
 			if ( isInClipSpace && isInside ) {
 
 
 				_line.start.fromBufferAttribute( instanceStart, i );
 				_line.start.fromBufferAttribute( instanceStart, i );
-
 				_line.end.fromBufferAttribute( instanceEnd, i );
 				_line.end.fromBufferAttribute( instanceEnd, i );
-
 				_line.start.applyMatrix4( matrixWorld );
 				_line.start.applyMatrix4( matrixWorld );
-
 				_line.end.applyMatrix4( matrixWorld );
 				_line.end.applyMatrix4( matrixWorld );
-
 				const pointOnLine = new THREE.Vector3();
 				const pointOnLine = new THREE.Vector3();
 				const point = new THREE.Vector3();
 				const point = new THREE.Vector3();
-
 				_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
 				_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
-
 				intersects.push( {
 				intersects.push( {
 					point: point,
 					point: point,
 					pointOnLine: pointOnLine,
 					pointOnLine: pointOnLine,
@@ -231,8 +188,9 @@
 			this.isLineSegments2 = true;
 			this.isLineSegments2 = true;
 			this.type = 'LineSegments2';
 			this.type = 'LineSegments2';
 
 
-		} // for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry...
+		}
 
 
+		// for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry...
 
 
 		computeLineDistances() {
 		computeLineDistances() {
 
 
@@ -240,13 +198,10 @@
 			const instanceStart = geometry.attributes.instanceStart;
 			const instanceStart = geometry.attributes.instanceStart;
 			const instanceEnd = geometry.attributes.instanceEnd;
 			const instanceEnd = geometry.attributes.instanceEnd;
 			const lineDistances = new Float32Array( 2 * instanceStart.count );
 			const lineDistances = new Float32Array( 2 * instanceStart.count );
-
 			for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 			for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 
 
 				_start.fromBufferAttribute( instanceStart, i );
 				_start.fromBufferAttribute( instanceStart, i );
-
 				_end.fromBufferAttribute( instanceEnd, i );
 				_end.fromBufferAttribute( instanceEnd, i );
-
 				lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
 				lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
 				lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 				lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 
 
@@ -255,18 +210,15 @@
 			const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 			const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
 
 			geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
 			geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
-
 			geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 			geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
 
 			return this;
 			return this;
 
 
 		}
 		}
-
 		raycast( raycaster, intersects ) {
 		raycast( raycaster, intersects ) {
 
 
 			const worldUnits = this.material.worldUnits;
 			const worldUnits = this.material.worldUnits;
 			const camera = raycaster.camera;
 			const camera = raycaster.camera;
-
 			if ( camera === null && ! worldUnits ) {
 			if ( camera === null && ! worldUnits ) {
 
 
 				console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' );
 				console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' );
@@ -280,19 +232,19 @@
 			const material = this.material;
 			const material = this.material;
 			_lineWidth = material.linewidth + threshold;
 			_lineWidth = material.linewidth + threshold;
 			_instanceStart = geometry.attributes.instanceStart;
 			_instanceStart = geometry.attributes.instanceStart;
-			_instanceEnd = geometry.attributes.instanceEnd; // check if we intersect the sphere bounds
+			_instanceEnd = geometry.attributes.instanceEnd;
 
 
+			// check if we intersect the sphere bounds
 			if ( geometry.boundingSphere === null ) {
 			if ( geometry.boundingSphere === null ) {
 
 
 				geometry.computeBoundingSphere();
 				geometry.computeBoundingSphere();
 
 
 			}
 			}
 
 
-			_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld ); // increase the sphere bounds by the worst case line screen space width
-
+			_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
 
 
+			// increase the sphere bounds by the worst case line screen space width
 			let sphereMargin;
 			let sphereMargin;
-
 			if ( worldUnits ) {
 			if ( worldUnits ) {
 
 
 				sphereMargin = _lineWidth * 0.5;
 				sphereMargin = _lineWidth * 0.5;
@@ -305,25 +257,23 @@
 			}
 			}
 
 
 			_sphere.radius += sphereMargin;
 			_sphere.radius += sphereMargin;
-
 			if ( _ray.intersectsSphere( _sphere ) === false ) {
 			if ( _ray.intersectsSphere( _sphere ) === false ) {
 
 
 				return;
 				return;
 
 
-			} // check if we intersect the box bounds
-
+			}
 
 
+			// check if we intersect the box bounds
 			if ( geometry.boundingBox === null ) {
 			if ( geometry.boundingBox === null ) {
 
 
 				geometry.computeBoundingBox();
 				geometry.computeBoundingBox();
 
 
 			}
 			}
 
 
-			_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld ); // increase the box bounds by the worst case line width
-
+			_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
 
 
+			// increase the box bounds by the worst case line width
 			let boxMargin;
 			let boxMargin;
-
 			if ( worldUnits ) {
 			if ( worldUnits ) {
 
 
 				boxMargin = _lineWidth * 0.5;
 				boxMargin = _lineWidth * 0.5;
@@ -336,7 +286,6 @@
 			}
 			}
 
 
 			_box.expandByScalar( boxMargin );
 			_box.expandByScalar( boxMargin );
-
 			if ( _ray.intersectsBox( _box ) === false ) {
 			if ( _ray.intersectsBox( _box ) === false ) {
 
 
 				return;
 				return;

+ 7 - 28
examples/js/lines/LineSegmentsGeometry.js

@@ -1,9 +1,7 @@
 ( function () {
 ( function () {
 
 
 	const _box = new THREE.Box3();
 	const _box = new THREE.Box3();
-
 	const _vector = new THREE.Vector3();
 	const _vector = new THREE.Vector3();
-
 	class LineSegmentsGeometry extends THREE.InstancedBufferGeometry {
 	class LineSegmentsGeometry extends THREE.InstancedBufferGeometry {
 
 
 		constructor() {
 		constructor() {
@@ -19,12 +17,10 @@
 			this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
 			this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
 
 
 		}
 		}
-
 		applyMatrix4( matrix ) {
 		applyMatrix4( matrix ) {
 
 
 			const start = this.attributes.instanceStart;
 			const start = this.attributes.instanceStart;
 			const end = this.attributes.instanceEnd;
 			const end = this.attributes.instanceEnd;
-
 			if ( start !== undefined ) {
 			if ( start !== undefined ) {
 
 
 				start.applyMatrix4( matrix );
 				start.applyMatrix4( matrix );
@@ -48,11 +44,9 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setPositions( array ) {
 		setPositions( array ) {
 
 
 			let lineSegments;
 			let lineSegments;
-
 			if ( array instanceof Float32Array ) {
 			if ( array instanceof Float32Array ) {
 
 
 				lineSegments = array;
 				lineSegments = array;
@@ -66,8 +60,8 @@
 			const instanceBuffer = new THREE.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
 			const instanceBuffer = new THREE.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
 
 
 			this.setAttribute( 'instanceStart', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
 			this.setAttribute( 'instanceStart', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
-
 			this.setAttribute( 'instanceEnd', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
 			this.setAttribute( 'instanceEnd', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
+
 			//
 			//
 
 
 			this.computeBoundingBox();
 			this.computeBoundingBox();
@@ -75,11 +69,9 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setColors( array ) {
 		setColors( array ) {
 
 
 			let colors;
 			let colors;
-
 			if ( array instanceof Float32Array ) {
 			if ( array instanceof Float32Array ) {
 
 
 				colors = array;
 				colors = array;
@@ -93,45 +85,42 @@
 			const instanceColorBuffer = new THREE.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
 			const instanceColorBuffer = new THREE.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
 
 
 			this.setAttribute( 'instanceColorStart', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
 			this.setAttribute( 'instanceColorStart', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
-
 			this.setAttribute( 'instanceColorEnd', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
 			this.setAttribute( 'instanceColorEnd', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
 
 
 			return this;
 			return this;
 
 
 		}
 		}
-
 		fromWireframeGeometry( geometry ) {
 		fromWireframeGeometry( geometry ) {
 
 
 			this.setPositions( geometry.attributes.position.array );
 			this.setPositions( geometry.attributes.position.array );
 			return this;
 			return this;
 
 
 		}
 		}
-
 		fromEdgesGeometry( geometry ) {
 		fromEdgesGeometry( geometry ) {
 
 
 			this.setPositions( geometry.attributes.position.array );
 			this.setPositions( geometry.attributes.position.array );
 			return this;
 			return this;
 
 
 		}
 		}
-
 		fromMesh( mesh ) {
 		fromMesh( mesh ) {
 
 
-			this.fromWireframeGeometry( new THREE.WireframeGeometry( mesh.geometry ) ); // set colors, maybe
+			this.fromWireframeGeometry( new THREE.WireframeGeometry( mesh.geometry ) );
+
+			// set colors, maybe
 
 
 			return this;
 			return this;
 
 
 		}
 		}
-
 		fromLineSegments( lineSegments ) {
 		fromLineSegments( lineSegments ) {
 
 
 			const geometry = lineSegments.geometry;
 			const geometry = lineSegments.geometry;
 			this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
 			this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
+
 			// set colors, maybe
 			// set colors, maybe
 
 
 			return this;
 			return this;
 
 
 		}
 		}
-
 		computeBoundingBox() {
 		computeBoundingBox() {
 
 
 			if ( this.boundingBox === null ) {
 			if ( this.boundingBox === null ) {
@@ -142,19 +131,15 @@
 
 
 			const start = this.attributes.instanceStart;
 			const start = this.attributes.instanceStart;
 			const end = this.attributes.instanceEnd;
 			const end = this.attributes.instanceEnd;
-
 			if ( start !== undefined && end !== undefined ) {
 			if ( start !== undefined && end !== undefined ) {
 
 
 				this.boundingBox.setFromBufferAttribute( start );
 				this.boundingBox.setFromBufferAttribute( start );
-
 				_box.setFromBufferAttribute( end );
 				_box.setFromBufferAttribute( end );
-
 				this.boundingBox.union( _box );
 				this.boundingBox.union( _box );
 
 
 			}
 			}
 
 
 		}
 		}
-
 		computeBoundingSphere() {
 		computeBoundingSphere() {
 
 
 			if ( this.boundingSphere === null ) {
 			if ( this.boundingSphere === null ) {
@@ -171,27 +156,21 @@
 
 
 			const start = this.attributes.instanceStart;
 			const start = this.attributes.instanceStart;
 			const end = this.attributes.instanceEnd;
 			const end = this.attributes.instanceEnd;
-
 			if ( start !== undefined && end !== undefined ) {
 			if ( start !== undefined && end !== undefined ) {
 
 
 				const center = this.boundingSphere.center;
 				const center = this.boundingSphere.center;
 				this.boundingBox.getCenter( center );
 				this.boundingBox.getCenter( center );
 				let maxRadiusSq = 0;
 				let maxRadiusSq = 0;
-
 				for ( let i = 0, il = start.count; i < il; i ++ ) {
 				for ( let i = 0, il = start.count; i < il; i ++ ) {
 
 
 					_vector.fromBufferAttribute( start, i );
 					_vector.fromBufferAttribute( start, i );
-
 					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
 					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
-
 					_vector.fromBufferAttribute( end, i );
 					_vector.fromBufferAttribute( end, i );
-
 					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
 					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
 
 
 				}
 				}
 
 
 				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
 				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
-
 				if ( isNaN( this.boundingSphere.radius ) ) {
 				if ( isNaN( this.boundingSphere.radius ) ) {
 
 
 					console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
 					console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
@@ -201,10 +180,10 @@
 			}
 			}
 
 
 		}
 		}
+		toJSON() {
 
 
-		toJSON() { // todo
+			// todo
 		}
 		}
-
 		applyMatrix( matrix ) {
 		applyMatrix( matrix ) {
 
 
 			console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
 			console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );

+ 2 - 7
examples/js/lines/Wireframe.js

@@ -1,9 +1,7 @@
 ( function () {
 ( function () {
 
 
 	const _start = new THREE.Vector3();
 	const _start = new THREE.Vector3();
-
 	const _end = new THREE.Vector3();
 	const _end = new THREE.Vector3();
-
 	class Wireframe extends THREE.Mesh {
 	class Wireframe extends THREE.Mesh {
 
 
 		constructor( geometry = new THREE.LineSegmentsGeometry(), material = new THREE.LineMaterial( {
 		constructor( geometry = new THREE.LineSegmentsGeometry(), material = new THREE.LineMaterial( {
@@ -14,8 +12,9 @@
 			this.isWireframe = true;
 			this.isWireframe = true;
 			this.type = 'Wireframe';
 			this.type = 'Wireframe';
 
 
-		} // for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry...
+		}
 
 
+		// for backwards-compatibility, but could be a method of THREE.LineSegmentsGeometry...
 
 
 		computeLineDistances() {
 		computeLineDistances() {
 
 
@@ -23,13 +22,10 @@
 			const instanceStart = geometry.attributes.instanceStart;
 			const instanceStart = geometry.attributes.instanceStart;
 			const instanceEnd = geometry.attributes.instanceEnd;
 			const instanceEnd = geometry.attributes.instanceEnd;
 			const lineDistances = new Float32Array( 2 * instanceStart.count );
 			const lineDistances = new Float32Array( 2 * instanceStart.count );
-
 			for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 			for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 
 
 				_start.fromBufferAttribute( instanceStart, i );
 				_start.fromBufferAttribute( instanceStart, i );
-
 				_end.fromBufferAttribute( instanceEnd, i );
 				_end.fromBufferAttribute( instanceEnd, i );
-
 				lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
 				lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
 				lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 				lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 
 
@@ -38,7 +34,6 @@
 			const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 			const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
 
 			geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
 			geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
-
 			geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 			geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
 
 			return this;
 			return this;

+ 3 - 1
examples/js/lines/WireframeGeometry2.js

@@ -7,7 +7,9 @@
 			super();
 			super();
 			this.isWireframeGeometry2 = true;
 			this.isWireframeGeometry2 = true;
 			this.type = 'WireframeGeometry2';
 			this.type = 'WireframeGeometry2';
-			this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) ); // set colors, maybe
+			this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) );
+
+			// set colors, maybe
 
 
 		}
 		}
 
 

+ 57 - 154
examples/js/loaders/3DMLoader.js

@@ -1,7 +1,6 @@
 ( function () {
 ( function () {
 
 
 	const _taskCache = new WeakMap();
 	const _taskCache = new WeakMap();
-
 	class Rhino3dmLoader extends THREE.Loader {
 	class Rhino3dmLoader extends THREE.Loader {
 
 
 		constructor( manager ) {
 		constructor( manager ) {
@@ -21,21 +20,18 @@
 			this.warnings = [];
 			this.warnings = [];
 
 
 		}
 		}
-
 		setLibraryPath( path ) {
 		setLibraryPath( path ) {
 
 
 			this.libraryPath = path;
 			this.libraryPath = path;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setWorkerLimit( workerLimit ) {
 		setWorkerLimit( workerLimit ) {
 
 
 			this.workerLimit = workerLimit;
 			this.workerLimit = workerLimit;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const loader = new THREE.FileLoader( this.manager );
 			const loader = new THREE.FileLoader( this.manager );
@@ -50,7 +46,6 @@
 				if ( _taskCache.has( buffer ) ) {
 				if ( _taskCache.has( buffer ) ) {
 
 
 					const cachedTask = _taskCache.get( buffer );
 					const cachedTask = _taskCache.get( buffer );
-
 					return cachedTask.promise.then( onLoad ).catch( onError );
 					return cachedTask.promise.then( onLoad ).catch( onError );
 
 
 				}
 				}
@@ -65,19 +60,16 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		debug() {
 		debug() {
 
 
 			console.log( 'Task load: ', this.workerPool.map( worker => worker._taskLoad ) );
 			console.log( 'Task load: ', this.workerPool.map( worker => worker._taskLoad ) );
 
 
 		}
 		}
-
 		decodeObjects( buffer, url ) {
 		decodeObjects( buffer, url ) {
 
 
 			let worker;
 			let worker;
 			let taskID;
 			let taskID;
 			const taskCost = buffer.byteLength;
 			const taskCost = buffer.byteLength;
-
 			const objectPending = this._getWorker( taskCost ).then( _worker => {
 			const objectPending = this._getWorker( taskCost ).then( _worker => {
 
 
 				worker = _worker;
 				worker = _worker;
@@ -92,7 +84,9 @@
 						type: 'decode',
 						type: 'decode',
 						id: taskID,
 						id: taskID,
 						buffer
 						buffer
-					}, [ buffer ] ); // this.debug();
+					}, [ buffer ] );
+
+					// this.debug();
 
 
 				} );
 				} );
 
 
@@ -100,29 +94,30 @@
 
 
 				throw e;
 				throw e;
 
 
-			} ); // Remove task from the task list.
-			// Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
-
+			} );
 
 
+			// Remove task from the task list.
+			// Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
 			objectPending.catch( () => true ).then( () => {
 			objectPending.catch( () => true ).then( () => {
 
 
 				if ( worker && taskID ) {
 				if ( worker && taskID ) {
 
 
-					this._releaseTask( worker, taskID ); //this.debug();
+					this._releaseTask( worker, taskID );
+
+					//this.debug();
 
 
 				}
 				}
 
 
-			} ); // Cache the task result.
+			} );
 
 
+			// Cache the task result.
 			_taskCache.set( buffer, {
 			_taskCache.set( buffer, {
 				url: url,
 				url: url,
 				promise: objectPending
 				promise: objectPending
 			} );
 			} );
-
 			return objectPending;
 			return objectPending;
 
 
 		}
 		}
-
 		parse( data, onLoad, onError ) {
 		parse( data, onLoad, onError ) {
 
 
 			this.decodeObjects( data, '' ).then( result => {
 			this.decodeObjects( data, '' ).then( result => {
@@ -133,7 +128,6 @@
 			} ).catch( e => onError( e ) );
 			} ).catch( e => onError( e ) );
 
 
 		}
 		}
-
 		_compareMaterials( material ) {
 		_compareMaterials( material ) {
 
 
 			const mat = {};
 			const mat = {};
@@ -143,7 +137,6 @@
 			mat.color.g = material.color.g;
 			mat.color.g = material.color.g;
 			mat.color.b = material.color.b;
 			mat.color.b = material.color.b;
 			mat.type = material.type;
 			mat.type = material.type;
-
 			for ( let i = 0; i < this.materials.length; i ++ ) {
 			for ( let i = 0; i < this.materials.length; i ++ ) {
 
 
 				const m = this.materials[ i ];
 				const m = this.materials[ i ];
@@ -154,7 +147,6 @@
 				_mat.color.g = m.color.g;
 				_mat.color.g = m.color.g;
 				_mat.color.b = m.color.b;
 				_mat.color.b = m.color.b;
 				_mat.type = m.type;
 				_mat.type = m.type;
-
 				if ( JSON.stringify( mat ) === JSON.stringify( _mat ) ) {
 				if ( JSON.stringify( mat ) === JSON.stringify( _mat ) ) {
 
 
 					return m;
 					return m;
@@ -167,7 +159,6 @@
 			return material;
 			return material;
 
 
 		}
 		}
-
 		_createMaterial( material ) {
 		_createMaterial( material ) {
 
 
 			if ( material === undefined ) {
 			if ( material === undefined ) {
@@ -183,15 +174,15 @@
 
 
 			const _diffuseColor = material.diffuseColor;
 			const _diffuseColor = material.diffuseColor;
 			const diffusecolor = new THREE.Color( _diffuseColor.r / 255.0, _diffuseColor.g / 255.0, _diffuseColor.b / 255.0 );
 			const diffusecolor = new THREE.Color( _diffuseColor.r / 255.0, _diffuseColor.g / 255.0, _diffuseColor.b / 255.0 );
-
 			if ( _diffuseColor.r === 0 && _diffuseColor.g === 0 && _diffuseColor.b === 0 ) {
 			if ( _diffuseColor.r === 0 && _diffuseColor.g === 0 && _diffuseColor.b === 0 ) {
 
 
 				diffusecolor.r = 1;
 				diffusecolor.r = 1;
 				diffusecolor.g = 1;
 				diffusecolor.g = 1;
 				diffusecolor.b = 1;
 				diffusecolor.b = 1;
 
 
-			} // console.log( material );
+			}
 
 
+			// console.log( material );
 
 
 			const mat = new THREE.MeshStandardMaterial( {
 			const mat = new THREE.MeshStandardMaterial( {
 				color: diffusecolor,
 				color: diffusecolor,
@@ -201,30 +192,24 @@
 				opacity: 1.0 - material.transparency
 				opacity: 1.0 - material.transparency
 			} );
 			} );
 			const textureLoader = new THREE.TextureLoader();
 			const textureLoader = new THREE.TextureLoader();
-
 			for ( let i = 0; i < material.textures.length; i ++ ) {
 			for ( let i = 0; i < material.textures.length; i ++ ) {
 
 
 				const texture = material.textures[ i ];
 				const texture = material.textures[ i ];
-
 				if ( texture.image !== null ) {
 				if ( texture.image !== null ) {
 
 
 					const map = textureLoader.load( texture.image );
 					const map = textureLoader.load( texture.image );
-
 					switch ( texture.type ) {
 					switch ( texture.type ) {
 
 
 						case 'Diffuse':
 						case 'Diffuse':
 							mat.map = map;
 							mat.map = map;
 							break;
 							break;
-
 						case 'Bump':
 						case 'Bump':
 							mat.bumpMap = map;
 							mat.bumpMap = map;
 							break;
 							break;
-
 						case 'Transparency':
 						case 'Transparency':
 							mat.alphaMap = map;
 							mat.alphaMap = map;
 							mat.transparent = true;
 							mat.transparent = true;
 							break;
 							break;
-
 						case 'Emap':
 						case 'Emap':
 							mat.envMap = map;
 							mat.envMap = map;
 							break;
 							break;
@@ -242,10 +227,10 @@
 			return mat;
 			return mat;
 
 
 		}
 		}
-
 		_createGeometry( data ) {
 		_createGeometry( data ) {
 
 
 			// console.log(data);
 			// console.log(data);
+
 			const object = new THREE.Object3D();
 			const object = new THREE.Object3D();
 			const instanceDefinitionObjects = [];
 			const instanceDefinitionObjects = [];
 			const instanceDefinitions = [];
 			const instanceDefinitions = [];
@@ -258,38 +243,30 @@
 			object.name = this.url;
 			object.name = this.url;
 			let objects = data.objects;
 			let objects = data.objects;
 			const materials = data.materials;
 			const materials = data.materials;
-
 			for ( let i = 0; i < objects.length; i ++ ) {
 			for ( let i = 0; i < objects.length; i ++ ) {
 
 
 				const obj = objects[ i ];
 				const obj = objects[ i ];
 				const attributes = obj.attributes;
 				const attributes = obj.attributes;
-
 				switch ( obj.objectType ) {
 				switch ( obj.objectType ) {
 
 
 					case 'InstanceDefinition':
 					case 'InstanceDefinition':
 						instanceDefinitions.push( obj );
 						instanceDefinitions.push( obj );
 						break;
 						break;
-
 					case 'InstanceReference':
 					case 'InstanceReference':
 						instanceReferences.push( obj );
 						instanceReferences.push( obj );
 						break;
 						break;
-
 					default:
 					default:
 						let _object;
 						let _object;
-
 						if ( attributes.materialIndex >= 0 ) {
 						if ( attributes.materialIndex >= 0 ) {
 
 
 							const rMaterial = materials[ attributes.materialIndex ];
 							const rMaterial = materials[ attributes.materialIndex ];
-
 							let material = this._createMaterial( rMaterial );
 							let material = this._createMaterial( rMaterial );
-
 							material = this._compareMaterials( material );
 							material = this._compareMaterials( material );
 							_object = this._createObject( obj, material );
 							_object = this._createObject( obj, material );
 
 
 						} else {
 						} else {
 
 
 							const material = this._createMaterial();
 							const material = this._createMaterial();
-
 							_object = this._createObject( obj, material );
 							_object = this._createObject( obj, material );
 
 
 						}
 						}
@@ -302,7 +279,6 @@
 
 
 						const layer = data.layers[ attributes.layerIndex ];
 						const layer = data.layers[ attributes.layerIndex ];
 						_object.visible = layer ? data.layers[ attributes.layerIndex ].visible : true;
 						_object.visible = layer ? data.layers[ attributes.layerIndex ].visible : true;
-
 						if ( attributes.isInstanceDefinitionObject ) {
 						if ( attributes.isInstanceDefinitionObject ) {
 
 
 							instanceDefinitionObjects.push( _object );
 							instanceDefinitionObjects.push( _object );
@@ -323,15 +299,12 @@
 
 
 				const iDef = instanceDefinitions[ i ];
 				const iDef = instanceDefinitions[ i ];
 				objects = [];
 				objects = [];
-
 				for ( let j = 0; j < iDef.attributes.objectIds.length; j ++ ) {
 				for ( let j = 0; j < iDef.attributes.objectIds.length; j ++ ) {
 
 
 					const objId = iDef.attributes.objectIds[ j ];
 					const objId = iDef.attributes.objectIds[ j ];
-
 					for ( let p = 0; p < instanceDefinitionObjects.length; p ++ ) {
 					for ( let p = 0; p < instanceDefinitionObjects.length; p ++ ) {
 
 
 						const idoId = instanceDefinitionObjects[ p ].userData.attributes.id;
 						const idoId = instanceDefinitionObjects[ p ].userData.attributes.id;
-
 						if ( objId === idoId ) {
 						if ( objId === idoId ) {
 
 
 							objects.push( instanceDefinitionObjects[ p ] );
 							objects.push( instanceDefinitionObjects[ p ] );
@@ -340,13 +313,13 @@
 
 
 					}
 					}
 
 
-				} // Currently clones geometry and does not take advantage of instancing
+				}
 
 
+				// Currently clones geometry and does not take advantage of instancing
 
 
 				for ( let j = 0; j < instanceReferences.length; j ++ ) {
 				for ( let j = 0; j < instanceReferences.length; j ++ ) {
 
 
 					const iRef = instanceReferences[ j ];
 					const iRef = instanceReferences[ j ];
-
 					if ( iRef.geometry.parentIdefId === iDef.attributes.id ) {
 					if ( iRef.geometry.parentIdefId === iDef.attributes.id ) {
 
 
 						const iRefObject = new THREE.Object3D();
 						const iRefObject = new THREE.Object3D();
@@ -354,7 +327,6 @@
 						const matrix = new THREE.Matrix4();
 						const matrix = new THREE.Matrix4();
 						matrix.set( xf[ 0 ], xf[ 1 ], xf[ 2 ], xf[ 3 ], xf[ 4 ], xf[ 5 ], xf[ 6 ], xf[ 7 ], xf[ 8 ], xf[ 9 ], xf[ 10 ], xf[ 11 ], xf[ 12 ], xf[ 13 ], xf[ 14 ], xf[ 15 ] );
 						matrix.set( xf[ 0 ], xf[ 1 ], xf[ 2 ], xf[ 3 ], xf[ 4 ], xf[ 5 ], xf[ 6 ], xf[ 7 ], xf[ 8 ], xf[ 9 ], xf[ 10 ], xf[ 11 ], xf[ 12 ], xf[ 13 ], xf[ 14 ], xf[ 15 ] );
 						iRefObject.applyMatrix4( matrix );
 						iRefObject.applyMatrix4( matrix );
-
 						for ( let p = 0; p < objects.length; p ++ ) {
 						for ( let p = 0; p < objects.length; p ++ ) {
 
 
 							iRefObject.add( objects[ p ].clone( true ) );
 							iRefObject.add( objects[ p ].clone( true ) );
@@ -373,20 +345,16 @@
 			return object;
 			return object;
 
 
 		}
 		}
-
 		_createObject( obj, mat ) {
 		_createObject( obj, mat ) {
 
 
 			const loader = new THREE.BufferGeometryLoader();
 			const loader = new THREE.BufferGeometryLoader();
 			const attributes = obj.attributes;
 			const attributes = obj.attributes;
-
 			let geometry, material, _color, color;
 			let geometry, material, _color, color;
-
 			switch ( obj.objectType ) {
 			switch ( obj.objectType ) {
 
 
 				case 'Point':
 				case 'Point':
 				case 'PointSet':
 				case 'PointSet':
 					geometry = loader.parse( obj.geometry );
 					geometry = loader.parse( obj.geometry );
-
 					if ( geometry.attributes.hasOwnProperty( 'color' ) ) {
 					if ( geometry.attributes.hasOwnProperty( 'color' ) ) {
 
 
 						material = new THREE.PointsMaterial( {
 						material = new THREE.PointsMaterial( {
@@ -411,7 +379,6 @@
 					const points = new THREE.Points( geometry, material );
 					const points = new THREE.Points( geometry, material );
 					points.userData[ 'attributes' ] = attributes;
 					points.userData[ 'attributes' ] = attributes;
 					points.userData[ 'objectType' ] = obj.objectType;
 					points.userData[ 'objectType' ] = obj.objectType;
-
 					if ( attributes.name ) {
 					if ( attributes.name ) {
 
 
 						points.name = attributes.name;
 						points.name = attributes.name;
@@ -419,14 +386,12 @@
 					}
 					}
 
 
 					return points;
 					return points;
-
 				case 'Mesh':
 				case 'Mesh':
 				case 'Extrusion':
 				case 'Extrusion':
 				case 'SubD':
 				case 'SubD':
 				case 'Brep':
 				case 'Brep':
 					if ( obj.geometry === null ) return;
 					if ( obj.geometry === null ) return;
 					geometry = loader.parse( obj.geometry );
 					geometry = loader.parse( obj.geometry );
-
 					if ( geometry.attributes.hasOwnProperty( 'color' ) ) {
 					if ( geometry.attributes.hasOwnProperty( 'color' ) ) {
 
 
 						mat.vertexColors = true;
 						mat.vertexColors = true;
@@ -445,7 +410,6 @@
 					mesh.receiveShadow = attributes.receivesShadows;
 					mesh.receiveShadow = attributes.receivesShadows;
 					mesh.userData[ 'attributes' ] = attributes;
 					mesh.userData[ 'attributes' ] = attributes;
 					mesh.userData[ 'objectType' ] = obj.objectType;
 					mesh.userData[ 'objectType' ] = obj.objectType;
-
 					if ( attributes.name ) {
 					if ( attributes.name ) {
 
 
 						mesh.name = attributes.name;
 						mesh.name = attributes.name;
@@ -453,7 +417,6 @@
 					}
 					}
 
 
 					return mesh;
 					return mesh;
-
 				case 'Curve':
 				case 'Curve':
 					geometry = loader.parse( obj.geometry );
 					geometry = loader.parse( obj.geometry );
 					_color = attributes.drawColor;
 					_color = attributes.drawColor;
@@ -465,7 +428,6 @@
 					const lines = new THREE.Line( geometry, material );
 					const lines = new THREE.Line( geometry, material );
 					lines.userData[ 'attributes' ] = attributes;
 					lines.userData[ 'attributes' ] = attributes;
 					lines.userData[ 'objectType' ] = obj.objectType;
 					lines.userData[ 'objectType' ] = obj.objectType;
-
 					if ( attributes.name ) {
 					if ( attributes.name ) {
 
 
 						lines.name = attributes.name;
 						lines.name = attributes.name;
@@ -473,7 +435,6 @@
 					}
 					}
 
 
 					return lines;
 					return lines;
-
 				case 'TextDot':
 				case 'TextDot':
 					geometry = obj.geometry;
 					geometry = obj.geometry;
 					const ctx = document.createElement( 'canvas' ).getContext( '2d' );
 					const ctx = document.createElement( 'canvas' ).getContext( '2d' );
@@ -508,7 +469,6 @@
 					sprite.scale.set( width / 10, height / 10, 1.0 );
 					sprite.scale.set( width / 10, height / 10, 1.0 );
 					sprite.userData[ 'attributes' ] = attributes;
 					sprite.userData[ 'attributes' ] = attributes;
 					sprite.userData[ 'objectType' ] = obj.objectType;
 					sprite.userData[ 'objectType' ] = obj.objectType;
-
 					if ( attributes.name ) {
 					if ( attributes.name ) {
 
 
 						sprite.name = attributes.name;
 						sprite.name = attributes.name;
@@ -516,11 +476,9 @@
 					}
 					}
 
 
 					return sprite;
 					return sprite;
-
 				case 'Light':
 				case 'Light':
 					geometry = obj.geometry;
 					geometry = obj.geometry;
 					let light;
 					let light;
-
 					switch ( geometry.lightStyle.name ) {
 					switch ( geometry.lightStyle.name ) {
 
 
 						case 'LightStyle_WorldPoint':
 						case 'LightStyle_WorldPoint':
@@ -529,7 +487,6 @@
 							light.position.set( geometry.location[ 0 ], geometry.location[ 1 ], geometry.location[ 2 ] );
 							light.position.set( geometry.location[ 0 ], geometry.location[ 1 ], geometry.location[ 2 ] );
 							light.shadow.normalBias = 0.1;
 							light.shadow.normalBias = 0.1;
 							break;
 							break;
-
 						case 'LightStyle_WorldSpot':
 						case 'LightStyle_WorldSpot':
 							light = new THREE.SpotLight();
 							light = new THREE.SpotLight();
 							light.castShadow = attributes.castsShadows;
 							light.castShadow = attributes.castsShadows;
@@ -538,7 +495,6 @@
 							light.angle = geometry.spotAngleRadians;
 							light.angle = geometry.spotAngleRadians;
 							light.shadow.normalBias = 0.1;
 							light.shadow.normalBias = 0.1;
 							break;
 							break;
-
 						case 'LightStyle_WorldRectangular':
 						case 'LightStyle_WorldRectangular':
 							light = new THREE.RectAreaLight();
 							light = new THREE.RectAreaLight();
 							const width = Math.abs( geometry.width[ 2 ] );
 							const width = Math.abs( geometry.width[ 2 ] );
@@ -548,7 +504,6 @@
 							light.width = width;
 							light.width = width;
 							light.lookAt( new THREE.Vector3( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] ) );
 							light.lookAt( new THREE.Vector3( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] ) );
 							break;
 							break;
-
 						case 'LightStyle_WorldDirectional':
 						case 'LightStyle_WorldDirectional':
 							light = new THREE.DirectionalLight();
 							light = new THREE.DirectionalLight();
 							light.castShadow = attributes.castsShadows;
 							light.castShadow = attributes.castsShadows;
@@ -556,11 +511,9 @@
 							light.target.position.set( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] );
 							light.target.position.set( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] );
 							light.shadow.normalBias = 0.1;
 							light.shadow.normalBias = 0.1;
 							break;
 							break;
-
 						case 'LightStyle_WorldLinear':
 						case 'LightStyle_WorldLinear':
 							// not conversion exists, warning has already been printed to the console
 							// not conversion exists, warning has already been printed to the console
 							break;
 							break;
-
 						default:
 						default:
 							break;
 							break;
 
 
@@ -582,7 +535,6 @@
 			}
 			}
 
 
 		}
 		}
-
 		_initLibrary() {
 		_initLibrary() {
 
 
 			if ( ! this.libraryPending ) {
 			if ( ! this.libraryPending ) {
@@ -594,8 +546,9 @@
 
 
 					jsLoader.load( 'rhino3dm.js', resolve, undefined, reject );
 					jsLoader.load( 'rhino3dm.js', resolve, undefined, reject );
 
 
-				} ); // Load rhino3dm WASM binary.
+				} );
 
 
+				// Load rhino3dm WASM binary.
 				const binaryLoader = new THREE.FileLoader( this.manager );
 				const binaryLoader = new THREE.FileLoader( this.manager );
 				binaryLoader.setPath( this.libraryPath );
 				binaryLoader.setPath( this.libraryPath );
 				binaryLoader.setResponseType( 'arraybuffer' );
 				binaryLoader.setResponseType( 'arraybuffer' );
@@ -619,7 +572,6 @@
 			return this.libraryPending;
 			return this.libraryPending;
 
 
 		}
 		}
-
 		_getWorker( taskCost ) {
 		_getWorker( taskCost ) {
 
 
 			return this._initLibrary().then( () => {
 			return this._initLibrary().then( () => {
@@ -634,28 +586,21 @@
 						type: 'init',
 						type: 'init',
 						libraryConfig: this.libraryConfig
 						libraryConfig: this.libraryConfig
 					} );
 					} );
-
 					worker.onmessage = e => {
 					worker.onmessage = e => {
 
 
 						const message = e.data;
 						const message = e.data;
-
 						switch ( message.type ) {
 						switch ( message.type ) {
 
 
 							case 'warning':
 							case 'warning':
 								this.warnings.push( message.data );
 								this.warnings.push( message.data );
 								console.warn( message.data );
 								console.warn( message.data );
 								break;
 								break;
-
 							case 'decode':
 							case 'decode':
 								worker._callbacks[ message.id ].resolve( message );
 								worker._callbacks[ message.id ].resolve( message );
-
 								break;
 								break;
-
 							case 'error':
 							case 'error':
 								worker._callbacks[ message.id ].reject( message );
 								worker._callbacks[ message.id ].reject( message );
-
 								break;
 								break;
-
 							default:
 							default:
 								console.error( 'THREE.Rhino3dmLoader: Unexpected message, "' + message.type + '"' );
 								console.error( 'THREE.Rhino3dmLoader: Unexpected message, "' + message.type + '"' );
 
 
@@ -682,7 +627,6 @@
 			} );
 			} );
 
 
 		}
 		}
-
 		_releaseTask( worker, taskID ) {
 		_releaseTask( worker, taskID ) {
 
 
 			worker._taskLoad -= worker._taskCosts[ taskID ];
 			worker._taskLoad -= worker._taskCosts[ taskID ];
@@ -690,7 +634,6 @@
 			delete worker._taskCosts[ taskID ];
 			delete worker._taskCosts[ taskID ];
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			for ( let i = 0; i < this.workerPool.length; ++ i ) {
 			for ( let i = 0; i < this.workerPool.length; ++ i ) {
@@ -705,8 +648,8 @@
 		}
 		}
 
 
 	}
 	}
-	/* WEB WORKER */
 
 
+	/* WEB WORKER */
 
 
 	function Rhino3dmWorker() {
 	function Rhino3dmWorker() {
 
 
@@ -714,11 +657,9 @@
 		let libraryConfig;
 		let libraryConfig;
 		let rhino;
 		let rhino;
 		let taskID;
 		let taskID;
-
 		onmessage = function ( e ) {
 		onmessage = function ( e ) {
 
 
 			const message = e.data;
 			const message = e.data;
-
 			switch ( message.type ) {
 			switch ( message.type ) {
 
 
 				case 'init':
 				case 'init':
@@ -741,7 +682,6 @@
 
 
 					} );
 					} );
 					break;
 					break;
-
 				case 'decode':
 				case 'decode':
 					taskID = message.id;
 					taskID = message.id;
 					const buffer = message.buffer;
 					const buffer = message.buffer;
@@ -783,28 +723,27 @@
 			const views = [];
 			const views = [];
 			const namedViews = [];
 			const namedViews = [];
 			const groups = [];
 			const groups = [];
-			const strings = []; //Handle objects
+			const strings = [];
+
+			//Handle objects
 
 
 			const objs = doc.objects();
 			const objs = doc.objects();
 			const cnt = objs.count;
 			const cnt = objs.count;
-
 			for ( let i = 0; i < cnt; i ++ ) {
 			for ( let i = 0; i < cnt; i ++ ) {
 
 
 				const _object = objs.get( i );
 				const _object = objs.get( i );
-
 				const object = extractObjectData( _object, doc );
 				const object = extractObjectData( _object, doc );
-
 				_object.delete();
 				_object.delete();
-
 				if ( object ) {
 				if ( object ) {
 
 
 					objects.push( object );
 					objects.push( object );
 
 
 				}
 				}
 
 
-			} // Handle instance definitions
-			// console.log( `Instance Definitions Count: ${doc.instanceDefinitions().count()}` );
+			}
 
 
+			// Handle instance definitions
+			// console.log( `Instance Definitions Count: ${doc.instanceDefinitions().count()}` );
 
 
 			for ( let i = 0; i < doc.instanceDefinitions().count(); i ++ ) {
 			for ( let i = 0; i < doc.instanceDefinitions().count(); i ++ ) {
 
 
@@ -817,26 +756,23 @@
 					objectType: 'InstanceDefinition'
 					objectType: 'InstanceDefinition'
 				} );
 				} );
 
 
-			} // Handle materials
+			}
 
 
+			// Handle materials
 
 
-			const textureTypes = [// rhino.TextureType.Bitmap,
+			const textureTypes = [
+				// rhino.TextureType.Bitmap,
 				rhino.TextureType.Diffuse, rhino.TextureType.Bump, rhino.TextureType.Transparency, rhino.TextureType.Opacity, rhino.TextureType.Emap ];
 				rhino.TextureType.Diffuse, rhino.TextureType.Bump, rhino.TextureType.Transparency, rhino.TextureType.Opacity, rhino.TextureType.Emap ];
 			const pbrTextureTypes = [ rhino.TextureType.PBR_BaseColor, rhino.TextureType.PBR_Subsurface, rhino.TextureType.PBR_SubsurfaceScattering, rhino.TextureType.PBR_SubsurfaceScatteringRadius, rhino.TextureType.PBR_Metallic, rhino.TextureType.PBR_Specular, rhino.TextureType.PBR_SpecularTint, rhino.TextureType.PBR_Roughness, rhino.TextureType.PBR_Anisotropic, rhino.TextureType.PBR_Anisotropic_Rotation, rhino.TextureType.PBR_Sheen, rhino.TextureType.PBR_SheenTint, rhino.TextureType.PBR_Clearcoat, rhino.TextureType.PBR_ClearcoatBump, rhino.TextureType.PBR_ClearcoatRoughness, rhino.TextureType.PBR_OpacityIor, rhino.TextureType.PBR_OpacityRoughness, rhino.TextureType.PBR_Emission, rhino.TextureType.PBR_AmbientOcclusion, rhino.TextureType.PBR_Displacement ];
 			const pbrTextureTypes = [ rhino.TextureType.PBR_BaseColor, rhino.TextureType.PBR_Subsurface, rhino.TextureType.PBR_SubsurfaceScattering, rhino.TextureType.PBR_SubsurfaceScatteringRadius, rhino.TextureType.PBR_Metallic, rhino.TextureType.PBR_Specular, rhino.TextureType.PBR_SpecularTint, rhino.TextureType.PBR_Roughness, rhino.TextureType.PBR_Anisotropic, rhino.TextureType.PBR_Anisotropic_Rotation, rhino.TextureType.PBR_Sheen, rhino.TextureType.PBR_SheenTint, rhino.TextureType.PBR_Clearcoat, rhino.TextureType.PBR_ClearcoatBump, rhino.TextureType.PBR_ClearcoatRoughness, rhino.TextureType.PBR_OpacityIor, rhino.TextureType.PBR_OpacityRoughness, rhino.TextureType.PBR_Emission, rhino.TextureType.PBR_AmbientOcclusion, rhino.TextureType.PBR_Displacement ];
-
 			for ( let i = 0; i < doc.materials().count(); i ++ ) {
 			for ( let i = 0; i < doc.materials().count(); i ++ ) {
 
 
 				const _material = doc.materials().get( i );
 				const _material = doc.materials().get( i );
-
 				const _pbrMaterial = _material.physicallyBased();
 				const _pbrMaterial = _material.physicallyBased();
-
 				let material = extractProperties( _material );
 				let material = extractProperties( _material );
 				const textures = [];
 				const textures = [];
-
 				for ( let j = 0; j < textureTypes.length; j ++ ) {
 				for ( let j = 0; j < textureTypes.length; j ++ ) {
 
 
 					const _texture = _material.getTexture( textureTypes[ j ] );
 					const _texture = _material.getTexture( textureTypes[ j ] );
-
 					if ( _texture ) {
 					if ( _texture ) {
 
 
 						let textureType = textureTypes[ j ].constructor.name;
 						let textureType = textureTypes[ j ].constructor.name;
@@ -848,11 +784,8 @@
 						texture.wrapU = _texture.wrapU;
 						texture.wrapU = _texture.wrapU;
 						texture.wrapV = _texture.wrapV;
 						texture.wrapV = _texture.wrapV;
 						texture.wrapW = _texture.wrapW;
 						texture.wrapW = _texture.wrapW;
-
 						const uvw = _texture.uvwTransform.toFloatArray( true );
 						const uvw = _texture.uvwTransform.toFloatArray( true );
-
 						texture.repeat = [ uvw[ 0 ], uvw[ 5 ] ];
 						texture.repeat = [ uvw[ 0 ], uvw[ 5 ] ];
-
 						if ( image ) {
 						if ( image ) {
 
 
 							texture.image = 'data:image/png;base64,' + image;
 							texture.image = 'data:image/png;base64,' + image;
@@ -872,7 +805,6 @@
 						}
 						}
 
 
 						textures.push( texture );
 						textures.push( texture );
-
 						_texture.delete();
 						_texture.delete();
 
 
 					}
 					}
@@ -880,13 +812,11 @@
 				}
 				}
 
 
 				material.textures = textures;
 				material.textures = textures;
-
 				if ( _pbrMaterial.supported ) {
 				if ( _pbrMaterial.supported ) {
 
 
 					for ( let j = 0; j < pbrTextureTypes.length; j ++ ) {
 					for ( let j = 0; j < pbrTextureTypes.length; j ++ ) {
 
 
 						const _texture = _material.getTexture( pbrTextureTypes[ j ] );
 						const _texture = _material.getTexture( pbrTextureTypes[ j ] );
-
 						if ( _texture ) {
 						if ( _texture ) {
 
 
 							const image = doc.getEmbeddedFileAsBase64( _texture.fileName );
 							const image = doc.getEmbeddedFileAsBase64( _texture.fileName );
@@ -897,7 +827,6 @@
 								image: 'data:image/png;base64,' + image
 								image: 'data:image/png;base64,' + image
 							};
 							};
 							textures.push( texture );
 							textures.push( texture );
-
 							_texture.delete();
 							_texture.delete();
 
 
 						}
 						}
@@ -910,74 +839,73 @@
 				}
 				}
 
 
 				materials.push( material );
 				materials.push( material );
-
 				_material.delete();
 				_material.delete();
-
 				_pbrMaterial.delete();
 				_pbrMaterial.delete();
 
 
-			} // Handle layers
+			}
 
 
+			// Handle layers
 
 
 			for ( let i = 0; i < doc.layers().count(); i ++ ) {
 			for ( let i = 0; i < doc.layers().count(); i ++ ) {
 
 
 				const _layer = doc.layers().get( i );
 				const _layer = doc.layers().get( i );
-
 				const layer = extractProperties( _layer );
 				const layer = extractProperties( _layer );
 				layers.push( layer );
 				layers.push( layer );
-
 				_layer.delete();
 				_layer.delete();
 
 
-			} // Handle views
+			}
 
 
+			// Handle views
 
 
 			for ( let i = 0; i < doc.views().count(); i ++ ) {
 			for ( let i = 0; i < doc.views().count(); i ++ ) {
 
 
 				const _view = doc.views().get( i );
 				const _view = doc.views().get( i );
-
 				const view = extractProperties( _view );
 				const view = extractProperties( _view );
 				views.push( view );
 				views.push( view );
-
 				_view.delete();
 				_view.delete();
 
 
-			} // Handle named views
+			}
 
 
+			// Handle named views
 
 
 			for ( let i = 0; i < doc.namedViews().count(); i ++ ) {
 			for ( let i = 0; i < doc.namedViews().count(); i ++ ) {
 
 
 				const _namedView = doc.namedViews().get( i );
 				const _namedView = doc.namedViews().get( i );
-
 				const namedView = extractProperties( _namedView );
 				const namedView = extractProperties( _namedView );
 				namedViews.push( namedView );
 				namedViews.push( namedView );
-
 				_namedView.delete();
 				_namedView.delete();
 
 
-			} // Handle groups
+			}
 
 
+			// Handle groups
 
 
 			for ( let i = 0; i < doc.groups().count(); i ++ ) {
 			for ( let i = 0; i < doc.groups().count(); i ++ ) {
 
 
 				const _group = doc.groups().get( i );
 				const _group = doc.groups().get( i );
-
 				const group = extractProperties( _group );
 				const group = extractProperties( _group );
 				groups.push( group );
 				groups.push( group );
-
 				_group.delete();
 				_group.delete();
 
 
-			} // Handle settings
+			}
+
+			// Handle settings
 
 
+			const settings = extractProperties( doc.settings() );
+
+			//TODO: Handle other document stuff like dimstyles, instance definitions, bitmaps etc.
 
 
-			const settings = extractProperties( doc.settings() ); //TODO: Handle other document stuff like dimstyles, instance definitions, bitmaps etc.
 			// Handle dimstyles
 			// Handle dimstyles
 			// console.log( `Dimstyle Count: ${doc.dimstyles().count()}` );
 			// console.log( `Dimstyle Count: ${doc.dimstyles().count()}` );
+
 			// Handle bitmaps
 			// Handle bitmaps
 			// console.log( `Bitmap Count: ${doc.bitmaps().count()}` );
 			// console.log( `Bitmap Count: ${doc.bitmaps().count()}` );
+
 			// Handle strings
 			// Handle strings
 			// console.log( `Document Strings Count: ${doc.strings().count()}` );
 			// console.log( `Document Strings Count: ${doc.strings().count()}` );
 			// Note: doc.strings().documentUserTextCount() counts any doc.strings defined in a section
 			// Note: doc.strings().documentUserTextCount() counts any doc.strings defined in a section
 			//console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` );
 			//console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` );
 
 
 			const strings_count = doc.strings().count();
 			const strings_count = doc.strings().count();
-
 			for ( let i = 0; i < strings_count; i ++ ) {
 			for ( let i = 0; i < strings_count; i ++ ) {
 
 
 				strings.push( doc.strings().get( i ) );
 				strings.push( doc.strings().get( i ) );
@@ -1001,14 +929,14 @@
 		function extractObjectData( object, doc ) {
 		function extractObjectData( object, doc ) {
 
 
 			const _geometry = object.geometry();
 			const _geometry = object.geometry();
-
 			const _attributes = object.attributes();
 			const _attributes = object.attributes();
-
 			let objectType = _geometry.objectType;
 			let objectType = _geometry.objectType;
-			let geometry, attributes, position, data, mesh; // skip instance definition objects
+			let geometry, attributes, position, data, mesh;
+
+			// skip instance definition objects
 			//if( _attributes.isInstanceDefinitionObject ) { continue; }
 			//if( _attributes.isInstanceDefinitionObject ) { continue; }
-			// TODO: handle other geometry types
 
 
+			// TODO: handle other geometry types
 			switch ( objectType ) {
 			switch ( objectType ) {
 
 
 				case rhino.ObjectType.Curve:
 				case rhino.ObjectType.Curve:
@@ -1019,7 +947,6 @@
 					position.itemSize = 3;
 					position.itemSize = 3;
 					position.type = 'Float32Array';
 					position.type = 'Float32Array';
 					position.array = [];
 					position.array = [];
-
 					for ( let j = 0; j < pts.length; j ++ ) {
 					for ( let j = 0; j < pts.length; j ++ ) {
 
 
 						position.array.push( pts[ j ][ 0 ] );
 						position.array.push( pts[ j ][ 0 ] );
@@ -1034,7 +961,6 @@
 						data
 						data
 					};
 					};
 					break;
 					break;
-
 				case rhino.ObjectType.Point:
 				case rhino.ObjectType.Point:
 					const pt = _geometry.location;
 					const pt = _geometry.location;
 					position = {};
 					position = {};
@@ -1044,9 +970,7 @@
 					position.itemSize = 3;
 					position.itemSize = 3;
 					position.type = 'Float32Array';
 					position.type = 'Float32Array';
 					position.array = [ pt[ 0 ], pt[ 1 ], pt[ 2 ] ];
 					position.array = [ pt[ 0 ], pt[ 1 ], pt[ 2 ] ];
-
 					const _color = _attributes.drawColor( doc );
 					const _color = _attributes.drawColor( doc );
-
 					color.itemSize = 3;
 					color.itemSize = 3;
 					color.type = 'Float32Array';
 					color.type = 'Float32Array';
 					color.array = [ _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 ];
 					color.array = [ _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 ];
@@ -1057,27 +981,20 @@
 						data
 						data
 					};
 					};
 					break;
 					break;
-
 				case rhino.ObjectType.PointSet:
 				case rhino.ObjectType.PointSet:
 				case rhino.ObjectType.Mesh:
 				case rhino.ObjectType.Mesh:
 					geometry = _geometry.toThreejsJSON();
 					geometry = _geometry.toThreejsJSON();
 					break;
 					break;
-
 				case rhino.ObjectType.Brep:
 				case rhino.ObjectType.Brep:
 					const faces = _geometry.faces();
 					const faces = _geometry.faces();
-
 					mesh = new rhino.Mesh();
 					mesh = new rhino.Mesh();
-
 					for ( let faceIndex = 0; faceIndex < faces.count; faceIndex ++ ) {
 					for ( let faceIndex = 0; faceIndex < faces.count; faceIndex ++ ) {
 
 
 						const face = faces.get( faceIndex );
 						const face = faces.get( faceIndex );
-
 						const _mesh = face.getMesh( rhino.MeshType.Any );
 						const _mesh = face.getMesh( rhino.MeshType.Any );
-
 						if ( _mesh ) {
 						if ( _mesh ) {
 
 
 							mesh.append( _mesh );
 							mesh.append( _mesh );
-
 							_mesh.delete();
 							_mesh.delete();
 
 
 						}
 						}
@@ -1096,10 +1013,8 @@
 
 
 					mesh.delete();
 					mesh.delete();
 					break;
 					break;
-
 				case rhino.ObjectType.Extrusion:
 				case rhino.ObjectType.Extrusion:
 					mesh = _geometry.getMesh( rhino.MeshType.Any );
 					mesh = _geometry.getMesh( rhino.MeshType.Any );
-
 					if ( mesh ) {
 					if ( mesh ) {
 
 
 						geometry = mesh.toThreejsJSON();
 						geometry = mesh.toThreejsJSON();
@@ -1108,14 +1023,11 @@
 					}
 					}
 
 
 					break;
 					break;
-
 				case rhino.ObjectType.TextDot:
 				case rhino.ObjectType.TextDot:
 					geometry = extractProperties( _geometry );
 					geometry = extractProperties( _geometry );
 					break;
 					break;
-
 				case rhino.ObjectType.Light:
 				case rhino.ObjectType.Light:
 					geometry = extractProperties( _geometry );
 					geometry = extractProperties( _geometry );
-
 					if ( geometry.lightStyle.name === 'LightStyle_WorldLinear' ) {
 					if ( geometry.lightStyle.name === 'LightStyle_WorldLinear' ) {
 
 
 						self.postMessage( {
 						self.postMessage( {
@@ -1131,19 +1043,15 @@
 					}
 					}
 
 
 					break;
 					break;
-
 				case rhino.ObjectType.InstanceReference:
 				case rhino.ObjectType.InstanceReference:
 					geometry = extractProperties( _geometry );
 					geometry = extractProperties( _geometry );
 					geometry.xform = extractProperties( _geometry.xform );
 					geometry.xform = extractProperties( _geometry.xform );
 					geometry.xform.array = _geometry.xform.toFloatArray( true );
 					geometry.xform.array = _geometry.xform.toFloatArray( true );
 					break;
 					break;
-
 				case rhino.ObjectType.SubD:
 				case rhino.ObjectType.SubD:
 					// TODO: precalculate resulting vertices and faces and warn on excessive results
 					// TODO: precalculate resulting vertices and faces and warn on excessive results
 					_geometry.subdivide( 3 );
 					_geometry.subdivide( 3 );
-
 					mesh = rhino.Mesh.createFromSubDControlNet( _geometry );
 					mesh = rhino.Mesh.createFromSubDControlNet( _geometry );
-
 					if ( mesh ) {
 					if ( mesh ) {
 
 
 						geometry = mesh.toThreejsJSON();
 						geometry = mesh.toThreejsJSON();
@@ -1177,7 +1085,6 @@
 
 
 				attributes = extractProperties( _attributes );
 				attributes = extractProperties( _attributes );
 				attributes.geometry = extractProperties( _geometry );
 				attributes.geometry = extractProperties( _geometry );
-
 				if ( _attributes.groupCount > 0 ) {
 				if ( _attributes.groupCount > 0 ) {
 
 
 					attributes.groupIds = _attributes.getGroupList();
 					attributes.groupIds = _attributes.getGroupList();
@@ -1224,11 +1131,9 @@
 		function extractProperties( object ) {
 		function extractProperties( object ) {
 
 
 			const result = {};
 			const result = {};
-
 			for ( const property in object ) {
 			for ( const property in object ) {
 
 
 				const value = object[ property ];
 				const value = object[ property ];
-
 				if ( typeof value !== 'function' ) {
 				if ( typeof value !== 'function' ) {
 
 
 					if ( typeof value === 'object' && value !== null && value.hasOwnProperty( 'constructor' ) ) {
 					if ( typeof value === 'object' && value !== null && value.hasOwnProperty( 'constructor' ) ) {
@@ -1244,7 +1149,9 @@
 
 
 					}
 					}
 
 
-				} else { // these are functions that could be called to extract more data.
+				} else {
+
+					// these are functions that could be called to extract more data.
 					//console.log( `${property}: ${object[ property ].constructor.name}` );
 					//console.log( `${property}: ${object[ property ].constructor.name}` );
 				}
 				}
 
 
@@ -1259,7 +1166,6 @@
 			let pointCount = pointLimit;
 			let pointCount = pointLimit;
 			let rc = [];
 			let rc = [];
 			const ts = [];
 			const ts = [];
-
 			if ( curve instanceof rhino.LineCurve ) {
 			if ( curve instanceof rhino.LineCurve ) {
 
 
 				return [ curve.pointAtStart, curve.pointAtEnd ];
 				return [ curve.pointAtStart, curve.pointAtEnd ];
@@ -1269,7 +1175,6 @@
 			if ( curve instanceof rhino.PolylineCurve ) {
 			if ( curve instanceof rhino.PolylineCurve ) {
 
 
 				pointCount = curve.pointCount;
 				pointCount = curve.pointCount;
-
 				for ( let i = 0; i < pointCount; i ++ ) {
 				for ( let i = 0; i < pointCount; i ++ ) {
 
 
 					rc.push( curve.point( i ) );
 					rc.push( curve.point( i ) );
@@ -1283,7 +1188,6 @@
 			if ( curve instanceof rhino.PolyCurve ) {
 			if ( curve instanceof rhino.PolyCurve ) {
 
 
 				const segmentCount = curve.segmentCount;
 				const segmentCount = curve.segmentCount;
-
 				for ( let i = 0; i < segmentCount; i ++ ) {
 				for ( let i = 0; i < segmentCount; i ++ ) {
 
 
 					const segment = curve.segmentCurve( i );
 					const segment = curve.segmentCurve( i );
@@ -1300,14 +1204,14 @@
 			if ( curve instanceof rhino.ArcCurve ) {
 			if ( curve instanceof rhino.ArcCurve ) {
 
 
 				pointCount = Math.floor( curve.angleDegrees / 5 );
 				pointCount = Math.floor( curve.angleDegrees / 5 );
-				pointCount = pointCount < 2 ? 2 : pointCount; // alternative to this hardcoded version: https://stackoverflow.com/a/18499923/2179399
+				pointCount = pointCount < 2 ? 2 : pointCount;
+				// alternative to this hardcoded version: https://stackoverflow.com/a/18499923/2179399
 
 
 			}
 			}
 
 
 			if ( curve instanceof rhino.NurbsCurve && curve.degree === 1 ) {
 			if ( curve instanceof rhino.NurbsCurve && curve.degree === 1 ) {
 
 
 				const pLine = curve.tryGetPolyline();
 				const pLine = curve.tryGetPolyline();
-
 				for ( let i = 0; i < pLine.count; i ++ ) {
 				for ( let i = 0; i < pLine.count; i ++ ) {
 
 
 					rc.push( pLine.get( i ) );
 					rc.push( pLine.get( i ) );
@@ -1321,11 +1225,9 @@
 
 
 			const domain = curve.domain;
 			const domain = curve.domain;
 			const divisions = pointCount - 1.0;
 			const divisions = pointCount - 1.0;
-
 			for ( let j = 0; j < pointCount; j ++ ) {
 			for ( let j = 0; j < pointCount; j ++ ) {
 
 
 				const t = domain[ 0 ] + j / divisions * ( domain[ 1 ] - domain[ 0 ] );
 				const t = domain[ 0 ] + j / divisions * ( domain[ 1 ] - domain[ 0 ] );
-
 				if ( t === domain[ 0 ] || t === domain[ 1 ] ) {
 				if ( t === domain[ 0 ] || t === domain[ 1 ] ) {
 
 
 					ts.push( t );
 					ts.push( t );
@@ -1334,14 +1236,15 @@
 				}
 				}
 
 
 				const tan = curve.tangentAt( t );
 				const tan = curve.tangentAt( t );
-				const prevTan = curve.tangentAt( ts.slice( - 1 )[ 0 ] ); // Duplicated from THREE.Vector3
+				const prevTan = curve.tangentAt( ts.slice( - 1 )[ 0 ] );
+
+				// Duplicated from THREE.Vector3
 				// How to pass imports to worker?
 				// How to pass imports to worker?
 
 
 				const tS = tan[ 0 ] * tan[ 0 ] + tan[ 1 ] * tan[ 1 ] + tan[ 2 ] * tan[ 2 ];
 				const tS = tan[ 0 ] * tan[ 0 ] + tan[ 1 ] * tan[ 1 ] + tan[ 2 ] * tan[ 2 ];
 				const ptS = prevTan[ 0 ] * prevTan[ 0 ] + prevTan[ 1 ] * prevTan[ 1 ] + prevTan[ 2 ] * prevTan[ 2 ];
 				const ptS = prevTan[ 0 ] * prevTan[ 0 ] + prevTan[ 1 ] * prevTan[ 1 ] + prevTan[ 2 ] * prevTan[ 2 ];
 				const denominator = Math.sqrt( tS * ptS );
 				const denominator = Math.sqrt( tS * ptS );
 				let angle;
 				let angle;
-
 				if ( denominator === 0 ) {
 				if ( denominator === 0 ) {
 
 
 					angle = Math.PI / 2;
 					angle = Math.PI / 2;

+ 72 - 106
examples/js/loaders/3MFLoader.js

@@ -26,7 +26,6 @@
 			this.availableExtensions = [];
 			this.availableExtensions = [];
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -60,12 +59,10 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			const scope = this;
 			const scope = this;
 			const textureLoader = new THREE.TextureLoader( this.manager );
 			const textureLoader = new THREE.TextureLoader( this.manager );
-
 			function loadDocument( data ) {
 			function loadDocument( data ) {
 
 
 				let zip = null;
 				let zip = null;
@@ -78,7 +75,6 @@
 				const modelParts = {};
 				const modelParts = {};
 				const printTicketParts = {};
 				const printTicketParts = {};
 				const texturesParts = {};
 				const texturesParts = {};
-
 				try {
 				try {
 
 
 					zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef
 					zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef
@@ -114,12 +110,15 @@
 
 
 					}
 					}
 
 
-				} //
+				}
 
 
+				//
 
 
 				const relsView = zip[ relsName ];
 				const relsView = zip[ relsName ];
 				const relsFileText = THREE.LoaderUtils.decodeText( relsView );
 				const relsFileText = THREE.LoaderUtils.decodeText( relsView );
-				const rels = parseRelsXml( relsFileText ); //
+				const rels = parseRelsXml( relsFileText );
+
+				//
 
 
 				if ( modelRelsName ) {
 				if ( modelRelsName ) {
 
 
@@ -127,8 +126,9 @@
 					const relsFileText = THREE.LoaderUtils.decodeText( relsView );
 					const relsFileText = THREE.LoaderUtils.decodeText( relsView );
 					modelRels = parseRelsXml( relsFileText );
 					modelRels = parseRelsXml( relsFileText );
 
 
-				} //
+				}
 
 
+				//
 
 
 				for ( let i = 0; i < modelPartNames.length; i ++ ) {
 				for ( let i = 0; i < modelPartNames.length; i ++ ) {
 
 
@@ -136,7 +136,6 @@
 					const view = zip[ modelPart ];
 					const view = zip[ modelPart ];
 					const fileText = THREE.LoaderUtils.decodeText( view );
 					const fileText = THREE.LoaderUtils.decodeText( view );
 					const xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
 					const xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
-
 					if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) {
 					if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) {
 
 
 						console.error( 'THREE.3MFLoader: Error loading 3MF - no 3MF document found: ', modelPart );
 						console.error( 'THREE.3MFLoader: Error loading 3MF - no 3MF document found: ', modelPart );
@@ -145,11 +144,9 @@
 
 
 					const modelNode = xmlData.querySelector( 'model' );
 					const modelNode = xmlData.querySelector( 'model' );
 					const extensions = {};
 					const extensions = {};
-
 					for ( let i = 0; i < modelNode.attributes.length; i ++ ) {
 					for ( let i = 0; i < modelNode.attributes.length; i ++ ) {
 
 
 						const attr = modelNode.attributes[ i ];
 						const attr = modelNode.attributes[ i ];
-
 						if ( attr.name.match( /^xmlns:(.+)$/ ) ) {
 						if ( attr.name.match( /^xmlns:(.+)$/ ) ) {
 
 
 							extensions[ attr.value ] = RegExp.$1;
 							extensions[ attr.value ] = RegExp.$1;
@@ -160,7 +157,6 @@
 
 
 					const modelData = parseModelNode( modelNode );
 					const modelData = parseModelNode( modelNode );
 					modelData[ 'xml' ] = modelNode;
 					modelData[ 'xml' ] = modelNode;
-
 					if ( 0 < Object.keys( extensions ).length ) {
 					if ( 0 < Object.keys( extensions ).length ) {
 
 
 						modelData[ 'extensions' ] = extensions;
 						modelData[ 'extensions' ] = extensions;
@@ -169,8 +165,9 @@
 
 
 					modelParts[ modelPart ] = modelData;
 					modelParts[ modelPart ] = modelData;
 
 
-				} //
+				}
 
 
+				//
 
 
 				for ( let i = 0; i < texturesPartNames.length; i ++ ) {
 				for ( let i = 0; i < texturesPartNames.length; i ++ ) {
 
 
@@ -194,7 +191,6 @@
 				const relationships = [];
 				const relationships = [];
 				const relsXmlData = new DOMParser().parseFromString( relsFileText, 'application/xml' );
 				const relsXmlData = new DOMParser().parseFromString( relsFileText, 'application/xml' );
 				const relsNodes = relsXmlData.querySelectorAll( 'Relationship' );
 				const relsNodes = relsXmlData.querySelectorAll( 'Relationship' );
-
 				for ( let i = 0; i < relsNodes.length; i ++ ) {
 				for ( let i = 0; i < relsNodes.length; i ++ ) {
 
 
 					const relsNode = relsNodes[ i ];
 					const relsNode = relsNodes[ i ];
@@ -204,8 +200,8 @@
 						id: relsNode.getAttribute( 'Id' ),
 						id: relsNode.getAttribute( 'Id' ),
 						//required
 						//required
 						type: relsNode.getAttribute( 'Type' ) //required
 						type: relsNode.getAttribute( 'Type' ) //required
-
 					};
 					};
+
 					relationships.push( relationship );
 					relationships.push( relationship );
 
 
 				}
 				}
@@ -217,13 +213,11 @@
 			function parseMetadataNodes( metadataNodes ) {
 			function parseMetadataNodes( metadataNodes ) {
 
 
 				const metadataData = {};
 				const metadataData = {};
-
 				for ( let i = 0; i < metadataNodes.length; i ++ ) {
 				for ( let i = 0; i < metadataNodes.length; i ++ ) {
 
 
 					const metadataNode = metadataNodes[ i ];
 					const metadataNode = metadataNodes[ i ];
 					const name = metadataNode.getAttribute( 'name' );
 					const name = metadataNode.getAttribute( 'name' );
 					const validNames = [ 'Title', 'Designer', 'Description', 'Copyright', 'LicenseTerms', 'Rating', 'CreationDate', 'ModificationDate' ];
 					const validNames = [ 'Title', 'Designer', 'Description', 'Copyright', 'LicenseTerms', 'Rating', 'CreationDate', 'ModificationDate' ];
-
 					if ( 0 <= validNames.indexOf( name ) ) {
 					if ( 0 <= validNames.indexOf( name ) ) {
 
 
 						metadataData[ name ] = metadataNode.textContent;
 						metadataData[ name ] = metadataNode.textContent;
@@ -244,13 +238,11 @@
 					basematerials: []
 					basematerials: []
 				};
 				};
 				const basematerialNodes = basematerialsNode.querySelectorAll( 'base' );
 				const basematerialNodes = basematerialsNode.querySelectorAll( 'base' );
-
 				for ( let i = 0; i < basematerialNodes.length; i ++ ) {
 				for ( let i = 0; i < basematerialNodes.length; i ++ ) {
 
 
 					const basematerialNode = basematerialNodes[ i ];
 					const basematerialNode = basematerialNodes[ i ];
 					const basematerialData = parseBasematerialNode( basematerialNode );
 					const basematerialData = parseBasematerialNode( basematerialNode );
 					basematerialData.index = i; // the order and count of the material nodes form an implicit 0-based index
 					basematerialData.index = i; // the order and count of the material nodes form an implicit 0-based index
-
 					basematerialsData.basematerials.push( basematerialData );
 					basematerialsData.basematerials.push( basematerialData );
 
 
 				}
 				}
@@ -287,7 +279,6 @@
 				};
 				};
 				const tex2coordNodes = texture2DGroupNode.querySelectorAll( 'tex2coord' );
 				const tex2coordNodes = texture2DGroupNode.querySelectorAll( 'tex2coord' );
 				const uvs = [];
 				const uvs = [];
-
 				for ( let i = 0; i < tex2coordNodes.length; i ++ ) {
 				for ( let i = 0; i < tex2coordNodes.length; i ++ ) {
 
 
 					const tex2coordNode = tex2coordNodes[ i ];
 					const tex2coordNode = tex2coordNodes[ i ];
@@ -312,7 +303,6 @@
 				const colorNodes = colorGroupNode.querySelectorAll( 'color' );
 				const colorNodes = colorGroupNode.querySelectorAll( 'color' );
 				const colors = [];
 				const colors = [];
 				const colorObject = new THREE.Color();
 				const colorObject = new THREE.Color();
-
 				for ( let i = 0; i < colorNodes.length; i ++ ) {
 				for ( let i = 0; i < colorNodes.length; i ++ ) {
 
 
 					const colorNode = colorNodes[ i ];
 					const colorNode = colorNodes[ i ];
@@ -333,11 +323,10 @@
 
 
 				const metallicDisplaypropertiesData = {
 				const metallicDisplaypropertiesData = {
 					id: metallicDisplaypropetiesNode.getAttribute( 'id' ) // required
 					id: metallicDisplaypropetiesNode.getAttribute( 'id' ) // required
-
 				};
 				};
+
 				const metallicNodes = metallicDisplaypropetiesNode.querySelectorAll( 'pbmetallic' );
 				const metallicNodes = metallicDisplaypropetiesNode.querySelectorAll( 'pbmetallic' );
 				const metallicData = [];
 				const metallicData = [];
-
 				for ( let i = 0; i < metallicNodes.length; i ++ ) {
 				for ( let i = 0; i < metallicNodes.length; i ++ ) {
 
 
 					const metallicNode = metallicNodes[ i ];
 					const metallicNode = metallicNodes[ i ];
@@ -347,7 +336,6 @@
 						metallicness: parseFloat( metallicNode.getAttribute( 'metallicness' ) ),
 						metallicness: parseFloat( metallicNode.getAttribute( 'metallicness' ) ),
 						// required
 						// required
 						roughness: parseFloat( metallicNode.getAttribute( 'roughness' ) ) // required
 						roughness: parseFloat( metallicNode.getAttribute( 'roughness' ) ) // required
-
 					} );
 					} );
 
 
 				}
 				}
@@ -361,9 +349,7 @@
 
 
 				const basematerialData = {};
 				const basematerialData = {};
 				basematerialData[ 'name' ] = basematerialNode.getAttribute( 'name' ); // required
 				basematerialData[ 'name' ] = basematerialNode.getAttribute( 'name' ); // required
-
 				basematerialData[ 'displaycolor' ] = basematerialNode.getAttribute( 'displaycolor' ); // required
 				basematerialData[ 'displaycolor' ] = basematerialNode.getAttribute( 'displaycolor' ); // required
-
 				basematerialData[ 'displaypropertiesid' ] = basematerialNode.getAttribute( 'displaypropertiesid' );
 				basematerialData[ 'displaypropertiesid' ] = basematerialNode.getAttribute( 'displaypropertiesid' );
 				return basematerialData;
 				return basematerialData;
 
 
@@ -374,7 +360,6 @@
 				const meshData = {};
 				const meshData = {};
 				const vertices = [];
 				const vertices = [];
 				const vertexNodes = meshNode.querySelectorAll( 'vertices vertex' );
 				const vertexNodes = meshNode.querySelectorAll( 'vertices vertex' );
-
 				for ( let i = 0; i < vertexNodes.length; i ++ ) {
 				for ( let i = 0; i < vertexNodes.length; i ++ ) {
 
 
 					const vertexNode = vertexNodes[ i ];
 					const vertexNode = vertexNodes[ i ];
@@ -389,7 +374,6 @@
 				const triangleProperties = [];
 				const triangleProperties = [];
 				const triangles = [];
 				const triangles = [];
 				const triangleNodes = meshNode.querySelectorAll( 'triangles triangle' );
 				const triangleNodes = meshNode.querySelectorAll( 'triangles triangle' );
-
 				for ( let i = 0; i < triangleNodes.length; i ++ ) {
 				for ( let i = 0; i < triangleNodes.length; i ++ ) {
 
 
 					const triangleNode = triangleNodes[ i ];
 					const triangleNode = triangleNodes[ i ];
@@ -404,7 +388,9 @@
 					triangleProperty[ 'v1' ] = parseInt( v1, 10 );
 					triangleProperty[ 'v1' ] = parseInt( v1, 10 );
 					triangleProperty[ 'v2' ] = parseInt( v2, 10 );
 					triangleProperty[ 'v2' ] = parseInt( v2, 10 );
 					triangleProperty[ 'v3' ] = parseInt( v3, 10 );
 					triangleProperty[ 'v3' ] = parseInt( v3, 10 );
-					triangles.push( triangleProperty[ 'v1' ], triangleProperty[ 'v2' ], triangleProperty[ 'v3' ] ); // optional
+					triangles.push( triangleProperty[ 'v1' ], triangleProperty[ 'v2' ], triangleProperty[ 'v3' ] );
+
+					// optional
 
 
 					if ( p1 ) {
 					if ( p1 ) {
 
 
@@ -448,7 +434,6 @@
 
 
 				const components = [];
 				const components = [];
 				const componentNodes = componentsNode.querySelectorAll( 'component' );
 				const componentNodes = componentsNode.querySelectorAll( 'component' );
-
 				for ( let i = 0; i < componentNodes.length; i ++ ) {
 				for ( let i = 0; i < componentNodes.length; i ++ ) {
 
 
 					const componentNode = componentNodes[ i ];
 					const componentNode = componentNodes[ i ];
@@ -467,7 +452,6 @@
 				componentData[ 'objectId' ] = componentNode.getAttribute( 'objectid' ); // required
 				componentData[ 'objectId' ] = componentNode.getAttribute( 'objectid' ); // required
 
 
 				const transform = componentNode.getAttribute( 'transform' );
 				const transform = componentNode.getAttribute( 'transform' );
-
 				if ( transform ) {
 				if ( transform ) {
 
 
 					componentData[ 'transform' ] = parseTransform( transform );
 					componentData[ 'transform' ] = parseTransform( transform );
@@ -498,7 +482,6 @@
 					type: objectNode.getAttribute( 'type' )
 					type: objectNode.getAttribute( 'type' )
 				};
 				};
 				const id = objectNode.getAttribute( 'id' );
 				const id = objectNode.getAttribute( 'id' );
-
 				if ( id ) {
 				if ( id ) {
 
 
 					objectData[ 'id' ] = id;
 					objectData[ 'id' ] = id;
@@ -506,7 +489,6 @@
 				}
 				}
 
 
 				const pid = objectNode.getAttribute( 'pid' );
 				const pid = objectNode.getAttribute( 'pid' );
-
 				if ( pid ) {
 				if ( pid ) {
 
 
 					objectData[ 'pid' ] = pid;
 					objectData[ 'pid' ] = pid;
@@ -514,7 +496,6 @@
 				}
 				}
 
 
 				const pindex = objectNode.getAttribute( 'pindex' );
 				const pindex = objectNode.getAttribute( 'pindex' );
-
 				if ( pindex ) {
 				if ( pindex ) {
 
 
 					objectData[ 'pindex' ] = pindex;
 					objectData[ 'pindex' ] = pindex;
@@ -522,7 +503,6 @@
 				}
 				}
 
 
 				const thumbnail = objectNode.getAttribute( 'thumbnail' );
 				const thumbnail = objectNode.getAttribute( 'thumbnail' );
-
 				if ( thumbnail ) {
 				if ( thumbnail ) {
 
 
 					objectData[ 'thumbnail' ] = thumbnail;
 					objectData[ 'thumbnail' ] = thumbnail;
@@ -530,7 +510,6 @@
 				}
 				}
 
 
 				const partnumber = objectNode.getAttribute( 'partnumber' );
 				const partnumber = objectNode.getAttribute( 'partnumber' );
-
 				if ( partnumber ) {
 				if ( partnumber ) {
 
 
 					objectData[ 'partnumber' ] = partnumber;
 					objectData[ 'partnumber' ] = partnumber;
@@ -538,7 +517,6 @@
 				}
 				}
 
 
 				const name = objectNode.getAttribute( 'name' );
 				const name = objectNode.getAttribute( 'name' );
-
 				if ( name ) {
 				if ( name ) {
 
 
 					objectData[ 'name' ] = name;
 					objectData[ 'name' ] = name;
@@ -546,7 +524,6 @@
 				}
 				}
 
 
 				const meshNode = objectNode.querySelector( 'mesh' );
 				const meshNode = objectNode.querySelector( 'mesh' );
-
 				if ( meshNode ) {
 				if ( meshNode ) {
 
 
 					objectData[ 'mesh' ] = parseMeshNode( meshNode );
 					objectData[ 'mesh' ] = parseMeshNode( meshNode );
@@ -554,7 +531,6 @@
 				}
 				}
 
 
 				const componentsNode = objectNode.querySelector( 'components' );
 				const componentsNode = objectNode.querySelector( 'components' );
-
 				if ( componentsNode ) {
 				if ( componentsNode ) {
 
 
 					objectData[ 'components' ] = parseComponentsNode( componentsNode );
 					objectData[ 'components' ] = parseComponentsNode( componentsNode );
@@ -570,67 +546,66 @@
 				const resourcesData = {};
 				const resourcesData = {};
 				resourcesData[ 'basematerials' ] = {};
 				resourcesData[ 'basematerials' ] = {};
 				const basematerialsNodes = resourcesNode.querySelectorAll( 'basematerials' );
 				const basematerialsNodes = resourcesNode.querySelectorAll( 'basematerials' );
-
 				for ( let i = 0; i < basematerialsNodes.length; i ++ ) {
 				for ( let i = 0; i < basematerialsNodes.length; i ++ ) {
 
 
 					const basematerialsNode = basematerialsNodes[ i ];
 					const basematerialsNode = basematerialsNodes[ i ];
 					const basematerialsData = parseBasematerialsNode( basematerialsNode );
 					const basematerialsData = parseBasematerialsNode( basematerialsNode );
 					resourcesData[ 'basematerials' ][ basematerialsData[ 'id' ] ] = basematerialsData;
 					resourcesData[ 'basematerials' ][ basematerialsData[ 'id' ] ] = basematerialsData;
 
 
-				} //
+				}
 
 
+				//
 
 
 				resourcesData[ 'texture2d' ] = {};
 				resourcesData[ 'texture2d' ] = {};
 				const textures2DNodes = resourcesNode.querySelectorAll( 'texture2d' );
 				const textures2DNodes = resourcesNode.querySelectorAll( 'texture2d' );
-
 				for ( let i = 0; i < textures2DNodes.length; i ++ ) {
 				for ( let i = 0; i < textures2DNodes.length; i ++ ) {
 
 
 					const textures2DNode = textures2DNodes[ i ];
 					const textures2DNode = textures2DNodes[ i ];
 					const texture2DData = parseTexture2DNode( textures2DNode );
 					const texture2DData = parseTexture2DNode( textures2DNode );
 					resourcesData[ 'texture2d' ][ texture2DData[ 'id' ] ] = texture2DData;
 					resourcesData[ 'texture2d' ][ texture2DData[ 'id' ] ] = texture2DData;
 
 
-				} //
+				}
 
 
+				//
 
 
 				resourcesData[ 'colorgroup' ] = {};
 				resourcesData[ 'colorgroup' ] = {};
 				const colorGroupNodes = resourcesNode.querySelectorAll( 'colorgroup' );
 				const colorGroupNodes = resourcesNode.querySelectorAll( 'colorgroup' );
-
 				for ( let i = 0; i < colorGroupNodes.length; i ++ ) {
 				for ( let i = 0; i < colorGroupNodes.length; i ++ ) {
 
 
 					const colorGroupNode = colorGroupNodes[ i ];
 					const colorGroupNode = colorGroupNodes[ i ];
 					const colorGroupData = parseColorGroupNode( colorGroupNode );
 					const colorGroupData = parseColorGroupNode( colorGroupNode );
 					resourcesData[ 'colorgroup' ][ colorGroupData[ 'id' ] ] = colorGroupData;
 					resourcesData[ 'colorgroup' ][ colorGroupData[ 'id' ] ] = colorGroupData;
 
 
-				} //
+				}
 
 
+				//
 
 
 				resourcesData[ 'pbmetallicdisplayproperties' ] = {};
 				resourcesData[ 'pbmetallicdisplayproperties' ] = {};
 				const pbmetallicdisplaypropertiesNodes = resourcesNode.querySelectorAll( 'pbmetallicdisplayproperties' );
 				const pbmetallicdisplaypropertiesNodes = resourcesNode.querySelectorAll( 'pbmetallicdisplayproperties' );
-
 				for ( let i = 0; i < pbmetallicdisplaypropertiesNodes.length; i ++ ) {
 				for ( let i = 0; i < pbmetallicdisplaypropertiesNodes.length; i ++ ) {
 
 
 					const pbmetallicdisplaypropertiesNode = pbmetallicdisplaypropertiesNodes[ i ];
 					const pbmetallicdisplaypropertiesNode = pbmetallicdisplaypropertiesNodes[ i ];
 					const pbmetallicdisplaypropertiesData = parseMetallicDisplaypropertiesNode( pbmetallicdisplaypropertiesNode );
 					const pbmetallicdisplaypropertiesData = parseMetallicDisplaypropertiesNode( pbmetallicdisplaypropertiesNode );
 					resourcesData[ 'pbmetallicdisplayproperties' ][ pbmetallicdisplaypropertiesData[ 'id' ] ] = pbmetallicdisplaypropertiesData;
 					resourcesData[ 'pbmetallicdisplayproperties' ][ pbmetallicdisplaypropertiesData[ 'id' ] ] = pbmetallicdisplaypropertiesData;
 
 
-				} //
+				}
 
 
+				//
 
 
 				resourcesData[ 'texture2dgroup' ] = {};
 				resourcesData[ 'texture2dgroup' ] = {};
 				const textures2DGroupNodes = resourcesNode.querySelectorAll( 'texture2dgroup' );
 				const textures2DGroupNodes = resourcesNode.querySelectorAll( 'texture2dgroup' );
-
 				for ( let i = 0; i < textures2DGroupNodes.length; i ++ ) {
 				for ( let i = 0; i < textures2DGroupNodes.length; i ++ ) {
 
 
 					const textures2DGroupNode = textures2DGroupNodes[ i ];
 					const textures2DGroupNode = textures2DGroupNodes[ i ];
 					const textures2DGroupData = parseTextures2DGroupNode( textures2DGroupNode );
 					const textures2DGroupData = parseTextures2DGroupNode( textures2DGroupNode );
 					resourcesData[ 'texture2dgroup' ][ textures2DGroupData[ 'id' ] ] = textures2DGroupData;
 					resourcesData[ 'texture2dgroup' ][ textures2DGroupData[ 'id' ] ] = textures2DGroupData;
 
 
-				} //
+				}
 
 
+				//
 
 
 				resourcesData[ 'object' ] = {};
 				resourcesData[ 'object' ] = {};
 				const objectNodes = resourcesNode.querySelectorAll( 'object' );
 				const objectNodes = resourcesNode.querySelectorAll( 'object' );
-
 				for ( let i = 0; i < objectNodes.length; i ++ ) {
 				for ( let i = 0; i < objectNodes.length; i ++ ) {
 
 
 					const objectNode = objectNodes[ i ];
 					const objectNode = objectNodes[ i ];
@@ -647,7 +622,6 @@
 
 
 				const buildData = [];
 				const buildData = [];
 				const itemNodes = buildNode.querySelectorAll( 'item' );
 				const itemNodes = buildNode.querySelectorAll( 'item' );
-
 				for ( let i = 0; i < itemNodes.length; i ++ ) {
 				for ( let i = 0; i < itemNodes.length; i ++ ) {
 
 
 					const itemNode = itemNodes[ i ];
 					const itemNode = itemNodes[ i ];
@@ -655,7 +629,6 @@
 						objectId: itemNode.getAttribute( 'objectid' )
 						objectId: itemNode.getAttribute( 'objectid' )
 					};
 					};
 					const transform = itemNode.getAttribute( 'transform' );
 					const transform = itemNode.getAttribute( 'transform' );
-
 					if ( transform ) {
 					if ( transform ) {
 
 
 						buildItem[ 'transform' ] = parseTransform( transform );
 						buildItem[ 'transform' ] = parseTransform( transform );
@@ -676,7 +649,6 @@
 					unit: modelNode.getAttribute( 'unit' ) || 'millimeter'
 					unit: modelNode.getAttribute( 'unit' ) || 'millimeter'
 				};
 				};
 				const metadataNodes = modelNode.querySelectorAll( 'metadata' );
 				const metadataNodes = modelNode.querySelectorAll( 'metadata' );
-
 				if ( metadataNodes ) {
 				if ( metadataNodes ) {
 
 
 					modelData[ 'metadata' ] = parseMetadataNodes( metadataNodes );
 					modelData[ 'metadata' ] = parseMetadataNodes( metadataNodes );
@@ -684,7 +656,6 @@
 				}
 				}
 
 
 				const resourcesNode = modelNode.querySelector( 'resources' );
 				const resourcesNode = modelNode.querySelector( 'resources' );
-
 				if ( resourcesNode ) {
 				if ( resourcesNode ) {
 
 
 					modelData[ 'resources' ] = parseResourcesNode( resourcesNode );
 					modelData[ 'resources' ] = parseResourcesNode( resourcesNode );
@@ -692,7 +663,6 @@
 				}
 				}
 
 
 				const buildNode = modelNode.querySelector( 'build' );
 				const buildNode = modelNode.querySelector( 'build' );
-
 				if ( buildNode ) {
 				if ( buildNode ) {
 
 
 					modelData[ 'build' ] = parseBuildNode( buildNode );
 					modelData[ 'build' ] = parseBuildNode( buildNode );
@@ -708,7 +678,6 @@
 				const texid = texture2dgroup.texid;
 				const texid = texture2dgroup.texid;
 				const texture2ds = modelData.resources.texture2d;
 				const texture2ds = modelData.resources.texture2d;
 				const texture2d = texture2ds[ texid ];
 				const texture2d = texture2ds[ texid ];
-
 				if ( texture2d ) {
 				if ( texture2d ) {
 
 
 					const data = textureData[ texture2d.path ];
 					const data = textureData[ texture2d.path ];
@@ -722,23 +691,22 @@
 						URL.revokeObjectURL( sourceURI );
 						URL.revokeObjectURL( sourceURI );
 
 
 					} );
 					} );
-					texture.encoding = THREE.sRGBEncoding; // texture parameters
+					texture.encoding = THREE.sRGBEncoding;
+
+					// texture parameters
 
 
 					switch ( texture2d.tilestyleu ) {
 					switch ( texture2d.tilestyleu ) {
 
 
 						case 'wrap':
 						case 'wrap':
 							texture.wrapS = THREE.RepeatWrapping;
 							texture.wrapS = THREE.RepeatWrapping;
 							break;
 							break;
-
 						case 'mirror':
 						case 'mirror':
 							texture.wrapS = THREE.MirroredRepeatWrapping;
 							texture.wrapS = THREE.MirroredRepeatWrapping;
 							break;
 							break;
-
 						case 'none':
 						case 'none':
 						case 'clamp':
 						case 'clamp':
 							texture.wrapS = THREE.ClampToEdgeWrapping;
 							texture.wrapS = THREE.ClampToEdgeWrapping;
 							break;
 							break;
-
 						default:
 						default:
 							texture.wrapS = THREE.RepeatWrapping;
 							texture.wrapS = THREE.RepeatWrapping;
 
 
@@ -749,16 +717,13 @@
 						case 'wrap':
 						case 'wrap':
 							texture.wrapT = THREE.RepeatWrapping;
 							texture.wrapT = THREE.RepeatWrapping;
 							break;
 							break;
-
 						case 'mirror':
 						case 'mirror':
 							texture.wrapT = THREE.MirroredRepeatWrapping;
 							texture.wrapT = THREE.MirroredRepeatWrapping;
 							break;
 							break;
-
 						case 'none':
 						case 'none':
 						case 'clamp':
 						case 'clamp':
 							texture.wrapT = THREE.ClampToEdgeWrapping;
 							texture.wrapT = THREE.ClampToEdgeWrapping;
 							break;
 							break;
-
 						default:
 						default:
 							texture.wrapT = THREE.RepeatWrapping;
 							texture.wrapT = THREE.RepeatWrapping;
 
 
@@ -770,17 +735,14 @@
 							texture.magFilter = THREE.LinearFilter;
 							texture.magFilter = THREE.LinearFilter;
 							texture.minFilter = THREE.LinearMipmapLinearFilter;
 							texture.minFilter = THREE.LinearMipmapLinearFilter;
 							break;
 							break;
-
 						case 'linear':
 						case 'linear':
 							texture.magFilter = THREE.LinearFilter;
 							texture.magFilter = THREE.LinearFilter;
 							texture.minFilter = THREE.LinearFilter;
 							texture.minFilter = THREE.LinearFilter;
 							break;
 							break;
-
 						case 'nearest':
 						case 'nearest':
 							texture.magFilter = THREE.NearestFilter;
 							texture.magFilter = THREE.NearestFilter;
 							texture.minFilter = THREE.NearestFilter;
 							texture.minFilter = THREE.NearestFilter;
 							break;
 							break;
-
 						default:
 						default:
 							texture.magFilter = THREE.LinearFilter;
 							texture.magFilter = THREE.LinearFilter;
 							texture.minFilter = THREE.LinearMipmapLinearFilter;
 							texture.minFilter = THREE.LinearMipmapLinearFilter;
@@ -801,7 +763,6 @@
 
 
 				const objectPindex = objectData.pindex;
 				const objectPindex = objectData.pindex;
 				const materialMap = {};
 				const materialMap = {};
-
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 
 
 					const triangleProperty = triangleProperties[ i ];
 					const triangleProperty = triangleProperties[ i ];
@@ -809,23 +770,24 @@
 					if ( materialMap[ pindex ] === undefined ) materialMap[ pindex ] = [];
 					if ( materialMap[ pindex ] === undefined ) materialMap[ pindex ] = [];
 					materialMap[ pindex ].push( triangleProperty );
 					materialMap[ pindex ].push( triangleProperty );
 
 
-				} //
+				}
 
 
+				//
 
 
 				const keys = Object.keys( materialMap );
 				const keys = Object.keys( materialMap );
 				const meshes = [];
 				const meshes = [];
-
 				for ( let i = 0, l = keys.length; i < l; i ++ ) {
 				for ( let i = 0, l = keys.length; i < l; i ++ ) {
 
 
 					const materialIndex = keys[ i ];
 					const materialIndex = keys[ i ];
 					const trianglePropertiesProps = materialMap[ materialIndex ];
 					const trianglePropertiesProps = materialMap[ materialIndex ];
 					const basematerialData = basematerials.basematerials[ materialIndex ];
 					const basematerialData = basematerials.basematerials[ materialIndex ];
-					const material = getBuild( basematerialData, objects, modelData, textureData, objectData, buildBasematerial ); //
+					const material = getBuild( basematerialData, objects, modelData, textureData, objectData, buildBasematerial );
+
+					//
 
 
 					const geometry = new THREE.BufferGeometry();
 					const geometry = new THREE.BufferGeometry();
 					const positionData = [];
 					const positionData = [];
 					const vertices = meshData.vertices;
 					const vertices = meshData.vertices;
-
 					for ( let j = 0, jl = trianglePropertiesProps.length; j < jl; j ++ ) {
 					for ( let j = 0, jl = trianglePropertiesProps.length; j < jl; j ++ ) {
 
 
 						const triangleProperty = trianglePropertiesProps[ j ];
 						const triangleProperty = trianglePropertiesProps[ j ];
@@ -841,7 +803,9 @@
 
 
 					}
 					}
 
 
-					geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); //
+					geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) );
+
+					//
 
 
 					const mesh = new THREE.Mesh( geometry, material );
 					const mesh = new THREE.Mesh( geometry, material );
 					meshes.push( mesh );
 					meshes.push( mesh );
@@ -855,12 +819,12 @@
 			function buildTexturedMesh( texture2dgroup, triangleProperties, meshData, objects, modelData, textureData, objectData ) {
 			function buildTexturedMesh( texture2dgroup, triangleProperties, meshData, objects, modelData, textureData, objectData ) {
 
 
 				// geometry
 				// geometry
+
 				const geometry = new THREE.BufferGeometry();
 				const geometry = new THREE.BufferGeometry();
 				const positionData = [];
 				const positionData = [];
 				const uvData = [];
 				const uvData = [];
 				const vertices = meshData.vertices;
 				const vertices = meshData.vertices;
 				const uvs = texture2dgroup.uvs;
 				const uvs = texture2dgroup.uvs;
-
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 
 
 					const triangleProperty = triangleProperties[ i ];
 					const triangleProperty = triangleProperties[ i ];
@@ -872,7 +836,9 @@
 					positionData.push( vertices[ triangleProperty.v2 * 3 + 2 ] );
 					positionData.push( vertices[ triangleProperty.v2 * 3 + 2 ] );
 					positionData.push( vertices[ triangleProperty.v3 * 3 + 0 ] );
 					positionData.push( vertices[ triangleProperty.v3 * 3 + 0 ] );
 					positionData.push( vertices[ triangleProperty.v3 * 3 + 1 ] );
 					positionData.push( vertices[ triangleProperty.v3 * 3 + 1 ] );
-					positionData.push( vertices[ triangleProperty.v3 * 3 + 2 ] ); //
+					positionData.push( vertices[ triangleProperty.v3 * 3 + 2 ] );
+
+					//
 
 
 					uvData.push( uvs[ triangleProperty.p1 * 2 + 0 ] );
 					uvData.push( uvs[ triangleProperty.p1 * 2 + 0 ] );
 					uvData.push( uvs[ triangleProperty.p1 * 2 + 1 ] );
 					uvData.push( uvs[ triangleProperty.p1 * 2 + 1 ] );
@@ -884,13 +850,17 @@
 				}
 				}
 
 
 				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) );
 				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) );
-				geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvData, 2 ) ); // material
+				geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvData, 2 ) );
+
+				// material
 
 
 				const texture = getBuild( texture2dgroup, objects, modelData, textureData, objectData, buildTexture );
 				const texture = getBuild( texture2dgroup, objects, modelData, textureData, objectData, buildTexture );
 				const material = new THREE.MeshPhongMaterial( {
 				const material = new THREE.MeshPhongMaterial( {
 					map: texture,
 					map: texture,
 					flatShading: true
 					flatShading: true
-				} ); // mesh
+				} );
+
+				// mesh
 
 
 				const mesh = new THREE.Mesh( geometry, material );
 				const mesh = new THREE.Mesh( geometry, material );
 				return mesh;
 				return mesh;
@@ -900,12 +870,12 @@
 			function buildVertexColorMesh( colorgroup, triangleProperties, meshData, objectData ) {
 			function buildVertexColorMesh( colorgroup, triangleProperties, meshData, objectData ) {
 
 
 				// geometry
 				// geometry
+
 				const geometry = new THREE.BufferGeometry();
 				const geometry = new THREE.BufferGeometry();
 				const positionData = [];
 				const positionData = [];
 				const colorData = [];
 				const colorData = [];
 				const vertices = meshData.vertices;
 				const vertices = meshData.vertices;
 				const colors = colorgroup.colors;
 				const colors = colorgroup.colors;
-
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 
 
 					const triangleProperty = triangleProperties[ i ];
 					const triangleProperty = triangleProperties[ i ];
@@ -920,7 +890,9 @@
 					positionData.push( vertices[ v2 * 3 + 2 ] );
 					positionData.push( vertices[ v2 * 3 + 2 ] );
 					positionData.push( vertices[ v3 * 3 + 0 ] );
 					positionData.push( vertices[ v3 * 3 + 0 ] );
 					positionData.push( vertices[ v3 * 3 + 1 ] );
 					positionData.push( vertices[ v3 * 3 + 1 ] );
-					positionData.push( vertices[ v3 * 3 + 2 ] ); //
+					positionData.push( vertices[ v3 * 3 + 2 ] );
+
+					//
 
 
 					const p1 = triangleProperty.p1 !== undefined ? triangleProperty.p1 : objectData.pindex;
 					const p1 = triangleProperty.p1 !== undefined ? triangleProperty.p1 : objectData.pindex;
 					const p2 = triangleProperty.p2 !== undefined ? triangleProperty.p2 : p1;
 					const p2 = triangleProperty.p2 !== undefined ? triangleProperty.p2 : p1;
@@ -938,12 +910,16 @@
 				}
 				}
 
 
 				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) );
 				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) );
-				geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorData, 3 ) ); // material
+				geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorData, 3 ) );
+
+				// material
 
 
 				const material = new THREE.MeshPhongMaterial( {
 				const material = new THREE.MeshPhongMaterial( {
 					vertexColors: true,
 					vertexColors: true,
 					flatShading: true
 					flatShading: true
-				} ); // mesh
+				} );
+
+				// mesh
 
 
 				const mesh = new THREE.Mesh( geometry, material );
 				const mesh = new THREE.Mesh( geometry, material );
 				return mesh;
 				return mesh;
@@ -968,19 +944,16 @@
 
 
 				const keys = Object.keys( resourceMap );
 				const keys = Object.keys( resourceMap );
 				const meshes = [];
 				const meshes = [];
-
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 
 					const resourceId = keys[ i ];
 					const resourceId = keys[ i ];
 					const triangleProperties = resourceMap[ resourceId ];
 					const triangleProperties = resourceMap[ resourceId ];
 					const resourceType = getResourceType( resourceId, modelData );
 					const resourceType = getResourceType( resourceId, modelData );
-
 					switch ( resourceType ) {
 					switch ( resourceType ) {
 
 
 						case 'material':
 						case 'material':
 							const basematerials = modelData.resources.basematerials[ resourceId ];
 							const basematerials = modelData.resources.basematerials[ resourceId ];
 							const newMeshes = buildBasematerialsMeshes( basematerials, triangleProperties, meshData, objects, modelData, textureData, objectData );
 							const newMeshes = buildBasematerialsMeshes( basematerials, triangleProperties, meshData, objects, modelData, textureData, objectData );
-
 							for ( let j = 0, jl = newMeshes.length; j < jl; j ++ ) {
 							for ( let j = 0, jl = newMeshes.length; j < jl; j ++ ) {
 
 
 								meshes.push( newMeshes[ j ] );
 								meshes.push( newMeshes[ j ] );
@@ -988,21 +961,17 @@
 							}
 							}
 
 
 							break;
 							break;
-
 						case 'texture':
 						case 'texture':
 							const texture2dgroup = modelData.resources.texture2dgroup[ resourceId ];
 							const texture2dgroup = modelData.resources.texture2dgroup[ resourceId ];
 							meshes.push( buildTexturedMesh( texture2dgroup, triangleProperties, meshData, objects, modelData, textureData, objectData ) );
 							meshes.push( buildTexturedMesh( texture2dgroup, triangleProperties, meshData, objects, modelData, textureData, objectData ) );
 							break;
 							break;
-
 						case 'vertexColors':
 						case 'vertexColors':
 							const colorgroup = modelData.resources.colorgroup[ resourceId ];
 							const colorgroup = modelData.resources.colorgroup[ resourceId ];
 							meshes.push( buildVertexColorMesh( colorgroup, triangleProperties, meshData, objectData ) );
 							meshes.push( buildVertexColorMesh( colorgroup, triangleProperties, meshData, objectData ) );
 							break;
 							break;
-
 						case 'default':
 						case 'default':
 							meshes.push( buildDefaultMesh( meshData ) );
 							meshes.push( buildDefaultMesh( meshData ) );
 							break;
 							break;
-
 						default:
 						default:
 							console.error( 'THREE.3MFLoader: Unsupported resource type.' );
 							console.error( 'THREE.3MFLoader: Unsupported resource type.' );
 
 
@@ -1055,7 +1024,6 @@
 				const resourceMap = {};
 				const resourceMap = {};
 				const triangleProperties = meshData[ 'triangleProperties' ];
 				const triangleProperties = meshData[ 'triangleProperties' ];
 				const objectPid = objectData.pid;
 				const objectPid = objectData.pid;
-
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 				for ( let i = 0, l = triangleProperties.length; i < l; i ++ ) {
 
 
 					const triangleProperty = triangleProperties[ i ];
 					const triangleProperty = triangleProperties[ i ];
@@ -1075,7 +1043,6 @@
 				const group = new THREE.Group();
 				const group = new THREE.Group();
 				const resourceMap = analyzeObject( meshData, objectData );
 				const resourceMap = analyzeObject( meshData, objectData );
 				const meshes = buildMeshes( resourceMap, meshData, objects, modelData, textureData, objectData );
 				const meshes = buildMeshes( resourceMap, meshData, objects, modelData, textureData, objectData );
-
 				for ( let i = 0, l = meshes.length; i < l; i ++ ) {
 				for ( let i = 0, l = meshes.length; i < l; i ++ ) {
 
 
 					group.add( meshes[ i ] );
 					group.add( meshes[ i ] );
@@ -1096,15 +1063,12 @@
 
 
 				const availableExtensions = [];
 				const availableExtensions = [];
 				const keys = Object.keys( extensions );
 				const keys = Object.keys( extensions );
-
 				for ( let i = 0; i < keys.length; i ++ ) {
 				for ( let i = 0; i < keys.length; i ++ ) {
 
 
 					const ns = keys[ i ];
 					const ns = keys[ i ];
-
 					for ( let j = 0; j < scope.availableExtensions.length; j ++ ) {
 					for ( let j = 0; j < scope.availableExtensions.length; j ++ ) {
 
 
 						const extension = scope.availableExtensions[ j ];
 						const extension = scope.availableExtensions[ j ];
-
 						if ( extension.ns === ns ) {
 						if ( extension.ns === ns ) {
 
 
 							availableExtensions.push( extension );
 							availableExtensions.push( extension );
@@ -1137,10 +1101,10 @@
 				let material;
 				let material;
 				const displaypropertiesid = materialData.displaypropertiesid;
 				const displaypropertiesid = materialData.displaypropertiesid;
 				const pbmetallicdisplayproperties = modelData.resources.pbmetallicdisplayproperties;
 				const pbmetallicdisplayproperties = modelData.resources.pbmetallicdisplayproperties;
-
 				if ( displaypropertiesid !== null && pbmetallicdisplayproperties[ displaypropertiesid ] !== undefined ) {
 				if ( displaypropertiesid !== null && pbmetallicdisplayproperties[ displaypropertiesid ] !== undefined ) {
 
 
 					// metallic display property, use StandardMaterial
 					// metallic display property, use StandardMaterial
+
 					const pbmetallicdisplayproperty = pbmetallicdisplayproperties[ displaypropertiesid ];
 					const pbmetallicdisplayproperty = pbmetallicdisplayproperties[ displaypropertiesid ];
 					const metallicData = pbmetallicdisplayproperty.data[ materialData.index ];
 					const metallicData = pbmetallicdisplayproperty.data[ materialData.index ];
 					material = new THREE.MeshStandardMaterial( {
 					material = new THREE.MeshStandardMaterial( {
@@ -1152,18 +1116,22 @@
 				} else {
 				} else {
 
 
 					// otherwise use PhongMaterial
 					// otherwise use PhongMaterial
+
 					material = new THREE.MeshPhongMaterial( {
 					material = new THREE.MeshPhongMaterial( {
 						flatShading: true
 						flatShading: true
 					} );
 					} );
 
 
 				}
 				}
 
 
-				material.name = materialData.name; // displaycolor MUST be specified with a value of a 6 or 8 digit hexadecimal number, e.g. "#RRGGBB" or "#RRGGBBAA"
+				material.name = materialData.name;
+
+				// displaycolor MUST be specified with a value of a 6 or 8 digit hexadecimal number, e.g. "#RRGGBB" or "#RRGGBBAA"
 
 
 				const displaycolor = materialData.displaycolor;
 				const displaycolor = materialData.displaycolor;
 				const color = displaycolor.substring( 0, 7 );
 				const color = displaycolor.substring( 0, 7 );
 				material.color.setStyle( color );
 				material.color.setStyle( color );
 				material.color.convertSRGBToLinear(); // displaycolor is in sRGB
 				material.color.convertSRGBToLinear(); // displaycolor is in sRGB
+
 				// process alpha if set
 				// process alpha if set
 
 
 				if ( displaycolor.length === 9 ) {
 				if ( displaycolor.length === 9 ) {
@@ -1179,12 +1147,10 @@
 			function buildComposite( compositeData, objects, modelData, textureData ) {
 			function buildComposite( compositeData, objects, modelData, textureData ) {
 
 
 				const composite = new THREE.Group();
 				const composite = new THREE.Group();
-
 				for ( let j = 0; j < compositeData.length; j ++ ) {
 				for ( let j = 0; j < compositeData.length; j ++ ) {
 
 
 					const component = compositeData[ j ];
 					const component = compositeData[ j ];
 					let build = objects[ component.objectId ];
 					let build = objects[ component.objectId ];
-
 					if ( build === undefined ) {
 					if ( build === undefined ) {
 
 
 						buildObject( component.objectId, objects, modelData, textureData );
 						buildObject( component.objectId, objects, modelData, textureData );
@@ -1192,10 +1158,11 @@
 
 
 					}
 					}
 
 
-					const object3D = build.clone(); // apply component transform
+					const object3D = build.clone();
 
 
-					const transform = component.transform;
+					// apply component transform
 
 
+					const transform = component.transform;
 					if ( transform ) {
 					if ( transform ) {
 
 
 						object3D.applyMatrix4( transform );
 						object3D.applyMatrix4( transform );
@@ -1213,7 +1180,6 @@
 			function buildObject( objectId, objects, modelData, textureData ) {
 			function buildObject( objectId, objects, modelData, textureData ) {
 
 
 				const objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
 				const objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
-
 				if ( objectData[ 'mesh' ] ) {
 				if ( objectData[ 'mesh' ] ) {
 
 
 					const meshData = objectData[ 'mesh' ];
 					const meshData = objectData[ 'mesh' ];
@@ -1243,7 +1209,9 @@
 				const modelRels = data3mf.modelRels;
 				const modelRels = data3mf.modelRels;
 				const objects = {};
 				const objects = {};
 				const modelsKeys = Object.keys( modelsData );
 				const modelsKeys = Object.keys( modelsData );
-				const textureData = {}; // evaluate model relationships to textures
+				const textureData = {};
+
+				// evaluate model relationships to textures
 
 
 				if ( modelRels ) {
 				if ( modelRels ) {
 
 
@@ -1251,7 +1219,6 @@
 
 
 						const modelRel = modelRels[ i ];
 						const modelRel = modelRels[ i ];
 						const textureKey = modelRel.target.substring( 1 );
 						const textureKey = modelRel.target.substring( 1 );
-
 						if ( data3mf.texture[ textureKey ] ) {
 						if ( data3mf.texture[ textureKey ] ) {
 
 
 							textureData[ modelRel.target ] = data3mf.texture[ textureKey ];
 							textureData[ modelRel.target ] = data3mf.texture[ textureKey ];
@@ -1260,15 +1227,15 @@
 
 
 					}
 					}
 
 
-				} // start build
+				}
 
 
+				// start build
 
 
 				for ( let i = 0; i < modelsKeys.length; i ++ ) {
 				for ( let i = 0; i < modelsKeys.length; i ++ ) {
 
 
 					const modelsKey = modelsKeys[ i ];
 					const modelsKey = modelsKeys[ i ];
 					const modelData = modelsData[ modelsKey ];
 					const modelData = modelsData[ modelsKey ];
 					const objectIds = Object.keys( modelData[ 'resources' ][ 'object' ] );
 					const objectIds = Object.keys( modelData[ 'resources' ][ 'object' ] );
-
 					for ( let j = 0; j < objectIds.length; j ++ ) {
 					for ( let j = 0; j < objectIds.length; j ++ ) {
 
 
 						const objectId = objectIds[ j ];
 						const objectId = objectIds[ j ];
@@ -1299,14 +1266,14 @@
 				const group = new THREE.Group();
 				const group = new THREE.Group();
 				const relationship = fetch3DModelPart( data3mf[ 'rels' ] );
 				const relationship = fetch3DModelPart( data3mf[ 'rels' ] );
 				const buildData = data3mf.model[ relationship[ 'target' ].substring( 1 ) ][ 'build' ];
 				const buildData = data3mf.model[ relationship[ 'target' ].substring( 1 ) ][ 'build' ];
-
 				for ( let i = 0; i < buildData.length; i ++ ) {
 				for ( let i = 0; i < buildData.length; i ++ ) {
 
 
 					const buildItem = buildData[ i ];
 					const buildItem = buildData[ i ];
-					const object3D = objects[ buildItem[ 'objectId' ] ].clone(); // apply transform
+					const object3D = objects[ buildItem[ 'objectId' ] ].clone();
 
 
-					const transform = buildItem[ 'transform' ];
+					// apply transform
 
 
+					const transform = buildItem[ 'transform' ];
 					if ( transform ) {
 					if ( transform ) {
 
 
 						object3D.applyMatrix4( transform );
 						object3D.applyMatrix4( transform );
@@ -1326,7 +1293,6 @@
 			return build( objects, data3mf );
 			return build( objects, data3mf );
 
 
 		}
 		}
-
 		addExtension( extension ) {
 		addExtension( extension ) {
 
 
 			this.availableExtensions.push( extension );
 			this.availableExtensions.push( extension );

+ 0 - 25
examples/js/loaders/AMFLoader.js

@@ -23,7 +23,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -57,20 +56,17 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			function loadDocument( data ) {
 			function loadDocument( data ) {
 
 
 				let view = new DataView( data );
 				let view = new DataView( data );
 				const magic = String.fromCharCode( view.getUint8( 0 ), view.getUint8( 1 ) );
 				const magic = String.fromCharCode( view.getUint8( 0 ), view.getUint8( 1 ) );
-
 				if ( magic === 'PK' ) {
 				if ( magic === 'PK' ) {
 
 
 					let zip = null;
 					let zip = null;
 					let file = null;
 					let file = null;
 					console.log( 'THREE.AMFLoader: Loading Zip' );
 					console.log( 'THREE.AMFLoader: Loading Zip' );
-
 					try {
 					try {
 
 
 						zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef
 						zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef
@@ -103,7 +99,6 @@
 
 
 				const fileText = THREE.LoaderUtils.decodeText( view );
 				const fileText = THREE.LoaderUtils.decodeText( view );
 				const xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
 				const xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
-
 				if ( xmlData.documentElement.nodeName.toLowerCase() !== 'amf' ) {
 				if ( xmlData.documentElement.nodeName.toLowerCase() !== 'amf' ) {
 
 
 					console.log( 'THREE.AMFLoader: Error loading AMF - no AMF document found.' );
 					console.log( 'THREE.AMFLoader: Error loading AMF - no AMF document found.' );
@@ -119,7 +114,6 @@
 
 
 				let scale = 1.0;
 				let scale = 1.0;
 				let unit = 'millimeter';
 				let unit = 'millimeter';
-
 				if ( node.documentElement.attributes.unit !== undefined ) {
 				if ( node.documentElement.attributes.unit !== undefined ) {
 
 
 					unit = node.documentElement.attributes.unit.value.toLowerCase();
 					unit = node.documentElement.attributes.unit.value.toLowerCase();
@@ -133,7 +127,6 @@
 					meter: 1000.0,
 					meter: 1000.0,
 					micron: 0.001
 					micron: 0.001
 				};
 				};
-
 				if ( scaleUnits[ unit ] !== undefined ) {
 				if ( scaleUnits[ unit ] !== undefined ) {
 
 
 					scale = scaleUnits[ unit ];
 					scale = scaleUnits[ unit ];
@@ -156,11 +149,9 @@
 					a: 1.0
 					a: 1.0
 				};
 				};
 				let loadedMaterial = null;
 				let loadedMaterial = null;
-
 				for ( let i = 0; i < node.childNodes.length; i ++ ) {
 				for ( let i = 0; i < node.childNodes.length; i ++ ) {
 
 
 					const matChildEl = node.childNodes[ i ];
 					const matChildEl = node.childNodes[ i ];
-
 					if ( matChildEl.nodeName === 'metadata' && matChildEl.attributes.type !== undefined ) {
 					if ( matChildEl.nodeName === 'metadata' && matChildEl.attributes.type !== undefined ) {
 
 
 						if ( matChildEl.attributes.type.value === 'name' ) {
 						if ( matChildEl.attributes.type.value === 'name' ) {
@@ -182,7 +173,6 @@
 					color: new THREE.Color( color.r, color.g, color.b ),
 					color: new THREE.Color( color.r, color.g, color.b ),
 					name: matName
 					name: matName
 				} );
 				} );
-
 				if ( color.a !== 1.0 ) {
 				if ( color.a !== 1.0 ) {
 
 
 					loadedMaterial.transparent = true;
 					loadedMaterial.transparent = true;
@@ -205,11 +195,9 @@
 					b: 1.0,
 					b: 1.0,
 					a: 1.0
 					a: 1.0
 				};
 				};
-
 				for ( let i = 0; i < node.childNodes.length; i ++ ) {
 				for ( let i = 0; i < node.childNodes.length; i ++ ) {
 
 
 					const matColor = node.childNodes[ i ];
 					const matColor = node.childNodes[ i ];
-
 					if ( matColor.nodeName === 'r' ) {
 					if ( matColor.nodeName === 'r' ) {
 
 
 						color.r = matColor.textContent;
 						color.r = matColor.textContent;
@@ -242,7 +230,6 @@
 					materialid: null
 					materialid: null
 				};
 				};
 				let currVolumeNode = node.firstElementChild;
 				let currVolumeNode = node.firstElementChild;
-
 				if ( node.attributes.materialid !== undefined ) {
 				if ( node.attributes.materialid !== undefined ) {
 
 
 					volume.materialId = node.attributes.materialid.nodeValue;
 					volume.materialId = node.attributes.materialid.nodeValue;
@@ -285,13 +272,11 @@
 				const vertArray = [];
 				const vertArray = [];
 				const normalArray = [];
 				const normalArray = [];
 				let currVerticesNode = node.firstElementChild;
 				let currVerticesNode = node.firstElementChild;
-
 				while ( currVerticesNode ) {
 				while ( currVerticesNode ) {
 
 
 					if ( currVerticesNode.nodeName === 'vertex' ) {
 					if ( currVerticesNode.nodeName === 'vertex' ) {
 
 
 						let vNode = currVerticesNode.firstElementChild;
 						let vNode = currVerticesNode.firstElementChild;
-
 						while ( vNode ) {
 						while ( vNode ) {
 
 
 							if ( vNode.nodeName === 'coordinates' ) {
 							if ( vNode.nodeName === 'coordinates' ) {
@@ -336,7 +321,6 @@
 				};
 				};
 				let currColor = null;
 				let currColor = null;
 				let currObjNode = node.firstElementChild;
 				let currObjNode = node.firstElementChild;
-
 				while ( currObjNode ) {
 				while ( currObjNode ) {
 
 
 					if ( currObjNode.nodeName === 'metadata' ) {
 					if ( currObjNode.nodeName === 'metadata' ) {
@@ -364,7 +348,6 @@
 							volumes: [],
 							volumes: [],
 							color: currColor
 							color: currColor
 						};
 						};
-
 						while ( currMeshNode ) {
 						while ( currMeshNode ) {
 
 
 							if ( currMeshNode.nodeName === 'vertices' ) {
 							if ( currMeshNode.nodeName === 'vertices' ) {
@@ -406,11 +389,9 @@
 			const amfObjects = {};
 			const amfObjects = {};
 			const childNodes = xmlData.documentElement.childNodes;
 			const childNodes = xmlData.documentElement.childNodes;
 			let i, j;
 			let i, j;
-
 			for ( i = 0; i < childNodes.length; i ++ ) {
 			for ( i = 0; i < childNodes.length; i ++ ) {
 
 
 				const child = childNodes[ i ];
 				const child = childNodes[ i ];
-
 				if ( child.nodeName === 'metadata' ) {
 				if ( child.nodeName === 'metadata' ) {
 
 
 					if ( child.attributes.type !== undefined ) {
 					if ( child.attributes.type !== undefined ) {
@@ -449,21 +430,18 @@
 			sceneObject.name = amfName;
 			sceneObject.name = amfName;
 			sceneObject.userData.author = amfAuthor;
 			sceneObject.userData.author = amfAuthor;
 			sceneObject.userData.loader = 'AMF';
 			sceneObject.userData.loader = 'AMF';
-
 			for ( const id in amfObjects ) {
 			for ( const id in amfObjects ) {
 
 
 				const part = amfObjects[ id ];
 				const part = amfObjects[ id ];
 				const meshes = part.meshes;
 				const meshes = part.meshes;
 				const newObject = new THREE.Group();
 				const newObject = new THREE.Group();
 				newObject.name = part.name || '';
 				newObject.name = part.name || '';
-
 				for ( i = 0; i < meshes.length; i ++ ) {
 				for ( i = 0; i < meshes.length; i ++ ) {
 
 
 					let objDefaultMaterial = defaultMaterial;
 					let objDefaultMaterial = defaultMaterial;
 					const mesh = meshes[ i ];
 					const mesh = meshes[ i ];
 					const vertices = new THREE.Float32BufferAttribute( mesh.vertices, 3 );
 					const vertices = new THREE.Float32BufferAttribute( mesh.vertices, 3 );
 					let normals = null;
 					let normals = null;
-
 					if ( mesh.normals.length ) {
 					if ( mesh.normals.length ) {
 
 
 						normals = new THREE.Float32BufferAttribute( mesh.normals, 3 );
 						normals = new THREE.Float32BufferAttribute( mesh.normals, 3 );
@@ -475,7 +453,6 @@
 						const color = mesh.color;
 						const color = mesh.color;
 						objDefaultMaterial = defaultMaterial.clone();
 						objDefaultMaterial = defaultMaterial.clone();
 						objDefaultMaterial.color = new THREE.Color( color.r, color.g, color.b );
 						objDefaultMaterial.color = new THREE.Color( color.r, color.g, color.b );
-
 						if ( color.a !== 1.0 ) {
 						if ( color.a !== 1.0 ) {
 
 
 							objDefaultMaterial.transparent = true;
 							objDefaultMaterial.transparent = true;
@@ -486,7 +463,6 @@
 					}
 					}
 
 
 					const volumes = mesh.volumes;
 					const volumes = mesh.volumes;
-
 					for ( j = 0; j < volumes.length; j ++ ) {
 					for ( j = 0; j < volumes.length; j ++ ) {
 
 
 						const volume = volumes[ j ];
 						const volume = volumes[ j ];
@@ -494,7 +470,6 @@
 						let material = objDefaultMaterial;
 						let material = objDefaultMaterial;
 						newGeometry.setIndex( volume.triangles );
 						newGeometry.setIndex( volume.triangles );
 						newGeometry.setAttribute( 'position', vertices.clone() );
 						newGeometry.setAttribute( 'position', vertices.clone() );
-
 						if ( normals ) {
 						if ( normals ) {
 
 
 							newGeometry.setAttribute( 'normal', normals.clone() );
 							newGeometry.setAttribute( 'normal', normals.clone() );

+ 44 - 43
examples/js/loaders/BVHLoader.js

@@ -16,7 +16,6 @@
 			this.animateBoneRotations = true;
 			this.animateBoneRotations = true;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -49,7 +48,6 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( text ) {
 		parse( text ) {
 
 
 			/*
 			/*
@@ -61,6 +59,7 @@
 			function readBvh( lines ) {
 			function readBvh( lines ) {
 
 
 				// read model structure
 				// read model structure
+
 				if ( nextLine( lines ) !== 'HIERARCHY' ) {
 				if ( nextLine( lines ) !== 'HIERARCHY' ) {
 
 
 					console.error( 'THREE.BVHLoader: HIERARCHY expected.' );
 					console.error( 'THREE.BVHLoader: HIERARCHY expected.' );
@@ -68,35 +67,37 @@
 				}
 				}
 
 
 				const list = []; // collects flat array of all bones
 				const list = []; // collects flat array of all bones
+				const root = readNode( lines, nextLine( lines ), list );
 
 
-				const root = readNode( lines, nextLine( lines ), list ); // read motion data
+				// read motion data
 
 
 				if ( nextLine( lines ) !== 'MOTION' ) {
 				if ( nextLine( lines ) !== 'MOTION' ) {
 
 
 					console.error( 'THREE.BVHLoader: MOTION expected.' );
 					console.error( 'THREE.BVHLoader: MOTION expected.' );
 
 
-				} // number of frames
+				}
 
 
+				// number of frames
 
 
 				let tokens = nextLine( lines ).split( /[\s]+/ );
 				let tokens = nextLine( lines ).split( /[\s]+/ );
 				const numFrames = parseInt( tokens[ 1 ] );
 				const numFrames = parseInt( tokens[ 1 ] );
-
 				if ( isNaN( numFrames ) ) {
 				if ( isNaN( numFrames ) ) {
 
 
 					console.error( 'THREE.BVHLoader: Failed to read number of frames.' );
 					console.error( 'THREE.BVHLoader: Failed to read number of frames.' );
 
 
-				} // frame time
+				}
 
 
+				// frame time
 
 
 				tokens = nextLine( lines ).split( /[\s]+/ );
 				tokens = nextLine( lines ).split( /[\s]+/ );
 				const frameTime = parseFloat( tokens[ 2 ] );
 				const frameTime = parseFloat( tokens[ 2 ] );
-
 				if ( isNaN( frameTime ) ) {
 				if ( isNaN( frameTime ) ) {
 
 
 					console.error( 'THREE.BVHLoader: Failed to read frame time.' );
 					console.error( 'THREE.BVHLoader: Failed to read frame time.' );
 
 
-				} // read frame data line by line
+				}
 
 
+				// read frame data line by line
 
 
 				for ( let i = 0; i < numFrames; i ++ ) {
 				for ( let i = 0; i < numFrames; i ++ ) {
 
 
@@ -108,6 +109,7 @@
 				return list;
 				return list;
 
 
 			}
 			}
+
 			/*
 			/*
     	Recursively reads data from a single frame into the bone hierarchy.
     	Recursively reads data from a single frame into the bone hierarchy.
     	The passed bone hierarchy has to be structured in the same order as the BVH file.
     	The passed bone hierarchy has to be structured in the same order as the BVH file.
@@ -117,12 +119,13 @@
     	- frameTime: playback time for this keyframe.
     	- frameTime: playback time for this keyframe.
     	- bone: the bone to read frame data from.
     	- bone: the bone to read frame data from.
     */
     */
-
-
 			function readFrameData( data, frameTime, bone ) {
 			function readFrameData( data, frameTime, bone ) {
 
 
 				// end sites have no motion data
 				// end sites have no motion data
-				if ( bone.type === 'ENDSITE' ) return; // add keyframe
+
+				if ( bone.type === 'ENDSITE' ) return;
+
+				// add keyframe
 
 
 				const keyframe = {
 				const keyframe = {
 					time: frameTime,
 					time: frameTime,
@@ -133,7 +136,9 @@
 				const quat = new THREE.Quaternion();
 				const quat = new THREE.Quaternion();
 				const vx = new THREE.Vector3( 1, 0, 0 );
 				const vx = new THREE.Vector3( 1, 0, 0 );
 				const vy = new THREE.Vector3( 0, 1, 0 );
 				const vy = new THREE.Vector3( 0, 1, 0 );
-				const vz = new THREE.Vector3( 0, 0, 1 ); // parse values for each channel in node
+				const vz = new THREE.Vector3( 0, 0, 1 );
+
+				// parse values for each channel in node
 
 
 				for ( let i = 0; i < bone.channels.length; i ++ ) {
 				for ( let i = 0; i < bone.channels.length; i ++ ) {
 
 
@@ -142,37 +147,32 @@
 						case 'Xposition':
 						case 'Xposition':
 							keyframe.position.x = parseFloat( data.shift().trim() );
 							keyframe.position.x = parseFloat( data.shift().trim() );
 							break;
 							break;
-
 						case 'Yposition':
 						case 'Yposition':
 							keyframe.position.y = parseFloat( data.shift().trim() );
 							keyframe.position.y = parseFloat( data.shift().trim() );
 							break;
 							break;
-
 						case 'Zposition':
 						case 'Zposition':
 							keyframe.position.z = parseFloat( data.shift().trim() );
 							keyframe.position.z = parseFloat( data.shift().trim() );
 							break;
 							break;
-
 						case 'Xrotation':
 						case 'Xrotation':
 							quat.setFromAxisAngle( vx, parseFloat( data.shift().trim() ) * Math.PI / 180 );
 							quat.setFromAxisAngle( vx, parseFloat( data.shift().trim() ) * Math.PI / 180 );
 							keyframe.rotation.multiply( quat );
 							keyframe.rotation.multiply( quat );
 							break;
 							break;
-
 						case 'Yrotation':
 						case 'Yrotation':
 							quat.setFromAxisAngle( vy, parseFloat( data.shift().trim() ) * Math.PI / 180 );
 							quat.setFromAxisAngle( vy, parseFloat( data.shift().trim() ) * Math.PI / 180 );
 							keyframe.rotation.multiply( quat );
 							keyframe.rotation.multiply( quat );
 							break;
 							break;
-
 						case 'Zrotation':
 						case 'Zrotation':
 							quat.setFromAxisAngle( vz, parseFloat( data.shift().trim() ) * Math.PI / 180 );
 							quat.setFromAxisAngle( vz, parseFloat( data.shift().trim() ) * Math.PI / 180 );
 							keyframe.rotation.multiply( quat );
 							keyframe.rotation.multiply( quat );
 							break;
 							break;
-
 						default:
 						default:
 							console.warn( 'THREE.BVHLoader: Invalid channel type.' );
 							console.warn( 'THREE.BVHLoader: Invalid channel type.' );
 
 
 					}
 					}
 
 
-				} // parse child nodes
+				}
 
 
+				// parse child nodes
 
 
 				for ( let i = 0; i < bone.children.length; i ++ ) {
 				for ( let i = 0; i < bone.children.length; i ++ ) {
 
 
@@ -181,6 +181,7 @@
 				}
 				}
 
 
 			}
 			}
+
 			/*
 			/*
      Recursively parses the HIERACHY section of the BVH file
      Recursively parses the HIERACHY section of the BVH file
     	 - lines: all lines of the file. lines are consumed as we go along.
     	 - lines: all lines of the file. lines are consumed as we go along.
@@ -188,8 +189,6 @@
      - list: collects a flat list of nodes
      - list: collects a flat list of nodes
     	 returns: a BVH node including children
     	 returns: a BVH node including children
     */
     */
-
-
 			function readNode( lines, firstline, list ) {
 			function readNode( lines, firstline, list ) {
 
 
 				const node = {
 				const node = {
@@ -197,10 +196,11 @@
 					type: '',
 					type: '',
 					frames: []
 					frames: []
 				};
 				};
-				list.push( node ); // parse node type and name
+				list.push( node );
 
 
-				let tokens = firstline.split( /[\s]+/ );
+				// parse node type and name
 
 
+				let tokens = firstline.split( /[\s]+/ );
 				if ( tokens[ 0 ].toUpperCase() === 'END' && tokens[ 1 ].toUpperCase() === 'SITE' ) {
 				if ( tokens[ 0 ].toUpperCase() === 'END' && tokens[ 1 ].toUpperCase() === 'SITE' ) {
 
 
 					node.type = 'ENDSITE';
 					node.type = 'ENDSITE';
@@ -217,11 +217,11 @@
 
 
 					console.error( 'THREE.BVHLoader: Expected opening { after type & name' );
 					console.error( 'THREE.BVHLoader: Expected opening { after type & name' );
 
 
-				} // parse OFFSET
+				}
 
 
+				// parse OFFSET
 
 
 				tokens = nextLine( lines ).split( /[\s]+/ );
 				tokens = nextLine( lines ).split( /[\s]+/ );
-
 				if ( tokens[ 0 ] !== 'OFFSET' ) {
 				if ( tokens[ 0 ] !== 'OFFSET' ) {
 
 
 					console.error( 'THREE.BVHLoader: Expected OFFSET but got: ' + tokens[ 0 ] );
 					console.error( 'THREE.BVHLoader: Expected OFFSET but got: ' + tokens[ 0 ] );
@@ -235,19 +235,19 @@
 				}
 				}
 
 
 				const offset = new THREE.Vector3( parseFloat( tokens[ 1 ] ), parseFloat( tokens[ 2 ] ), parseFloat( tokens[ 3 ] ) );
 				const offset = new THREE.Vector3( parseFloat( tokens[ 1 ] ), parseFloat( tokens[ 2 ] ), parseFloat( tokens[ 3 ] ) );
-
 				if ( isNaN( offset.x ) || isNaN( offset.y ) || isNaN( offset.z ) ) {
 				if ( isNaN( offset.x ) || isNaN( offset.y ) || isNaN( offset.z ) ) {
 
 
 					console.error( 'THREE.BVHLoader: Invalid values of OFFSET.' );
 					console.error( 'THREE.BVHLoader: Invalid values of OFFSET.' );
 
 
 				}
 				}
 
 
-				node.offset = offset; // parse CHANNELS definitions
+				node.offset = offset;
+
+				// parse CHANNELS definitions
 
 
 				if ( node.type !== 'ENDSITE' ) {
 				if ( node.type !== 'ENDSITE' ) {
 
 
 					tokens = nextLine( lines ).split( /[\s]+/ );
 					tokens = nextLine( lines ).split( /[\s]+/ );
-
 					if ( tokens[ 0 ] !== 'CHANNELS' ) {
 					if ( tokens[ 0 ] !== 'CHANNELS' ) {
 
 
 						console.error( 'THREE.BVHLoader: Expected CHANNELS definition.' );
 						console.error( 'THREE.BVHLoader: Expected CHANNELS definition.' );
@@ -258,13 +258,13 @@
 					node.channels = tokens.splice( 2, numChannels );
 					node.channels = tokens.splice( 2, numChannels );
 					node.children = [];
 					node.children = [];
 
 
-				} // read children
+				}
 
 
+				// read children
 
 
 				while ( true ) {
 				while ( true ) {
 
 
 					const line = nextLine( lines );
 					const line = nextLine( lines );
-
 					if ( line === '}' ) {
 					if ( line === '}' ) {
 
 
 						return node;
 						return node;
@@ -278,21 +278,19 @@
 				}
 				}
 
 
 			}
 			}
+
 			/*
 			/*
     	recursively converts the internal bvh node structure to a THREE.Bone hierarchy
     	recursively converts the internal bvh node structure to a THREE.Bone hierarchy
     		source: the bvh root node
     		source: the bvh root node
     	list: pass an empty array, collects a flat list of all converted THREE.Bones
     	list: pass an empty array, collects a flat list of all converted THREE.Bones
     		returns the root THREE.Bone
     		returns the root THREE.Bone
     */
     */
-
-
 			function toTHREEBone( source, list ) {
 			function toTHREEBone( source, list ) {
 
 
 				const bone = new THREE.Bone();
 				const bone = new THREE.Bone();
 				list.push( bone );
 				list.push( bone );
 				bone.position.add( source.offset );
 				bone.position.add( source.offset );
 				bone.name = source.name;
 				bone.name = source.name;
-
 				if ( source.type !== 'ENDSITE' ) {
 				if ( source.type !== 'ENDSITE' ) {
 
 
 					for ( let i = 0; i < source.children.length; i ++ ) {
 					for ( let i = 0; i < source.children.length; i ++ ) {
@@ -306,30 +304,34 @@
 				return bone;
 				return bone;
 
 
 			}
 			}
+
 			/*
 			/*
     	builds a THREE.AnimationClip from the keyframe data saved in each bone.
     	builds a THREE.AnimationClip from the keyframe data saved in each bone.
     		bone: bvh root node
     		bone: bvh root node
     		returns: a THREE.AnimationClip containing position and quaternion tracks
     		returns: a THREE.AnimationClip containing position and quaternion tracks
     */
     */
-
-
 			function toTHREEAnimation( bones ) {
 			function toTHREEAnimation( bones ) {
 
 
-				const tracks = []; // create a position and quaternion animation track for each node
+				const tracks = [];
+
+				// create a position and quaternion animation track for each node
 
 
 				for ( let i = 0; i < bones.length; i ++ ) {
 				for ( let i = 0; i < bones.length; i ++ ) {
 
 
 					const bone = bones[ i ];
 					const bone = bones[ i ];
-					if ( bone.type === 'ENDSITE' ) continue; // track data
+					if ( bone.type === 'ENDSITE' ) continue;
+
+					// track data
 
 
 					const times = [];
 					const times = [];
 					const positions = [];
 					const positions = [];
 					const rotations = [];
 					const rotations = [];
-
 					for ( let j = 0; j < bone.frames.length; j ++ ) {
 					for ( let j = 0; j < bone.frames.length; j ++ ) {
 
 
 						const frame = bone.frames[ j ];
 						const frame = bone.frames[ j ];
-						times.push( frame.time ); // the animation system animates the position property,
+						times.push( frame.time );
+
+						// the animation system animates the position property,
 						// so we have to add the joint offset to all values
 						// so we have to add the joint offset to all values
 
 
 						positions.push( frame.position.x + bone.offset.x );
 						positions.push( frame.position.x + bone.offset.x );
@@ -359,15 +361,14 @@
 				return new THREE.AnimationClip( 'animation', - 1, tracks );
 				return new THREE.AnimationClip( 'animation', - 1, tracks );
 
 
 			}
 			}
+
 			/*
 			/*
     	returns the next non-empty line in lines
     	returns the next non-empty line in lines
     */
     */
-
-
 			function nextLine( lines ) {
 			function nextLine( lines ) {
 
 
-				let line; // skip empty lines
-
+				let line;
+				// skip empty lines
 				while ( ( line = lines.shift().trim() ).length === 0 ) {}
 				while ( ( line = lines.shift().trim() ).length === 0 ) {}
 
 
 				return line;
 				return line;

+ 16 - 46
examples/js/loaders/BasisTextureLoader.js

@@ -14,7 +14,6 @@
  */
  */
 
 
 	const _taskCache = new WeakMap();
 	const _taskCache = new WeakMap();
-
 	class BasisTextureLoader extends THREE.Loader {
 	class BasisTextureLoader extends THREE.Loader {
 
 
 		constructor( manager ) {
 		constructor( manager ) {
@@ -31,21 +30,18 @@
 			console.warn( 'THREE.BasisTextureLoader: This loader is deprecated, and will be removed in a future release. ' + 'Instead, use Basis Universal compression in KTX2 (.ktx2) files with THREE.KTX2Loader.' );
 			console.warn( 'THREE.BasisTextureLoader: This loader is deprecated, and will be removed in a future release. ' + 'Instead, use Basis Universal compression in KTX2 (.ktx2) files with THREE.KTX2Loader.' );
 
 
 		}
 		}
-
 		setTranscoderPath( path ) {
 		setTranscoderPath( path ) {
 
 
 			this.transcoderPath = path;
 			this.transcoderPath = path;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setWorkerLimit( workerLimit ) {
 		setWorkerLimit( workerLimit ) {
 
 
 			this.workerLimit = workerLimit;
 			this.workerLimit = workerLimit;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		detectSupport( renderer ) {
 		detectSupport( renderer ) {
 
 
 			this.workerConfig = {
 			this.workerConfig = {
@@ -59,7 +55,6 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const loader = new THREE.FileLoader( this.manager );
 			const loader = new THREE.FileLoader( this.manager );
@@ -73,7 +68,6 @@
 				if ( _taskCache.has( buffer ) ) {
 				if ( _taskCache.has( buffer ) ) {
 
 
 					const cachedTask = _taskCache.get( buffer );
 					const cachedTask = _taskCache.get( buffer );
-
 					return cachedTask.promise.then( onLoad ).catch( onError );
 					return cachedTask.promise.then( onLoad ).catch( onError );
 
 
 				}
 				}
@@ -90,41 +84,38 @@
 			return texture;
 			return texture;
 
 
 		}
 		}
-		/** Low-level transcoding API, exposed for use by KTX2Loader. */
-
 
 
+		/** Low-level transcoding API, exposed for use by KTX2Loader. */
 		parseInternalAsync( options ) {
 		parseInternalAsync( options ) {
 
 
 			const {
 			const {
 				levels
 				levels
 			} = options;
 			} = options;
 			const buffers = new Set();
 			const buffers = new Set();
-
 			for ( let i = 0; i < levels.length; i ++ ) {
 			for ( let i = 0; i < levels.length; i ++ ) {
 
 
 				buffers.add( levels[ i ].data.buffer );
 				buffers.add( levels[ i ].data.buffer );
 
 
 			}
 			}
 
 
-			return this._createTexture( Array.from( buffers ), { ...options,
+			return this._createTexture( Array.from( buffers ), {
+				...options,
 				lowLevel: true
 				lowLevel: true
 			} );
 			} );
 
 
 		}
 		}
+
 		/**
 		/**
    * @param {ArrayBuffer[]} buffers
    * @param {ArrayBuffer[]} buffers
    * @param {object?} config
    * @param {object?} config
    * @return {Promise<CompressedTexture>}
    * @return {Promise<CompressedTexture>}
    */
    */
-
-
 		_createTexture( buffers, config = {} ) {
 		_createTexture( buffers, config = {} ) {
 
 
 			let worker;
 			let worker;
 			let taskID;
 			let taskID;
 			const taskConfig = config;
 			const taskConfig = config;
 			let taskCost = 0;
 			let taskCost = 0;
-
 			for ( let i = 0; i < buffers.length; i ++ ) {
 			for ( let i = 0; i < buffers.length; i ++ ) {
 
 
 				taskCost += buffers[ i ].byteLength;
 				taskCost += buffers[ i ].byteLength;
@@ -165,9 +156,9 @@
 				texture.needsUpdate = true;
 				texture.needsUpdate = true;
 				return texture;
 				return texture;
 
 
-			} ); // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
-
+			} );
 
 
+			// Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
 			texturePending.catch( () => true ).then( () => {
 			texturePending.catch( () => true ).then( () => {
 
 
 				if ( worker && taskID ) {
 				if ( worker && taskID ) {
@@ -177,16 +168,15 @@
 
 
 				}
 				}
 
 
-			} ); // Cache the task result.
+			} );
 
 
+			// Cache the task result.
 			_taskCache.set( buffers[ 0 ], {
 			_taskCache.set( buffers[ 0 ], {
 				promise: texturePending
 				promise: texturePending
 			} );
 			} );
-
 			return texturePending;
 			return texturePending;
 
 
 		}
 		}
-
 		_initTranscoder() {
 		_initTranscoder() {
 
 
 			if ( ! this.transcoderPending ) {
 			if ( ! this.transcoderPending ) {
@@ -199,8 +189,9 @@
 
 
 					jsLoader.load( 'basis_transcoder.js', resolve, undefined, reject );
 					jsLoader.load( 'basis_transcoder.js', resolve, undefined, reject );
 
 
-				} ); // Load transcoder WASM binary.
+				} );
 
 
+				// Load transcoder WASM binary.
 				const binaryLoader = new THREE.FileLoader( this.manager );
 				const binaryLoader = new THREE.FileLoader( this.manager );
 				binaryLoader.setPath( this.transcoderPath );
 				binaryLoader.setPath( this.transcoderPath );
 				binaryLoader.setResponseType( 'arraybuffer' );
 				binaryLoader.setResponseType( 'arraybuffer' );
@@ -224,7 +215,6 @@
 			return this.transcoderPending;
 			return this.transcoderPending;
 
 
 		}
 		}
-
 		_allocateWorker( taskCost ) {
 		_allocateWorker( taskCost ) {
 
 
 			return this._initTranscoder().then( () => {
 			return this._initTranscoder().then( () => {
@@ -239,23 +229,17 @@
 						config: this.workerConfig,
 						config: this.workerConfig,
 						transcoderBinary: this.transcoderBinary
 						transcoderBinary: this.transcoderBinary
 					} );
 					} );
-
 					worker.onmessage = function ( e ) {
 					worker.onmessage = function ( e ) {
 
 
 						const message = e.data;
 						const message = e.data;
-
 						switch ( message.type ) {
 						switch ( message.type ) {
 
 
 							case 'transcode':
 							case 'transcode':
 								worker._callbacks[ message.id ].resolve( message );
 								worker._callbacks[ message.id ].resolve( message );
-
 								break;
 								break;
-
 							case 'error':
 							case 'error':
 								worker._callbacks[ message.id ].reject( message );
 								worker._callbacks[ message.id ].reject( message );
-
 								break;
 								break;
-
 							default:
 							default:
 								console.error( 'THREE.BasisTextureLoader: Unexpected message, "' + message.type + '"' );
 								console.error( 'THREE.BasisTextureLoader: Unexpected message, "' + message.type + '"' );
 
 
@@ -282,7 +266,6 @@
 			} );
 			} );
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			for ( let i = 0; i < this.workerPool.length; i ++ ) {
 			for ( let i = 0; i < this.workerPool.length; i ++ ) {
@@ -297,8 +280,8 @@
 		}
 		}
 
 
 	}
 	}
-	/* CONSTANTS */
 
 
+	/* CONSTANTS */
 
 
 	BasisTextureLoader.BasisFormat = {
 	BasisTextureLoader.BasisFormat = {
 		ETC1S: 0,
 		ETC1S: 0,
@@ -335,6 +318,7 @@
 		RGB_PVRTC_4BPPV1_Format: THREE.RGB_PVRTC_4BPPV1_Format,
 		RGB_PVRTC_4BPPV1_Format: THREE.RGB_PVRTC_4BPPV1_Format,
 		RGB_S3TC_DXT1_Format: THREE.RGB_S3TC_DXT1_Format
 		RGB_S3TC_DXT1_Format: THREE.RGB_S3TC_DXT1_Format
 	};
 	};
+
 	/* WEB WORKER */
 	/* WEB WORKER */
 
 
 	BasisTextureLoader.BasisWorker = function () {
 	BasisTextureLoader.BasisWorker = function () {
@@ -343,22 +327,18 @@
 		let transcoderPending;
 		let transcoderPending;
 		let BasisModule;
 		let BasisModule;
 		const EngineFormat = _EngineFormat; // eslint-disable-line no-undef
 		const EngineFormat = _EngineFormat; // eslint-disable-line no-undef
-
 		const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef
 		const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef
-
 		const BasisFormat = _BasisFormat; // eslint-disable-line no-undef
 		const BasisFormat = _BasisFormat; // eslint-disable-line no-undef
 
 
 		onmessage = function ( e ) {
 		onmessage = function ( e ) {
 
 
 			const message = e.data;
 			const message = e.data;
-
 			switch ( message.type ) {
 			switch ( message.type ) {
 
 
 				case 'init':
 				case 'init':
 					config = message.config;
 					config = message.config;
 					init( message.transcoderBinary );
 					init( message.transcoderBinary );
 					break;
 					break;
-
 				case 'transcode':
 				case 'transcode':
 					transcoderPending.then( () => {
 					transcoderPending.then( () => {
 
 
@@ -372,7 +352,6 @@
 								format
 								format
 							} = message.taskConfig.lowLevel ? transcodeLowLevel( message.taskConfig ) : transcode( message.buffers[ 0 ] );
 							} = message.taskConfig.lowLevel ? transcodeLowLevel( message.taskConfig ) : transcode( message.buffers[ 0 ] );
 							const buffers = [];
 							const buffers = [];
-
 							for ( let i = 0; i < mipmaps.length; ++ i ) {
 							for ( let i = 0; i < mipmaps.length; ++ i ) {
 
 
 								buffers.push( mipmaps[ i ].data.buffer );
 								buffers.push( mipmaps[ i ].data.buffer );
@@ -440,7 +419,6 @@
 			const blockByteLength = BasisModule.getBytesPerBlockOrPixel( transcoderFormat );
 			const blockByteLength = BasisModule.getBytesPerBlockOrPixel( transcoderFormat );
 			assert( BasisModule.isFormatSupported( transcoderFormat ), 'THREE.BasisTextureLoader: Unsupported format.' );
 			assert( BasisModule.isFormatSupported( transcoderFormat ), 'THREE.BasisTextureLoader: Unsupported format.' );
 			const mipmaps = [];
 			const mipmaps = [];
-
 			if ( basisFormat === BasisFormat.ETC1S ) {
 			if ( basisFormat === BasisFormat.ETC1S ) {
 
 
 				const transcoder = new BasisModule.LowLevelETC1SImageTranscoder();
 				const transcoder = new BasisModule.LowLevelETC1SImageTranscoder();
@@ -451,7 +429,6 @@
 					selectorsData,
 					selectorsData,
 					tablesData
 					tablesData
 				} = taskConfig.globalData;
 				} = taskConfig.globalData;
-
 				try {
 				try {
 
 
 					let ok;
 					let ok;
@@ -459,7 +436,6 @@
 					assert( ok, 'THREE.BasisTextureLoader: decodePalettes() failed.' );
 					assert( ok, 'THREE.BasisTextureLoader: decodePalettes() failed.' );
 					ok = transcoder.decodeTables( tablesData );
 					ok = transcoder.decodeTables( tablesData );
 					assert( ok, 'THREE.BasisTextureLoader: decodeTables() failed.' );
 					assert( ok, 'THREE.BasisTextureLoader: decodeTables() failed.' );
-
 					for ( let i = 0; i < taskConfig.levels.length; i ++ ) {
 					for ( let i = 0; i < taskConfig.levels.length; i ++ ) {
 
 
 						const level = taskConfig.levels[ i ];
 						const level = taskConfig.levels[ i ];
@@ -519,7 +495,6 @@
 			const height = basisFile.getImageHeight( 0, 0 );
 			const height = basisFile.getImageHeight( 0, 0 );
 			const levels = basisFile.getNumLevels( 0 );
 			const levels = basisFile.getNumLevels( 0 );
 			const hasAlpha = basisFile.getHasAlpha();
 			const hasAlpha = basisFile.getHasAlpha();
-
 			function cleanup() {
 			function cleanup() {
 
 
 				basisFile.close();
 				basisFile.close();
@@ -531,7 +506,6 @@
 				transcoderFormat,
 				transcoderFormat,
 				engineFormat
 				engineFormat
 			} = getTranscoderFormat( basisFormat, width, height, hasAlpha );
 			} = getTranscoderFormat( basisFormat, width, height, hasAlpha );
-
 			if ( ! width || ! height || ! levels ) {
 			if ( ! width || ! height || ! levels ) {
 
 
 				cleanup();
 				cleanup();
@@ -547,14 +521,12 @@
 			}
 			}
 
 
 			const mipmaps = [];
 			const mipmaps = [];
-
 			for ( let mip = 0; mip < levels; mip ++ ) {
 			for ( let mip = 0; mip < levels; mip ++ ) {
 
 
 				const mipWidth = basisFile.getImageWidth( 0, mip );
 				const mipWidth = basisFile.getImageWidth( 0, mip );
 				const mipHeight = basisFile.getImageHeight( 0, mip );
 				const mipHeight = basisFile.getImageHeight( 0, mip );
 				const dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, mip, transcoderFormat ) );
 				const dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, mip, transcoderFormat ) );
 				const status = basisFile.transcodeImage( dst, 0, mip, transcoderFormat, 0, hasAlpha );
 				const status = basisFile.transcodeImage( dst, 0, mip, transcoderFormat, 0, hasAlpha );
-
 				if ( ! status ) {
 				if ( ! status ) {
 
 
 					cleanup();
 					cleanup();
@@ -579,7 +551,10 @@
 				format: engineFormat
 				format: engineFormat
 			};
 			};
 
 
-		} //
+		}
+
+		//
+
 		// Optimal choice of a transcoder target format depends on the Basis format (ETC1S or UASTC),
 		// Optimal choice of a transcoder target format depends on the Basis format (ETC1S or UASTC),
 		// device capabilities, and texture dimensions. The list below ranks the formats separately
 		// device capabilities, and texture dimensions. The list below ranks the formats separately
 		// for ETC1S and UASTC.
 		// for ETC1S and UASTC.
@@ -587,8 +562,6 @@
 		// In some cases, transcoding UASTC to RGBA32 might be preferred for higher quality (at
 		// In some cases, transcoding UASTC to RGBA32 might be preferred for higher quality (at
 		// significant memory cost) compared to ETC1/2, BC1/3, and PVRTC. The transcoder currently
 		// significant memory cost) compared to ETC1/2, BC1/3, and PVRTC. The transcoder currently
 		// chooses RGBA32 only as a last resort and does not expose that option to the caller.
 		// chooses RGBA32 only as a last resort and does not expose that option to the caller.
-
-
 		const FORMAT_OPTIONS = [ {
 		const FORMAT_OPTIONS = [ {
 			if: 'astcSupported',
 			if: 'astcSupported',
 			basisFormat: [ BasisFormat.UASTC_4x4 ],
 			basisFormat: [ BasisFormat.UASTC_4x4 ],
@@ -648,13 +621,11 @@
 			return a.priorityUASTC - b.priorityUASTC;
 			return a.priorityUASTC - b.priorityUASTC;
 
 
 		} );
 		} );
-
 		function getTranscoderFormat( basisFormat, width, height, hasAlpha ) {
 		function getTranscoderFormat( basisFormat, width, height, hasAlpha ) {
 
 
 			let transcoderFormat;
 			let transcoderFormat;
 			let engineFormat;
 			let engineFormat;
 			const options = basisFormat === BasisFormat.ETC1S ? ETC1S_OPTIONS : UASTC_OPTIONS;
 			const options = basisFormat === BasisFormat.ETC1S ? ETC1S_OPTIONS : UASTC_OPTIONS;
-
 			for ( let i = 0; i < options.length; i ++ ) {
 			for ( let i = 0; i < options.length; i ++ ) {
 
 
 				const opt = options[ i ];
 				const opt = options[ i ];
@@ -701,7 +672,6 @@
 		function getTranscodedImageByteLength( transcoderFormat, width, height ) {
 		function getTranscodedImageByteLength( transcoderFormat, width, height ) {
 
 
 			const blockByteLength = BasisModule.getBytesPerBlockOrPixel( transcoderFormat );
 			const blockByteLength = BasisModule.getBytesPerBlockOrPixel( transcoderFormat );
-
 			if ( BasisModule.formatIsUncompressed( transcoderFormat ) ) {
 			if ( BasisModule.formatIsUncompressed( transcoderFormat ) ) {
 
 
 				return width * height * blockByteLength;
 				return width * height * blockByteLength;

文件差異過大導致無法顯示
+ 81 - 141
examples/js/loaders/ColladaLoader.js


+ 24 - 25
examples/js/loaders/DDSLoader.js

@@ -7,7 +7,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		parse( buffer, loadMipmaps ) {
 		parse( buffer, loadMipmaps ) {
 
 
 			const dds = {
 			const dds = {
@@ -16,19 +15,25 @@
 				height: 0,
 				height: 0,
 				format: null,
 				format: null,
 				mipmapCount: 1
 				mipmapCount: 1
-			}; // Adapted from @toji's DDS utils
+			};
+
+			// Adapted from @toji's DDS utils
 			// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
 			// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
+
 			// All values and structures referenced from:
 			// All values and structures referenced from:
 			// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
 			// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
 
 
-			const DDS_MAGIC = 0x20534444; // const DDSD_CAPS = 0x1;
+			const DDS_MAGIC = 0x20534444;
+
+			// const DDSD_CAPS = 0x1;
 			// const DDSD_HEIGHT = 0x2;
 			// const DDSD_HEIGHT = 0x2;
 			// const DDSD_WIDTH = 0x4;
 			// const DDSD_WIDTH = 0x4;
 			// const DDSD_PITCH = 0x8;
 			// const DDSD_PITCH = 0x8;
 			// const DDSD_PIXELFORMAT = 0x1000;
 			// const DDSD_PIXELFORMAT = 0x1000;
-
-			const DDSD_MIPMAPCOUNT = 0x20000; // const DDSD_LINEARSIZE = 0x80000;
+			const DDSD_MIPMAPCOUNT = 0x20000;
+			// const DDSD_LINEARSIZE = 0x80000;
 			// const DDSD_DEPTH = 0x800000;
 			// const DDSD_DEPTH = 0x800000;
+
 			// const DDSCAPS_COMPLEX = 0x8;
 			// const DDSCAPS_COMPLEX = 0x8;
 			// const DDSCAPS_MIPMAP = 0x400000;
 			// const DDSCAPS_MIPMAP = 0x400000;
 			// const DDSCAPS_TEXTURE = 0x1000;
 			// const DDSCAPS_TEXTURE = 0x1000;
@@ -39,7 +44,9 @@
 			const DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
 			const DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
 			const DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
 			const DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
 			const DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000;
 			const DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000;
-			const DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000; // const DDSCAPS2_VOLUME = 0x200000;
+			const DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000;
+			// const DDSCAPS2_VOLUME = 0x200000;
+
 			// const DDPF_ALPHAPIXELS = 0x1;
 			// const DDPF_ALPHAPIXELS = 0x1;
 			// const DDPF_ALPHA = 0x2;
 			// const DDPF_ALPHA = 0x2;
 			// const DDPF_FOURCC = 0x4;
 			// const DDPF_FOURCC = 0x4;
@@ -66,7 +73,6 @@
 				const byteArray = new Uint8Array( dataLength );
 				const byteArray = new Uint8Array( dataLength );
 				let dst = 0;
 				let dst = 0;
 				let src = 0;
 				let src = 0;
-
 				for ( let y = 0; y < height; y ++ ) {
 				for ( let y = 0; y < height; y ++ ) {
 
 
 					for ( let x = 0; x < width; x ++ ) {
 					for ( let x = 0; x < width; x ++ ) {
@@ -81,13 +87,10 @@
 						src ++;
 						src ++;
 						byteArray[ dst ] = r;
 						byteArray[ dst ] = r;
 						dst ++; //r
 						dst ++; //r
-
 						byteArray[ dst ] = g;
 						byteArray[ dst ] = g;
 						dst ++; //g
 						dst ++; //g
-
 						byteArray[ dst ] = b;
 						byteArray[ dst ] = b;
 						dst ++; //b
 						dst ++; //b
-
 						byteArray[ dst ] = a;
 						byteArray[ dst ] = a;
 						dst ++; //a
 						dst ++; //a
 
 
@@ -104,6 +107,7 @@
 			const FOURCC_DXT5 = fourCCToInt32( 'DXT5' );
 			const FOURCC_DXT5 = fourCCToInt32( 'DXT5' );
 			const FOURCC_ETC1 = fourCCToInt32( 'ETC1' );
 			const FOURCC_ETC1 = fourCCToInt32( 'ETC1' );
 			const headerLengthInt = 31; // The header length in 32 bit ints
 			const headerLengthInt = 31; // The header length in 32 bit ints
+
 			// Offsets into the header array
 			// Offsets into the header array
 
 
 			const off_magic = 0;
 			const off_magic = 0;
@@ -111,21 +115,24 @@
 			const off_flags = 2;
 			const off_flags = 2;
 			const off_height = 3;
 			const off_height = 3;
 			const off_width = 4;
 			const off_width = 4;
-			const off_mipmapCount = 7; // const off_pfFlags = 20;
+			const off_mipmapCount = 7;
 
 
+			// const off_pfFlags = 20;
 			const off_pfFourCC = 21;
 			const off_pfFourCC = 21;
 			const off_RGBBitCount = 22;
 			const off_RGBBitCount = 22;
 			const off_RBitMask = 23;
 			const off_RBitMask = 23;
 			const off_GBitMask = 24;
 			const off_GBitMask = 24;
 			const off_BBitMask = 25;
 			const off_BBitMask = 25;
-			const off_ABitMask = 26; // const off_caps = 27;
+			const off_ABitMask = 26;
 
 
-			const off_caps2 = 28; // const off_caps3 = 29;
+			// const off_caps = 27;
+			const off_caps2 = 28;
+			// const off_caps3 = 29;
 			// const off_caps4 = 30;
 			// const off_caps4 = 30;
+
 			// Parse header
 			// Parse header
 
 
 			const header = new Int32Array( buffer, 0, headerLengthInt );
 			const header = new Int32Array( buffer, 0, headerLengthInt );
-
 			if ( header[ off_magic ] !== DDS_MAGIC ) {
 			if ( header[ off_magic ] !== DDS_MAGIC ) {
 
 
 				console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' );
 				console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' );
@@ -136,29 +143,24 @@
 			let blockBytes;
 			let blockBytes;
 			const fourCC = header[ off_pfFourCC ];
 			const fourCC = header[ off_pfFourCC ];
 			let isRGBAUncompressed = false;
 			let isRGBAUncompressed = false;
-
 			switch ( fourCC ) {
 			switch ( fourCC ) {
 
 
 				case FOURCC_DXT1:
 				case FOURCC_DXT1:
 					blockBytes = 8;
 					blockBytes = 8;
 					dds.format = THREE.RGB_S3TC_DXT1_Format;
 					dds.format = THREE.RGB_S3TC_DXT1_Format;
 					break;
 					break;
-
 				case FOURCC_DXT3:
 				case FOURCC_DXT3:
 					blockBytes = 16;
 					blockBytes = 16;
 					dds.format = THREE.RGBA_S3TC_DXT3_Format;
 					dds.format = THREE.RGBA_S3TC_DXT3_Format;
 					break;
 					break;
-
 				case FOURCC_DXT5:
 				case FOURCC_DXT5:
 					blockBytes = 16;
 					blockBytes = 16;
 					dds.format = THREE.RGBA_S3TC_DXT5_Format;
 					dds.format = THREE.RGBA_S3TC_DXT5_Format;
 					break;
 					break;
-
 				case FOURCC_ETC1:
 				case FOURCC_ETC1:
 					blockBytes = 8;
 					blockBytes = 8;
 					dds.format = THREE.RGB_ETC1_Format;
 					dds.format = THREE.RGB_ETC1_Format;
 					break;
 					break;
-
 				default:
 				default:
 					if ( header[ off_RGBBitCount ] === 32 && header[ off_RBitMask ] & 0xff0000 && header[ off_GBitMask ] & 0xff00 && header[ off_BBitMask ] & 0xff && header[ off_ABitMask ] & 0xff000000 ) {
 					if ( header[ off_RGBBitCount ] === 32 && header[ off_RBitMask ] & 0xff0000 && header[ off_GBitMask ] & 0xff00 && header[ off_BBitMask ] & 0xff && header[ off_ABitMask ] & 0xff000000 ) {
 
 
@@ -176,7 +178,6 @@
 			}
 			}
 
 
 			dds.mipmapCount = 1;
 			dds.mipmapCount = 1;
-
 			if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
 			if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
 
 
 				dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
 				dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
@@ -185,7 +186,6 @@
 
 
 			const caps2 = header[ off_caps2 ];
 			const caps2 = header[ off_caps2 ];
 			dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
 			dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
-
 			if ( dds.isCubemap && ( ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) || ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) || ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) ) ) {
 			if ( dds.isCubemap && ( ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) || ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) || ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) || ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) ) ) {
 
 
 				console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
 				console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
@@ -195,19 +195,18 @@
 
 
 			dds.width = header[ off_width ];
 			dds.width = header[ off_width ];
 			dds.height = header[ off_height ];
 			dds.height = header[ off_height ];
-			let dataOffset = header[ off_size ] + 4; // Extract mipmaps buffers
+			let dataOffset = header[ off_size ] + 4;
 
 
-			const faces = dds.isCubemap ? 6 : 1;
+			// Extract mipmaps buffers
 
 
+			const faces = dds.isCubemap ? 6 : 1;
 			for ( let face = 0; face < faces; face ++ ) {
 			for ( let face = 0; face < faces; face ++ ) {
 
 
 				let width = dds.width;
 				let width = dds.width;
 				let height = dds.height;
 				let height = dds.height;
-
 				for ( let i = 0; i < dds.mipmapCount; i ++ ) {
 				for ( let i = 0; i < dds.mipmapCount; i ++ ) {
 
 
 					let byteArray, dataLength;
 					let byteArray, dataLength;
-
 					if ( isRGBAUncompressed ) {
 					if ( isRGBAUncompressed ) {
 
 
 						byteArray = loadARGBMip( buffer, dataOffset, width, height );
 						byteArray = loadARGBMip( buffer, dataOffset, width, height );

+ 29 - 66
examples/js/loaders/DRACOLoader.js

@@ -1,7 +1,6 @@
 ( function () {
 ( function () {
 
 
 	const _taskCache = new WeakMap();
 	const _taskCache = new WeakMap();
-
 	class DRACOLoader extends THREE.Loader {
 	class DRACOLoader extends THREE.Loader {
 
 
 		constructor( manager ) {
 		constructor( manager ) {
@@ -29,28 +28,24 @@
 			};
 			};
 
 
 		}
 		}
-
 		setDecoderPath( path ) {
 		setDecoderPath( path ) {
 
 
 			this.decoderPath = path;
 			this.decoderPath = path;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setDecoderConfig( config ) {
 		setDecoderConfig( config ) {
 
 
 			this.decoderConfig = config;
 			this.decoderConfig = config;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setWorkerLimit( workerLimit ) {
 		setWorkerLimit( workerLimit ) {
 
 
 			this.workerLimit = workerLimit;
 			this.workerLimit = workerLimit;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const loader = new THREE.FileLoader( this.manager );
 			const loader = new THREE.FileLoader( this.manager );
@@ -65,7 +60,6 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) {
 		decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) {
 
 
 			const taskConfig = {
 			const taskConfig = {
@@ -76,16 +70,15 @@
 			return this.decodeGeometry( buffer, taskConfig ).then( callback );
 			return this.decodeGeometry( buffer, taskConfig ).then( callback );
 
 
 		}
 		}
-
 		decodeGeometry( buffer, taskConfig ) {
 		decodeGeometry( buffer, taskConfig ) {
 
 
-			const taskKey = JSON.stringify( taskConfig ); // Check for an existing task using this buffer. A transferred buffer cannot be transferred
-			// again from this thread.
+			const taskKey = JSON.stringify( taskConfig );
 
 
+			// Check for an existing task using this buffer. A transferred buffer cannot be transferred
+			// again from this thread.
 			if ( _taskCache.has( buffer ) ) {
 			if ( _taskCache.has( buffer ) ) {
 
 
 				const cachedTask = _taskCache.get( buffer );
 				const cachedTask = _taskCache.get( buffer );
-
 				if ( cachedTask.key === taskKey ) {
 				if ( cachedTask.key === taskKey ) {
 
 
 					return cachedTask.promise;
 					return cachedTask.promise;
@@ -100,14 +93,16 @@
 
 
 				}
 				}
 
 
-			} //
+			}
 
 
+			//
 
 
 			let worker;
 			let worker;
 			const taskID = this.workerNextTaskID ++;
 			const taskID = this.workerNextTaskID ++;
-			const taskCost = buffer.byteLength; // Obtain a worker and assign a task, and construct a geometry instance
-			// when the task completes.
+			const taskCost = buffer.byteLength;
 
 
+			// Obtain a worker and assign a task, and construct a geometry instance
+			// when the task completes.
 			const geometryPending = this._getWorker( taskID, taskCost ).then( _worker => {
 			const geometryPending = this._getWorker( taskID, taskCost ).then( _worker => {
 
 
 				worker = _worker;
 				worker = _worker;
@@ -122,37 +117,39 @@
 						id: taskID,
 						id: taskID,
 						taskConfig,
 						taskConfig,
 						buffer
 						buffer
-					}, [ buffer ] ); // this.debug();
+					}, [ buffer ] );
 
 
-				} );
+					// this.debug();
 
 
-			} ).then( message => this._createGeometry( message.geometry ) ); // Remove task from the task list.
-			// Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
+				} );
 
 
+			} ).then( message => this._createGeometry( message.geometry ) );
 
 
+			// Remove task from the task list.
+			// Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
 			geometryPending.catch( () => true ).then( () => {
 			geometryPending.catch( () => true ).then( () => {
 
 
 				if ( worker && taskID ) {
 				if ( worker && taskID ) {
 
 
-					this._releaseTask( worker, taskID ); // this.debug();
+					this._releaseTask( worker, taskID );
+
+					// this.debug();
 
 
 				}
 				}
 
 
-			} ); // Cache the task result.
+			} );
 
 
+			// Cache the task result.
 			_taskCache.set( buffer, {
 			_taskCache.set( buffer, {
 				key: taskKey,
 				key: taskKey,
 				promise: geometryPending
 				promise: geometryPending
 			} );
 			} );
-
 			return geometryPending;
 			return geometryPending;
 
 
 		}
 		}
-
 		_createGeometry( geometryData ) {
 		_createGeometry( geometryData ) {
 
 
 			const geometry = new THREE.BufferGeometry();
 			const geometry = new THREE.BufferGeometry();
-
 			if ( geometryData.index ) {
 			if ( geometryData.index ) {
 
 
 				geometry.setIndex( new THREE.BufferAttribute( geometryData.index.array, 1 ) );
 				geometry.setIndex( new THREE.BufferAttribute( geometryData.index.array, 1 ) );
@@ -172,7 +169,6 @@
 			return geometry;
 			return geometry;
 
 
 		}
 		}
-
 		_loadLibrary( url, responseType ) {
 		_loadLibrary( url, responseType ) {
 
 
 			const loader = new THREE.FileLoader( this.manager );
 			const loader = new THREE.FileLoader( this.manager );
@@ -186,21 +182,17 @@
 			} );
 			} );
 
 
 		}
 		}
-
 		preload() {
 		preload() {
 
 
 			this._initDecoder();
 			this._initDecoder();
-
 			return this;
 			return this;
 
 
 		}
 		}
-
 		_initDecoder() {
 		_initDecoder() {
 
 
 			if ( this.decoderPending ) return this.decoderPending;
 			if ( this.decoderPending ) return this.decoderPending;
 			const useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';
 			const useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';
 			const librariesPending = [];
 			const librariesPending = [];
-
 			if ( useJS ) {
 			if ( useJS ) {
 
 
 				librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) );
 				librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) );
@@ -215,7 +207,6 @@
 			this.decoderPending = Promise.all( librariesPending ).then( libraries => {
 			this.decoderPending = Promise.all( librariesPending ).then( libraries => {
 
 
 				const jsContent = libraries[ 0 ];
 				const jsContent = libraries[ 0 ];
-
 				if ( ! useJS ) {
 				if ( ! useJS ) {
 
 
 					this.decoderConfig.wasmBinary = libraries[ 1 ];
 					this.decoderConfig.wasmBinary = libraries[ 1 ];
@@ -230,7 +221,6 @@
 			return this.decoderPending;
 			return this.decoderPending;
 
 
 		}
 		}
-
 		_getWorker( taskID, taskCost ) {
 		_getWorker( taskID, taskCost ) {
 
 
 			return this._initDecoder().then( () => {
 			return this._initDecoder().then( () => {
@@ -245,23 +235,17 @@
 						type: 'init',
 						type: 'init',
 						decoderConfig: this.decoderConfig
 						decoderConfig: this.decoderConfig
 					} );
 					} );
-
 					worker.onmessage = function ( e ) {
 					worker.onmessage = function ( e ) {
 
 
 						const message = e.data;
 						const message = e.data;
-
 						switch ( message.type ) {
 						switch ( message.type ) {
 
 
 							case 'decode':
 							case 'decode':
 								worker._callbacks[ message.id ].resolve( message );
 								worker._callbacks[ message.id ].resolve( message );
-
 								break;
 								break;
-
 							case 'error':
 							case 'error':
 								worker._callbacks[ message.id ].reject( message );
 								worker._callbacks[ message.id ].reject( message );
-
 								break;
 								break;
-
 							default:
 							default:
 								console.error( 'THREE.DRACOLoader: Unexpected message, "' + message.type + '"' );
 								console.error( 'THREE.DRACOLoader: Unexpected message, "' + message.type + '"' );
 
 
@@ -289,7 +273,6 @@
 			} );
 			} );
 
 
 		}
 		}
-
 		_releaseTask( worker, taskID ) {
 		_releaseTask( worker, taskID ) {
 
 
 			worker._taskLoad -= worker._taskCosts[ taskID ];
 			worker._taskLoad -= worker._taskCosts[ taskID ];
@@ -297,13 +280,11 @@
 			delete worker._taskCosts[ taskID ];
 			delete worker._taskCosts[ taskID ];
 
 
 		}
 		}
-
 		debug() {
 		debug() {
 
 
 			console.log( 'Task load: ', this.workerPool.map( worker => worker._taskLoad ) );
 			console.log( 'Task load: ', this.workerPool.map( worker => worker._taskLoad ) );
 
 
 		}
 		}
-
 		dispose() {
 		dispose() {
 
 
 			for ( let i = 0; i < this.workerPool.length; ++ i ) {
 			for ( let i = 0; i < this.workerPool.length; ++ i ) {
@@ -318,25 +299,21 @@
 		}
 		}
 
 
 	}
 	}
-	/* WEB WORKER */
 
 
+	/* WEB WORKER */
 
 
 	function DRACOWorker() {
 	function DRACOWorker() {
 
 
 		let decoderConfig;
 		let decoderConfig;
 		let decoderPending;
 		let decoderPending;
-
 		onmessage = function ( e ) {
 		onmessage = function ( e ) {
 
 
 			const message = e.data;
 			const message = e.data;
-
 			switch ( message.type ) {
 			switch ( message.type ) {
 
 
 				case 'init':
 				case 'init':
 					decoderConfig = message.decoderConfig;
 					decoderConfig = message.decoderConfig;
-					decoderPending = new Promise( function ( resolve
-						/*, reject*/
-					) {
+					decoderPending = new Promise( function ( resolve /*, reject*/ ) {
 
 
 						decoderConfig.onModuleLoaded = function ( draco ) {
 						decoderConfig.onModuleLoaded = function ( draco ) {
 
 
@@ -350,8 +327,8 @@
 						DracoDecoderModule( decoderConfig ); // eslint-disable-line no-undef
 						DracoDecoderModule( decoderConfig ); // eslint-disable-line no-undef
 
 
 					} );
 					} );
-					break;
 
 
+					break;
 				case 'decode':
 				case 'decode':
 					const buffer = message.buffer;
 					const buffer = message.buffer;
 					const taskConfig = message.taskConfig;
 					const taskConfig = message.taskConfig;
@@ -361,7 +338,6 @@
 						const decoder = new draco.Decoder();
 						const decoder = new draco.Decoder();
 						const decoderBuffer = new draco.DecoderBuffer();
 						const decoderBuffer = new draco.DecoderBuffer();
 						decoderBuffer.Init( new Int8Array( buffer ), buffer.byteLength );
 						decoderBuffer.Init( new Int8Array( buffer ), buffer.byteLength );
-
 						try {
 						try {
 
 
 							const geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig );
 							const geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig );
@@ -403,7 +379,6 @@
 			let dracoGeometry;
 			let dracoGeometry;
 			let decodingStatus;
 			let decodingStatus;
 			const geometryType = decoder.GetEncodedGeometryType( decoderBuffer );
 			const geometryType = decoder.GetEncodedGeometryType( decoderBuffer );
-
 			if ( geometryType === draco.TRIANGULAR_MESH ) {
 			if ( geometryType === draco.TRIANGULAR_MESH ) {
 
 
 				dracoGeometry = new draco.Mesh();
 				dracoGeometry = new draco.Mesh();
@@ -429,17 +404,19 @@
 			const geometry = {
 			const geometry = {
 				index: null,
 				index: null,
 				attributes: []
 				attributes: []
-			}; // Gather all vertex attributes.
+			};
 
 
+			// Gather all vertex attributes.
 			for ( const attributeName in attributeIDs ) {
 			for ( const attributeName in attributeIDs ) {
 
 
 				const attributeType = self[ attributeTypes[ attributeName ] ];
 				const attributeType = self[ attributeTypes[ attributeName ] ];
 				let attribute;
 				let attribute;
-				let attributeID; // A Draco file may be created with default vertex attributes, whose attribute IDs
+				let attributeID;
+
+				// A Draco file may be created with default vertex attributes, whose attribute IDs
 				// are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,
 				// are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,
 				// a Draco file may contain a custom set of attributes, identified by known unique
 				// a Draco file may contain a custom set of attributes, identified by known unique
 				// IDs. glTF files always do the latter, and `.drc` files typically do the former.
 				// IDs. glTF files always do the latter, and `.drc` files typically do the former.
-
 				if ( taskConfig.useUniqueIDs ) {
 				if ( taskConfig.useUniqueIDs ) {
 
 
 					attributeID = attributeIDs[ attributeName ];
 					attributeID = attributeIDs[ attributeName ];
@@ -455,9 +432,9 @@
 
 
 				geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) );
 				geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) );
 
 
-			} // Add index.
-
+			}
 
 
+			// Add index.
 			if ( geometryType === draco.TRIANGULAR_MESH ) {
 			if ( geometryType === draco.TRIANGULAR_MESH ) {
 
 
 				geometry.index = decodeIndex( draco, decoder, dracoGeometry );
 				geometry.index = decodeIndex( draco, decoder, dracoGeometry );
@@ -474,14 +451,10 @@
 			const numFaces = dracoGeometry.num_faces();
 			const numFaces = dracoGeometry.num_faces();
 			const numIndices = numFaces * 3;
 			const numIndices = numFaces * 3;
 			const byteLength = numIndices * 4;
 			const byteLength = numIndices * 4;
-
 			const ptr = draco._malloc( byteLength );
 			const ptr = draco._malloc( byteLength );
-
 			decoder.GetTrianglesUInt32Array( dracoGeometry, byteLength, ptr );
 			decoder.GetTrianglesUInt32Array( dracoGeometry, byteLength, ptr );
 			const index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice();
 			const index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice();
-
 			draco._free( ptr );
 			draco._free( ptr );
-
 			return {
 			return {
 				array: index,
 				array: index,
 				itemSize: 1
 				itemSize: 1
@@ -496,14 +469,10 @@
 			const numValues = numPoints * numComponents;
 			const numValues = numPoints * numComponents;
 			const byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
 			const byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
 			const dataType = getDracoDataType( draco, attributeType );
 			const dataType = getDracoDataType( draco, attributeType );
-
 			const ptr = draco._malloc( byteLength );
 			const ptr = draco._malloc( byteLength );
-
 			decoder.GetAttributeDataArrayForAllPoints( dracoGeometry, attribute, dataType, byteLength, ptr );
 			decoder.GetAttributeDataArrayForAllPoints( dracoGeometry, attribute, dataType, byteLength, ptr );
 			const array = new attributeType( draco.HEAPF32.buffer, ptr, numValues ).slice();
 			const array = new attributeType( draco.HEAPF32.buffer, ptr, numValues ).slice();
-
 			draco._free( ptr );
 			draco._free( ptr );
-
 			return {
 			return {
 				name: attributeName,
 				name: attributeName,
 				array: array,
 				array: array,
@@ -518,22 +487,16 @@
 
 
 				case Float32Array:
 				case Float32Array:
 					return draco.DT_FLOAT32;
 					return draco.DT_FLOAT32;
-
 				case Int8Array:
 				case Int8Array:
 					return draco.DT_INT8;
 					return draco.DT_INT8;
-
 				case Int16Array:
 				case Int16Array:
 					return draco.DT_INT16;
 					return draco.DT_INT16;
-
 				case Int32Array:
 				case Int32Array:
 					return draco.DT_INT32;
 					return draco.DT_INT32;
-
 				case Uint8Array:
 				case Uint8Array:
 					return draco.DT_UINT8;
 					return draco.DT_UINT8;
-
 				case Uint16Array:
 				case Uint16Array:
 					return draco.DT_UINT16;
 					return draco.DT_UINT16;
-
 				case Uint32Array:
 				case Uint32Array:
 					return draco.DT_UINT32;
 					return draco.DT_UINT32;
 
 

文件差異過大導致無法顯示
+ 67 - 162
examples/js/loaders/EXRLoader.js


文件差異過大導致無法顯示
+ 87 - 164
examples/js/loaders/FBXLoader.js


+ 6 - 15
examples/js/loaders/FontLoader.js

@@ -7,7 +7,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -23,15 +22,15 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( json ) {
 		parse( json ) {
 
 
 			return new Font( json );
 			return new Font( json );
 
 
 		}
 		}
 
 
-	} //
+	}
 
 
+	//
 
 
 	class Font {
 	class Font {
 
 
@@ -42,12 +41,10 @@
 			this.data = data;
 			this.data = data;
 
 
 		}
 		}
-
 		generateShapes( text, size = 100 ) {
 		generateShapes( text, size = 100 ) {
 
 
 			const shapes = [];
 			const shapes = [];
 			const paths = createPaths( text, size, this.data );
 			const paths = createPaths( text, size, this.data );
-
 			for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
 			for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
 
 
 				shapes.push( ...paths[ p ].toShapes() );
 				shapes.push( ...paths[ p ].toShapes() );
@@ -59,7 +56,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function createPaths( text, size, data ) {
 	function createPaths( text, size, data ) {
 
 
 		const chars = Array.from( text );
 		const chars = Array.from( text );
@@ -68,11 +64,9 @@
 		const paths = [];
 		const paths = [];
 		let offsetX = 0,
 		let offsetX = 0,
 			offsetY = 0;
 			offsetY = 0;
-
 		for ( let i = 0; i < chars.length; i ++ ) {
 		for ( let i = 0; i < chars.length; i ++ ) {
 
 
 			const char = chars[ i ];
 			const char = chars[ i ];
-
 			if ( char === '\n' ) {
 			if ( char === '\n' ) {
 
 
 				offsetX = 0;
 				offsetX = 0;
@@ -95,7 +89,6 @@
 	function createPath( char, scale, offsetX, offsetY, data ) {
 	function createPath( char, scale, offsetX, offsetY, data ) {
 
 
 		const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
 		const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
-
 		if ( ! glyph ) {
 		if ( ! glyph ) {
 
 
 			console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
 			console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
@@ -105,42 +98,40 @@
 
 
 		const path = new THREE.ShapePath();
 		const path = new THREE.ShapePath();
 		let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
 		let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
-
 		if ( glyph.o ) {
 		if ( glyph.o ) {
 
 
 			const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
 			const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
-
 			for ( let i = 0, l = outline.length; i < l; ) {
 			for ( let i = 0, l = outline.length; i < l; ) {
 
 
 				const action = outline[ i ++ ];
 				const action = outline[ i ++ ];
-
 				switch ( action ) {
 				switch ( action ) {
 
 
 					case 'm':
 					case 'm':
 						// moveTo
 						// moveTo
+
 						x = outline[ i ++ ] * scale + offsetX;
 						x = outline[ i ++ ] * scale + offsetX;
 						y = outline[ i ++ ] * scale + offsetY;
 						y = outline[ i ++ ] * scale + offsetY;
 						path.moveTo( x, y );
 						path.moveTo( x, y );
 						break;
 						break;
-
 					case 'l':
 					case 'l':
 						// lineTo
 						// lineTo
+
 						x = outline[ i ++ ] * scale + offsetX;
 						x = outline[ i ++ ] * scale + offsetX;
 						y = outline[ i ++ ] * scale + offsetY;
 						y = outline[ i ++ ] * scale + offsetY;
 						path.lineTo( x, y );
 						path.lineTo( x, y );
 						break;
 						break;
-
 					case 'q':
 					case 'q':
 						// quadraticCurveTo
 						// quadraticCurveTo
+
 						cpx = outline[ i ++ ] * scale + offsetX;
 						cpx = outline[ i ++ ] * scale + offsetX;
 						cpy = outline[ i ++ ] * scale + offsetY;
 						cpy = outline[ i ++ ] * scale + offsetY;
 						cpx1 = outline[ i ++ ] * scale + offsetX;
 						cpx1 = outline[ i ++ ] * scale + offsetX;
 						cpy1 = outline[ i ++ ] * scale + offsetY;
 						cpy1 = outline[ i ++ ] * scale + offsetY;
 						path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
 						path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
 						break;
 						break;
-
 					case 'b':
 					case 'b':
 						// bezierCurveTo
 						// bezierCurveTo
+
 						cpx = outline[ i ++ ] * scale + offsetX;
 						cpx = outline[ i ++ ] * scale + offsetX;
 						cpy = outline[ i ++ ] * scale + offsetY;
 						cpy = outline[ i ++ ] * scale + offsetY;
 						cpx1 = outline[ i ++ ] * scale + offsetX;
 						cpx1 = outline[ i ++ ] * scale + offsetX;

+ 15 - 16
examples/js/loaders/GCodeLoader.js

@@ -17,7 +17,6 @@
 			this.splitLayer = false;
 			this.splitLayer = false;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -50,7 +49,6 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			let state = {
 			let state = {
@@ -72,7 +70,6 @@
 				color: 0x00FF00
 				color: 0x00FF00
 			} );
 			} );
 			extrudingMaterial.name = 'extruded';
 			extrudingMaterial.name = 'extruded';
-
 			function newLayer( line ) {
 			function newLayer( line ) {
 
 
 				currentLayer = {
 				currentLayer = {
@@ -82,9 +79,9 @@
 				};
 				};
 				layers.push( currentLayer );
 				layers.push( currentLayer );
 
 
-			} //Create lie segment between p1 and p2
-
+			}
 
 
+			//Create lie segment between p1 and p2
 			function addSegment( p1, p2 ) {
 			function addSegment( p1, p2 ) {
 
 
 				if ( currentLayer === undefined ) {
 				if ( currentLayer === undefined ) {
@@ -120,12 +117,12 @@
 			}
 			}
 
 
 			const lines = data.replace( /;.+/g, '' ).split( '\n' );
 			const lines = data.replace( /;.+/g, '' ).split( '\n' );
-
 			for ( let i = 0; i < lines.length; i ++ ) {
 			for ( let i = 0; i < lines.length; i ++ ) {
 
 
 				const tokens = lines[ i ].split( ' ' );
 				const tokens = lines[ i ].split( ' ' );
-				const cmd = tokens[ 0 ].toUpperCase(); //Argumments
+				const cmd = tokens[ 0 ].toUpperCase();
 
 
+				//Argumments
 				const args = {};
 				const args = {};
 				tokens.splice( 1 ).forEach( function ( token ) {
 				tokens.splice( 1 ).forEach( function ( token ) {
 
 
@@ -137,9 +134,10 @@
 
 
 					}
 					}
 
 
-				} ); //Process commands
-				//G0/G1 – Linear Movement
+				} );
 
 
+				//Process commands
+				//G0/G1 – Linear Movement
 				if ( cmd === 'G0' || cmd === 'G1' ) {
 				if ( cmd === 'G0' || cmd === 'G1' ) {
 
 
 					const line = {
 					const line = {
@@ -148,12 +146,12 @@
 						z: args.z !== undefined ? absolute( state.z, args.z ) : state.z,
 						z: args.z !== undefined ? absolute( state.z, args.z ) : state.z,
 						e: args.e !== undefined ? absolute( state.e, args.e ) : state.e,
 						e: args.e !== undefined ? absolute( state.e, args.e ) : state.e,
 						f: args.f !== undefined ? absolute( state.f, args.f ) : state.f
 						f: args.f !== undefined ? absolute( state.f, args.f ) : state.f
-					}; //Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position
+					};
 
 
+					//Layer change detection is or made by watching Z, it's made by watching when we extrude at a new Z position
 					if ( delta( state.e, line.e ) > 0 ) {
 					if ( delta( state.e, line.e ) > 0 ) {
 
 
 						state.extruding = delta( state.e, line.e ) > 0;
 						state.extruding = delta( state.e, line.e ) > 0;
-
 						if ( currentLayer == undefined || line.z != currentLayer.z ) {
 						if ( currentLayer == undefined || line.z != currentLayer.z ) {
 
 
 							newLayer( line );
 							newLayer( line );
@@ -165,7 +163,9 @@
 					addSegment( state, line );
 					addSegment( state, line );
 					state = line;
 					state = line;
 
 
-				} else if ( cmd === 'G2' || cmd === 'G3' ) { //G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise )
+				} else if ( cmd === 'G2' || cmd === 'G3' ) {
+
+					//G2/G3 - Arc Movement ( G2 clock wise and G3 counter clock wise )
 					//console.warn( 'THREE.GCodeLoader: Arc command not supported' );
 					//console.warn( 'THREE.GCodeLoader: Arc command not supported' );
 				} else if ( cmd === 'G90' ) {
 				} else if ( cmd === 'G90' ) {
 
 
@@ -186,7 +186,9 @@
 					line.z = args.z !== undefined ? args.z : line.z;
 					line.z = args.z !== undefined ? args.z : line.z;
 					line.e = args.e !== undefined ? args.e : line.e;
 					line.e = args.e !== undefined ? args.e : line.e;
 
 
-				} else { //console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd );
+				} else {
+
+					//console.warn( 'THREE.GCodeLoader: Command not supported:' + cmd );
 				}
 				}
 
 
 			}
 			}
@@ -203,7 +205,6 @@
 
 
 			const object = new THREE.Group();
 			const object = new THREE.Group();
 			object.name = 'gcode';
 			object.name = 'gcode';
-
 			if ( this.splitLayer ) {
 			if ( this.splitLayer ) {
 
 
 				for ( let i = 0; i < layers.length; i ++ ) {
 				for ( let i = 0; i < layers.length; i ++ ) {
@@ -218,13 +219,11 @@
 
 
 				const vertex = [],
 				const vertex = [],
 					pathVertex = [];
 					pathVertex = [];
-
 				for ( let i = 0; i < layers.length; i ++ ) {
 				for ( let i = 0; i < layers.length; i ++ ) {
 
 
 					const layer = layers[ i ];
 					const layer = layers[ i ];
 					const layerVertex = layer.vertex;
 					const layerVertex = layer.vertex;
 					const layerPathVertex = layer.pathVertex;
 					const layerPathVertex = layer.pathVertex;
-
 					for ( let j = 0; j < layerVertex.length; j ++ ) {
 					for ( let j = 0; j < layerVertex.length; j ++ ) {
 
 
 						vertex.push( layerVertex[ j ] );
 						vertex.push( layerVertex[ j ] );

文件差異過大導致無法顯示
+ 50 - 147
examples/js/loaders/GLTFLoader.js


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

@@ -9,12 +9,10 @@
 			this.type = THREE.HalfFloatType;
 			this.type = THREE.HalfFloatType;
 
 
 		}
 		}
-
 		load( urls, onLoad, onProgress, onError ) {
 		load( urls, onLoad, onProgress, onError ) {
 
 
 			const texture = new THREE.CubeTexture();
 			const texture = new THREE.CubeTexture();
 			texture.type = this.type;
 			texture.type = this.type;
-
 			switch ( texture.type ) {
 			switch ( texture.type ) {
 
 
 				case THREE.FloatType:
 				case THREE.FloatType:
@@ -23,7 +21,6 @@
 					texture.magFilter = THREE.LinearFilter;
 					texture.magFilter = THREE.LinearFilter;
 					texture.generateMipmaps = false;
 					texture.generateMipmaps = false;
 					break;
 					break;
-
 				case THREE.HalfFloatType:
 				case THREE.HalfFloatType:
 					texture.encoding = THREE.LinearEncoding;
 					texture.encoding = THREE.LinearEncoding;
 					texture.minFilter = THREE.LinearFilter;
 					texture.minFilter = THREE.LinearFilter;
@@ -35,7 +32,6 @@
 
 
 			const scope = this;
 			const scope = this;
 			let loaded = 0;
 			let loaded = 0;
-
 			function loadHDRData( i, onLoad, onProgress, onError ) {
 			function loadHDRData( i, onLoad, onProgress, onError ) {
 
 
 				new THREE.FileLoader( scope.manager ).setPath( scope.path ).setResponseType( 'arraybuffer' ).setWithCredentials( scope.withCredentials ).load( urls[ i ], function ( buffer ) {
 				new THREE.FileLoader( scope.manager ).setPath( scope.path ).setResponseType( 'arraybuffer' ).setWithCredentials( scope.withCredentials ).load( urls[ i ], function ( buffer ) {
@@ -43,7 +39,6 @@
 					loaded ++;
 					loaded ++;
 					const texData = scope.hdrLoader.parse( buffer );
 					const texData = scope.hdrLoader.parse( buffer );
 					if ( ! texData ) return;
 					if ( ! texData ) return;
-
 					if ( texData.data !== undefined ) {
 					if ( texData.data !== undefined ) {
 
 
 						const dataTexture = new THREE.DataTexture( texData.data, texData.width, texData.height );
 						const dataTexture = new THREE.DataTexture( texData.data, texData.width, texData.height );
@@ -77,7 +72,6 @@
 			return texture;
 			return texture;
 
 
 		}
 		}
-
 		setDataType( value ) {
 		setDataType( value ) {
 
 
 			this.type = value;
 			this.type = value;

+ 3 - 7
examples/js/loaders/KMZLoader.js

@@ -7,7 +7,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -41,7 +40,6 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			function findFile( url ) {
 			function findFile( url ) {
@@ -62,7 +60,6 @@
 			manager.setURLModifier( function ( url ) {
 			manager.setURLModifier( function ( url ) {
 
 
 				const image = findFile( url );
 				const image = findFile( url );
-
 				if ( image ) {
 				if ( image ) {
 
 
 					console.log( 'Loading', url );
 					console.log( 'Loading', url );
@@ -75,7 +72,9 @@
 
 
 				return url;
 				return url;
 
 
-			} ); //
+			} );
+
+			//
 
 
 			const zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef
 			const zip = fflate.unzipSync( new Uint8Array( data ) ); // eslint-disable-line no-undef
 
 
@@ -84,7 +83,6 @@
 				const xml = new DOMParser().parseFromString( fflate.strFromU8( zip[ 'doc.kml' ] ), 'application/xml' ); // eslint-disable-line no-undef
 				const xml = new DOMParser().parseFromString( fflate.strFromU8( zip[ 'doc.kml' ] ), 'application/xml' ); // eslint-disable-line no-undef
 
 
 				const model = xml.querySelector( 'Placemark Model Link href' );
 				const model = xml.querySelector( 'Placemark Model Link href' );
-
 				if ( model ) {
 				if ( model ) {
 
 
 					const loader = new THREE.ColladaLoader( manager );
 					const loader = new THREE.ColladaLoader( manager );
@@ -95,11 +93,9 @@
 			} else {
 			} else {
 
 
 				console.warn( 'KMZLoader: Missing doc.kml file.' );
 				console.warn( 'KMZLoader: Missing doc.kml file.' );
-
 				for ( const path in zip ) {
 				for ( const path in zip ) {
 
 
 					const extension = path.split( '.' ).pop().toLowerCase();
 					const extension = path.split( '.' ).pop().toLowerCase();
-
 					if ( extension === 'dae' ) {
 					if ( extension === 'dae' ) {
 
 
 						const loader = new THREE.ColladaLoader( manager );
 						const loader = new THREE.ColladaLoader( manager );

+ 12 - 30
examples/js/loaders/KTXLoader.js

@@ -14,7 +14,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		parse( buffer, loadMipmaps ) {
 		parse( buffer, loadMipmaps ) {
 
 
 			const ktx = new KhronosTextureContainer( buffer, 1 );
 			const ktx = new KhronosTextureContainer( buffer, 1 );
@@ -30,10 +29,8 @@
 		}
 		}
 
 
 	}
 	}
-
 	const HEADER_LEN = 12 + 13 * 4; // identifier + header elements (not including key value meta-data pairs)
 	const HEADER_LEN = 12 + 13 * 4; // identifier + header elements (not including key value meta-data pairs)
 	// load types
 	// load types
-
 	const COMPRESSED_2D = 0; // uses a gl.compressedTexImage2D()
 	const COMPRESSED_2D = 0; // uses a gl.compressedTexImage2D()
 	//const COMPRESSED_3D = 1; // uses a gl.compressedTexImage3D()
 	//const COMPRESSED_3D = 1; // uses a gl.compressedTexImage3D()
 	//const TEX_2D = 2; // uses a gl.texImage2D()
 	//const TEX_2D = 2; // uses a gl.texImage2D()
@@ -47,53 +44,40 @@
    * @param {boolean} threeDExpected- provision for indicating that data should be a 3D texture, not implemented
    * @param {boolean} threeDExpected- provision for indicating that data should be a 3D texture, not implemented
    * @param {boolean} textureArrayExpected- provision for indicating that data should be a texture array, not implemented
    * @param {boolean} textureArrayExpected- provision for indicating that data should be a texture array, not implemented
    */
    */
-		constructor( arrayBuffer, facesExpected
-			/*, threeDExpected, textureArrayExpected */
-		) {
+		constructor( arrayBuffer, facesExpected /*, threeDExpected, textureArrayExpected */ ) {
+
+			this.arrayBuffer = arrayBuffer;
 
 
-			this.arrayBuffer = arrayBuffer; // Test that it is a ktx formatted file, based on the first 12 bytes, character representation is:
+			// Test that it is a ktx formatted file, based on the first 12 bytes, character representation is:
 			// '´', 'K', 'T', 'X', ' ', '1', '1', 'ª', '\r', '\n', '\x1A', '\n'
 			// '´', 'K', 'T', 'X', ' ', '1', '1', 'ª', '\r', '\n', '\x1A', '\n'
 			// 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
 			// 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
-
 			const identifier = new Uint8Array( this.arrayBuffer, 0, 12 );
 			const identifier = new Uint8Array( this.arrayBuffer, 0, 12 );
-
 			if ( identifier[ 0 ] !== 0xAB || identifier[ 1 ] !== 0x4B || identifier[ 2 ] !== 0x54 || identifier[ 3 ] !== 0x58 || identifier[ 4 ] !== 0x20 || identifier[ 5 ] !== 0x31 || identifier[ 6 ] !== 0x31 || identifier[ 7 ] !== 0xBB || identifier[ 8 ] !== 0x0D || identifier[ 9 ] !== 0x0A || identifier[ 10 ] !== 0x1A || identifier[ 11 ] !== 0x0A ) {
 			if ( identifier[ 0 ] !== 0xAB || identifier[ 1 ] !== 0x4B || identifier[ 2 ] !== 0x54 || identifier[ 3 ] !== 0x58 || identifier[ 4 ] !== 0x20 || identifier[ 5 ] !== 0x31 || identifier[ 6 ] !== 0x31 || identifier[ 7 ] !== 0xBB || identifier[ 8 ] !== 0x0D || identifier[ 9 ] !== 0x0A || identifier[ 10 ] !== 0x1A || identifier[ 11 ] !== 0x0A ) {
 
 
 				console.error( 'texture missing KTX identifier' );
 				console.error( 'texture missing KTX identifier' );
 				return;
 				return;
 
 
-			} // load the reset of the header in native 32 bit uint
-
+			}
 
 
+			// load the reset of the header in native 32 bit uint
 			const dataSize = Uint32Array.BYTES_PER_ELEMENT;
 			const dataSize = Uint32Array.BYTES_PER_ELEMENT;
 			const headerDataView = new DataView( this.arrayBuffer, 12, 13 * dataSize );
 			const headerDataView = new DataView( this.arrayBuffer, 12, 13 * dataSize );
 			const endianness = headerDataView.getUint32( 0, true );
 			const endianness = headerDataView.getUint32( 0, true );
 			const littleEndian = endianness === 0x04030201;
 			const littleEndian = endianness === 0x04030201;
 			this.glType = headerDataView.getUint32( 1 * dataSize, littleEndian ); // must be 0 for compressed textures
 			this.glType = headerDataView.getUint32( 1 * dataSize, littleEndian ); // must be 0 for compressed textures
-
 			this.glTypeSize = headerDataView.getUint32( 2 * dataSize, littleEndian ); // must be 1 for compressed textures
 			this.glTypeSize = headerDataView.getUint32( 2 * dataSize, littleEndian ); // must be 1 for compressed textures
-
 			this.glFormat = headerDataView.getUint32( 3 * dataSize, littleEndian ); // must be 0 for compressed textures
 			this.glFormat = headerDataView.getUint32( 3 * dataSize, littleEndian ); // must be 0 for compressed textures
-
 			this.glInternalFormat = headerDataView.getUint32( 4 * dataSize, littleEndian ); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
 			this.glInternalFormat = headerDataView.getUint32( 4 * dataSize, littleEndian ); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
-
 			this.glBaseInternalFormat = headerDataView.getUint32( 5 * dataSize, littleEndian ); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
 			this.glBaseInternalFormat = headerDataView.getUint32( 5 * dataSize, littleEndian ); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
-
 			this.pixelWidth = headerDataView.getUint32( 6 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
 			this.pixelWidth = headerDataView.getUint32( 6 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
-
 			this.pixelHeight = headerDataView.getUint32( 7 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
 			this.pixelHeight = headerDataView.getUint32( 7 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
-
 			this.pixelDepth = headerDataView.getUint32( 8 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
 			this.pixelDepth = headerDataView.getUint32( 8 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
-
 			this.numberOfArrayElements = headerDataView.getUint32( 9 * dataSize, littleEndian ); // used for texture arrays
 			this.numberOfArrayElements = headerDataView.getUint32( 9 * dataSize, littleEndian ); // used for texture arrays
-
 			this.numberOfFaces = headerDataView.getUint32( 10 * dataSize, littleEndian ); // used for cubemap textures, should either be 1 or 6
 			this.numberOfFaces = headerDataView.getUint32( 10 * dataSize, littleEndian ); // used for cubemap textures, should either be 1 or 6
-
 			this.numberOfMipmapLevels = headerDataView.getUint32( 11 * dataSize, littleEndian ); // number of levels; disregard possibility of 0 for compressed textures
 			this.numberOfMipmapLevels = headerDataView.getUint32( 11 * dataSize, littleEndian ); // number of levels; disregard possibility of 0 for compressed textures
-
 			this.bytesOfKeyValueData = headerDataView.getUint32( 12 * dataSize, littleEndian ); // the amount of space after the header for meta-data
 			this.bytesOfKeyValueData = headerDataView.getUint32( 12 * dataSize, littleEndian ); // the amount of space after the header for meta-data
-			// Make sure we have a compressed type.  Not only reduces work, but probably better to let dev know they are not compressing.
 
 
+			// Make sure we have a compressed type.  Not only reduces work, but probably better to let dev know they are not compressing.
 			if ( this.glType !== 0 ) {
 			if ( this.glType !== 0 ) {
 
 
 				console.warn( 'only compressed formats currently supported' );
 				console.warn( 'only compressed formats currently supported' );
@@ -125,27 +109,25 @@
 				console.warn( 'number of faces expected' + facesExpected + ', but found ' + this.numberOfFaces );
 				console.warn( 'number of faces expected' + facesExpected + ', but found ' + this.numberOfFaces );
 				return;
 				return;
 
 
-			} // we now have a completely validated file, so could use existence of loadType as success
-			// would need to make this more elaborate & adjust checks above to support more than one load type
-
+			}
 
 
+			// we now have a completely validated file, so could use existence of loadType as success
+			// would need to make this more elaborate & adjust checks above to support more than one load type
 			this.loadType = COMPRESSED_2D;
 			this.loadType = COMPRESSED_2D;
 
 
 		}
 		}
-
 		mipmaps( loadMipmaps ) {
 		mipmaps( loadMipmaps ) {
 
 
-			const mipmaps = []; // initialize width & height for level 1
+			const mipmaps = [];
 
 
+			// initialize width & height for level 1
 			let dataOffset = HEADER_LEN + this.bytesOfKeyValueData;
 			let dataOffset = HEADER_LEN + this.bytesOfKeyValueData;
 			let width = this.pixelWidth;
 			let width = this.pixelWidth;
 			let height = this.pixelHeight;
 			let height = this.pixelHeight;
 			const mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1;
 			const mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1;
-
 			for ( let level = 0; level < mipmapCount; level ++ ) {
 			for ( let level = 0; level < mipmapCount; level ++ ) {
 
 
 				const imageSize = new Int32Array( this.arrayBuffer, dataOffset, 1 )[ 0 ]; // size per face, since not supporting array cubemaps
 				const imageSize = new Int32Array( this.arrayBuffer, dataOffset, 1 )[ 0 ]; // size per face, since not supporting array cubemaps
-
 				dataOffset += 4; // size of the image + 4 for the imageSize field
 				dataOffset += 4; // size of the image + 4 for the imageSize field
 
 
 				for ( let face = 0; face < this.numberOfFaces; face ++ ) {
 				for ( let face = 0; face < this.numberOfFaces; face ++ ) {

文件差異過大導致無法顯示
+ 108 - 171
examples/js/loaders/LDrawLoader.js


+ 7 - 11
examples/js/loaders/LUT3dlLoader.js

@@ -33,17 +33,16 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( str ) {
 		parse( str ) {
 
 
 			// remove empty lines and comment lints
 			// remove empty lines and comment lints
 			str = str.replace( /^#.*?(\n|\r)/gm, '' ).replace( /^\s*?(\n|\r)/gm, '' ).trim();
 			str = str.replace( /^#.*?(\n|\r)/gm, '' ).replace( /^\s*?(\n|\r)/gm, '' ).trim();
-			const lines = str.split( /[\n\r]+/g ); // first line is the positions on the grid that are provided by the LUT
+			const lines = str.split( /[\n\r]+/g );
 
 
+			// first line is the positions on the grid that are provided by the LUT
 			const gridLines = lines[ 0 ].trim().split( /\s+/g ).map( e => parseFloat( e ) );
 			const gridLines = lines[ 0 ].trim().split( /\s+/g ).map( e => parseFloat( e ) );
 			const gridStep = gridLines[ 1 ] - gridLines[ 0 ];
 			const gridStep = gridLines[ 1 ] - gridLines[ 0 ];
 			const size = gridLines.length;
 			const size = gridLines.length;
-
 			for ( let i = 1, l = gridLines.length; i < l; i ++ ) {
 			for ( let i = 1, l = gridLines.length; i < l; i ++ ) {
 
 
 				if ( gridStep !== gridLines[ i ] - gridLines[ i - 1 ] ) {
 				if ( gridStep !== gridLines[ i ] - gridLines[ i - 1 ] ) {
@@ -57,7 +56,6 @@
 			const dataArray = new Array( size * size * size * 4 );
 			const dataArray = new Array( size * size * size * 4 );
 			let index = 0;
 			let index = 0;
 			let maxOutputValue = 0.0;
 			let maxOutputValue = 0.0;
-
 			for ( let i = 1, l = lines.length; i < l; i ++ ) {
 			for ( let i = 1, l = lines.length; i < l; i ++ ) {
 
 
 				const line = lines[ i ].trim();
 				const line = lines[ i ].trim();
@@ -68,8 +66,9 @@
 				maxOutputValue = Math.max( maxOutputValue, r, g, b );
 				maxOutputValue = Math.max( maxOutputValue, r, g, b );
 				const bLayer = index % size;
 				const bLayer = index % size;
 				const gLayer = Math.floor( index / size ) % size;
 				const gLayer = Math.floor( index / size ) % size;
-				const rLayer = Math.floor( index / ( size * size ) ) % size; // b grows first, then g, then r
+				const rLayer = Math.floor( index / ( size * size ) ) % size;
 
 
+				// b grows first, then g, then r
 				const pixelIndex = bLayer * size * size + gLayer * size + rLayer;
 				const pixelIndex = bLayer * size * size + gLayer * size + rLayer;
 				dataArray[ 4 * pixelIndex + 0 ] = r;
 				dataArray[ 4 * pixelIndex + 0 ] = r;
 				dataArray[ 4 * pixelIndex + 1 ] = g;
 				dataArray[ 4 * pixelIndex + 1 ] = g;
@@ -77,22 +76,19 @@
 				dataArray[ 4 * pixelIndex + 3 ] = 1.0;
 				dataArray[ 4 * pixelIndex + 3 ] = 1.0;
 				index += 1;
 				index += 1;
 
 
-			} // Find the apparent bit depth of the stored RGB values and map the
-			// values to [ 0, 255 ].
-
+			}
 
 
+			// Find the apparent bit depth of the stored RGB values and map the
+			// values to [ 0, 255 ].
 			const bits = Math.ceil( Math.log2( maxOutputValue ) );
 			const bits = Math.ceil( Math.log2( maxOutputValue ) );
 			const maxBitValue = Math.pow( 2.0, bits );
 			const maxBitValue = Math.pow( 2.0, bits );
-
 			for ( let i = 0, l = dataArray.length; i < l; i += 4 ) {
 			for ( let i = 0, l = dataArray.length; i < l; i += 4 ) {
 
 
 				const r = dataArray[ i + 0 ];
 				const r = dataArray[ i + 0 ];
 				const g = dataArray[ i + 1 ];
 				const g = dataArray[ i + 1 ];
 				const b = dataArray[ i + 2 ];
 				const b = dataArray[ i + 2 ];
 				dataArray[ i + 0 ] = 255 * r / maxBitValue; // r
 				dataArray[ i + 0 ] = 255 * r / maxBitValue; // r
-
 				dataArray[ i + 1 ] = 255 * g / maxBitValue; // g
 				dataArray[ i + 1 ] = 255 * g / maxBitValue; // g
-
 				dataArray[ i + 2 ] = 255 * b / maxBitValue; // b
 				dataArray[ i + 2 ] = 255 * b / maxBitValue; // b
 
 
 			}
 			}

+ 0 - 8
examples/js/loaders/LUTCubeLoader.js

@@ -33,7 +33,6 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( str ) {
 		parse( str ) {
 
 
 			// Remove empty lines and comments
 			// Remove empty lines and comments
@@ -45,18 +44,15 @@
 			const lines = str.split( /[\n\r]+/g );
 			const lines = str.split( /[\n\r]+/g );
 			let data = null;
 			let data = null;
 			let currIndex = 0;
 			let currIndex = 0;
-
 			for ( let i = 0, l = lines.length; i < l; i ++ ) {
 			for ( let i = 0, l = lines.length; i < l; i ++ ) {
 
 
 				const line = lines[ i ].trim();
 				const line = lines[ i ].trim();
 				const split = line.split( /\s/g );
 				const split = line.split( /\s/g );
-
 				switch ( split[ 0 ] ) {
 				switch ( split[ 0 ] ) {
 
 
 					case 'TITLE':
 					case 'TITLE':
 						title = line.substring( 7, line.length - 1 );
 						title = line.substring( 7, line.length - 1 );
 						break;
 						break;
-
 					case 'LUT_3D_SIZE':
 					case 'LUT_3D_SIZE':
 						// TODO: A .CUBE LUT file specifies floating point values and could be represented with
 						// TODO: A .CUBE LUT file specifies floating point values and could be represented with
 						// more precision than can be captured with Uint8Array.
 						// more precision than can be captured with Uint8Array.
@@ -64,24 +60,20 @@
 						size = parseFloat( sizeToken );
 						size = parseFloat( sizeToken );
 						data = new Uint8Array( size * size * size * 4 );
 						data = new Uint8Array( size * size * size * 4 );
 						break;
 						break;
-
 					case 'DOMAIN_MIN':
 					case 'DOMAIN_MIN':
 						domainMin.x = parseFloat( split[ 1 ] );
 						domainMin.x = parseFloat( split[ 1 ] );
 						domainMin.y = parseFloat( split[ 2 ] );
 						domainMin.y = parseFloat( split[ 2 ] );
 						domainMin.z = parseFloat( split[ 3 ] );
 						domainMin.z = parseFloat( split[ 3 ] );
 						break;
 						break;
-
 					case 'DOMAIN_MAX':
 					case 'DOMAIN_MAX':
 						domainMax.x = parseFloat( split[ 1 ] );
 						domainMax.x = parseFloat( split[ 1 ] );
 						domainMax.y = parseFloat( split[ 2 ] );
 						domainMax.y = parseFloat( split[ 2 ] );
 						domainMax.z = parseFloat( split[ 3 ] );
 						domainMax.z = parseFloat( split[ 3 ] );
 						break;
 						break;
-
 					default:
 					default:
 						const r = parseFloat( split[ 0 ] );
 						const r = parseFloat( split[ 0 ] );
 						const g = parseFloat( split[ 1 ] );
 						const g = parseFloat( split[ 1 ] );
 						const b = parseFloat( split[ 2 ] );
 						const b = parseFloat( split[ 2 ] );
-
 						if ( r > 1.0 || r < 0.0 || g > 1.0 || g < 0.0 || b > 1.0 || b < 0.0 ) {
 						if ( r > 1.0 || r < 0.0 || g > 1.0 || g < 0.0 || b > 1.0 || b < 0.0 ) {
 
 
 							throw new Error( 'LUTCubeLoader : Non normalized values not supported.' );
 							throw new Error( 'LUTCubeLoader : Non normalized values not supported.' );

+ 59 - 124
examples/js/loaders/LWOLoader.js

@@ -12,9 +12,7 @@
  *  https://static.lightwave3d.com/sdk/2019/html/filefmts/lwo2.html
  *  https://static.lightwave3d.com/sdk/2019/html/filefmts/lwo2.html
  *
  *
  **/
  **/
-
 	let _lwoTree;
 	let _lwoTree;
-
 	class LWOLoader extends THREE.Loader {
 	class LWOLoader extends THREE.Loader {
 
 
 		constructor( manager, parameters = {} ) {
 		constructor( manager, parameters = {} ) {
@@ -23,12 +21,12 @@
 			this.resourcePath = parameters.resourcePath !== undefined ? parameters.resourcePath : '';
 			this.resourcePath = parameters.resourcePath !== undefined ? parameters.resourcePath : '';
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
-			const path = scope.path === '' ? extractParentUrl( url, 'Objects' ) : scope.path; // give the mesh a default name based on the filename
+			const path = scope.path === '' ? extractParentUrl( url, 'Objects' ) : scope.path;
 
 
+			// give the mesh a default name based on the filename
 			const modelName = url.split( path ).pop().split( '.' )[ 0 ];
 			const modelName = url.split( path ).pop().split( '.' )[ 0 ];
 			const loader = new THREE.FileLoader( this.manager );
 			const loader = new THREE.FileLoader( this.manager );
 			loader.setPath( scope.path );
 			loader.setPath( scope.path );
@@ -36,6 +34,7 @@
 			loader.load( url, function ( buffer ) {
 			loader.load( url, function ( buffer ) {
 
 
 				// console.time( 'Total parsing: ' );
 				// console.time( 'Total parsing: ' );
+
 				try {
 				try {
 
 
 					onLoad( scope.parse( buffer, path, modelName ) );
 					onLoad( scope.parse( buffer, path, modelName ) );
@@ -54,24 +53,27 @@
 
 
 					scope.manager.itemError( url );
 					scope.manager.itemError( url );
 
 
-				} // console.timeEnd( 'Total parsing: ' );
+				}
+
+				// console.timeEnd( 'Total parsing: ' );
 
 
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( iffBuffer, path, modelName ) {
 		parse( iffBuffer, path, modelName ) {
 
 
-			_lwoTree = new THREE.IFFParser().parse( iffBuffer ); // console.log( 'lwoTree', lwoTree );
+			_lwoTree = new THREE.IFFParser().parse( iffBuffer );
+
+			// console.log( 'lwoTree', lwoTree );
 
 
 			const textureLoader = new THREE.TextureLoader( this.manager ).setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin );
 			const textureLoader = new THREE.TextureLoader( this.manager ).setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin );
 			return new LWOTreeParser( textureLoader ).parse( modelName );
 			return new LWOTreeParser( textureLoader ).parse( modelName );
 
 
 		}
 		}
 
 
-	} // Parse the lwoTree object
-
+	}
 
 
+	// Parse the lwoTree object
 	class LWOTreeParser {
 	class LWOTreeParser {
 
 
 		constructor( textureLoader ) {
 		constructor( textureLoader ) {
@@ -79,7 +81,6 @@
 			this.textureLoader = textureLoader;
 			this.textureLoader = textureLoader;
 
 
 		}
 		}
-
 		parse( modelName ) {
 		parse( modelName ) {
 
 
 			this.materials = new MaterialParser( this.textureLoader ).parse();
 			this.materials = new MaterialParser( this.textureLoader ).parse();
@@ -91,16 +92,15 @@
 			};
 			};
 
 
 		}
 		}
-
 		parseLayers() {
 		parseLayers() {
 
 
 			// array of all meshes for building hierarchy
 			// array of all meshes for building hierarchy
-			const meshes = []; // final array containing meshes with scene graph hierarchy set up
+			const meshes = [];
 
 
+			// final array containing meshes with scene graph hierarchy set up
 			const finalMeshes = [];
 			const finalMeshes = [];
 			const geometryParser = new GeometryParser();
 			const geometryParser = new GeometryParser();
 			const scope = this;
 			const scope = this;
-
 			_lwoTree.layers.forEach( function ( layer ) {
 			_lwoTree.layers.forEach( function ( layer ) {
 
 
 				const geometry = geometryParser.parse( layer.geometry, layer );
 				const geometry = geometryParser.parse( layer.geometry, layer );
@@ -109,12 +109,10 @@
 				if ( layer.parent === - 1 ) finalMeshes.push( mesh ); else meshes[ layer.parent ].add( mesh );
 				if ( layer.parent === - 1 ) finalMeshes.push( mesh ); else meshes[ layer.parent ].add( mesh );
 
 
 			} );
 			} );
-
 			this.applyPivots( finalMeshes );
 			this.applyPivots( finalMeshes );
 			return finalMeshes;
 			return finalMeshes;
 
 
 		}
 		}
-
 		parseMesh( geometry, layer ) {
 		parseMesh( geometry, layer ) {
 
 
 			let mesh;
 			let mesh;
@@ -125,9 +123,9 @@
 			mesh.userData.pivot = layer.pivot;
 			mesh.userData.pivot = layer.pivot;
 			return mesh;
 			return mesh;
 
 
-		} // TODO: may need to be reversed in z to convert LWO to three.js coordinates
-
+		}
 
 
+		// TODO: may need to be reversed in z to convert LWO to three.js coordinates
 		applyPivots( meshes ) {
 		applyPivots( meshes ) {
 
 
 			meshes.forEach( function ( mesh ) {
 			meshes.forEach( function ( mesh ) {
@@ -138,7 +136,6 @@
 					child.position.x += pivot[ 0 ];
 					child.position.x += pivot[ 0 ];
 					child.position.y += pivot[ 1 ];
 					child.position.y += pivot[ 1 ];
 					child.position.z += pivot[ 2 ];
 					child.position.z += pivot[ 2 ];
-
 					if ( child.parent ) {
 					if ( child.parent ) {
 
 
 						const parentPivot = child.parent.userData.pivot;
 						const parentPivot = child.parent.userData.pivot;
@@ -153,7 +150,6 @@
 			} );
 			} );
 
 
 		}
 		}
-
 		getMaterials( namesArray, type ) {
 		getMaterials( namesArray, type ) {
 
 
 			const materials = [];
 			const materials = [];
@@ -162,8 +158,9 @@
 
 
 				materials[ i ] = scope.getMaterialByName( name );
 				materials[ i ] = scope.getMaterialByName( name );
 
 
-			} ); // convert materials to line or point mats if required
+			} );
 
 
+			// convert materials to line or point mats if required
 			if ( type === 'points' || type === 'lines' ) {
 			if ( type === 'points' || type === 'lines' ) {
 
 
 				materials.forEach( function ( mat, i ) {
 				materials.forEach( function ( mat, i ) {
@@ -171,7 +168,6 @@
 					const spec = {
 					const spec = {
 						color: mat.color
 						color: mat.color
 					};
 					};
-
 					if ( type === 'points' ) {
 					if ( type === 'points' ) {
 
 
 						spec.size = 0.1;
 						spec.size = 0.1;
@@ -186,15 +182,14 @@
 
 
 				} );
 				} );
 
 
-			} // if there is only one material, return that directly instead of array
-
+			}
 
 
+			// if there is only one material, return that directly instead of array
 			const filtered = materials.filter( Boolean );
 			const filtered = materials.filter( Boolean );
 			if ( filtered.length === 1 ) return filtered[ 0 ];
 			if ( filtered.length === 1 ) return filtered[ 0 ];
 			return materials;
 			return materials;
 
 
 		}
 		}
-
 		getMaterialByName( name ) {
 		getMaterialByName( name ) {
 
 
 			return this.materials.filter( function ( m ) {
 			return this.materials.filter( function ( m ) {
@@ -203,13 +198,12 @@
 
 
 			} )[ 0 ];
 			} )[ 0 ];
 
 
-		} // If the material has an aoMap, duplicate UVs
-
+		}
 
 
+		// If the material has an aoMap, duplicate UVs
 		duplicateUVs( geometry, materials ) {
 		duplicateUVs( geometry, materials ) {
 
 
 			let duplicateUVs = false;
 			let duplicateUVs = false;
-
 			if ( ! Array.isArray( materials ) ) {
 			if ( ! Array.isArray( materials ) ) {
 
 
 				if ( materials.aoMap ) duplicateUVs = true;
 				if ( materials.aoMap ) duplicateUVs = true;
@@ -230,7 +224,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	class MaterialParser {
 	class MaterialParser {
 
 
 		constructor( textureLoader ) {
 		constructor( textureLoader ) {
@@ -238,12 +231,10 @@
 			this.textureLoader = textureLoader;
 			this.textureLoader = textureLoader;
 
 
 		}
 		}
-
 		parse() {
 		parse() {
 
 
 			const materials = [];
 			const materials = [];
 			this.textures = {};
 			this.textures = {};
-
 			for ( const name in _lwoTree.materials ) {
 			for ( const name in _lwoTree.materials ) {
 
 
 				if ( _lwoTree.format === 'LWO3' ) {
 				if ( _lwoTree.format === 'LWO3' ) {
@@ -261,7 +252,6 @@
 			return materials;
 			return materials;
 
 
 		}
 		}
-
 		parseMaterial( materialData, name, textures ) {
 		parseMaterial( materialData, name, textures ) {
 
 
 			let params = {
 			let params = {
@@ -282,10 +272,7 @@
 			return new materialType( params );
 			return new materialType( params );
 
 
 		}
 		}
-
-		parseMaterialLwo2( materialData, name
-			/*, textures*/
-		) {
+		parseMaterialLwo2( materialData, name /*, textures*/ ) {
 
 
 			let params = {
 			let params = {
 				name: name,
 				name: name,
@@ -296,38 +283,33 @@
 			params = Object.assign( params, attributes );
 			params = Object.assign( params, attributes );
 			return new THREE.MeshPhongMaterial( params );
 			return new THREE.MeshPhongMaterial( params );
 
 
-		} // Note: converting from left to right handed coords by switching x -> -x in vertices, and
+		}
+
+		// Note: converting from left to right handed coords by switching x -> -x in vertices, and
 		// then switching mat THREE.FrontSide -> THREE.BackSide
 		// then switching mat THREE.FrontSide -> THREE.BackSide
 		// NB: this means that THREE.FrontSide and THREE.BackSide have been switched!
 		// NB: this means that THREE.FrontSide and THREE.BackSide have been switched!
-
-
 		getSide( attributes ) {
 		getSide( attributes ) {
 
 
 			if ( ! attributes.side ) return THREE.BackSide;
 			if ( ! attributes.side ) return THREE.BackSide;
-
 			switch ( attributes.side ) {
 			switch ( attributes.side ) {
 
 
 				case 0:
 				case 0:
 				case 1:
 				case 1:
 					return THREE.BackSide;
 					return THREE.BackSide;
-
 				case 2:
 				case 2:
 					return THREE.FrontSide;
 					return THREE.FrontSide;
-
 				case 3:
 				case 3:
 					return THREE.DoubleSide;
 					return THREE.DoubleSide;
 
 
 			}
 			}
 
 
 		}
 		}
-
 		getSmooth( attributes ) {
 		getSmooth( attributes ) {
 
 
 			if ( ! attributes.smooth ) return true;
 			if ( ! attributes.smooth ) return true;
 			return ! attributes.smooth;
 			return ! attributes.smooth;
 
 
 		}
 		}
-
 		parseConnections( connections, nodes ) {
 		parseConnections( connections, nodes ) {
 
 
 			const materialConnections = {
 			const materialConnections = {
@@ -361,7 +343,6 @@
 			return materialConnections;
 			return materialConnections;
 
 
 		}
 		}
-
 		getNodeByRefName( refName, nodes ) {
 		getNodeByRefName( refName, nodes ) {
 
 
 			for ( const name in nodes ) {
 			for ( const name in nodes ) {
@@ -371,11 +352,9 @@
 			}
 			}
 
 
 		}
 		}
-
 		parseTextureNodes( textureNodes ) {
 		parseTextureNodes( textureNodes ) {
 
 
 			const maps = {};
 			const maps = {};
-
 			for ( const name in textureNodes ) {
 			for ( const name in textureNodes ) {
 
 
 				const node = textureNodes[ name ];
 				const node = textureNodes[ name ];
@@ -384,70 +363,60 @@
 				const texture = this.loadTexture( path );
 				const texture = this.loadTexture( path );
 				if ( node.widthWrappingMode !== undefined ) texture.wrapS = this.getWrappingType( node.widthWrappingMode );
 				if ( node.widthWrappingMode !== undefined ) texture.wrapS = this.getWrappingType( node.widthWrappingMode );
 				if ( node.heightWrappingMode !== undefined ) texture.wrapT = this.getWrappingType( node.heightWrappingMode );
 				if ( node.heightWrappingMode !== undefined ) texture.wrapT = this.getWrappingType( node.heightWrappingMode );
-
 				switch ( name ) {
 				switch ( name ) {
 
 
 					case 'Color':
 					case 'Color':
 						maps.map = texture;
 						maps.map = texture;
 						break;
 						break;
-
 					case 'Roughness':
 					case 'Roughness':
 						maps.roughnessMap = texture;
 						maps.roughnessMap = texture;
 						maps.roughness = 1;
 						maps.roughness = 1;
 						break;
 						break;
-
 					case 'Specular':
 					case 'Specular':
 						maps.specularMap = texture;
 						maps.specularMap = texture;
 						maps.specular = 0xffffff;
 						maps.specular = 0xffffff;
 						break;
 						break;
-
 					case 'Luminous':
 					case 'Luminous':
 						maps.emissiveMap = texture;
 						maps.emissiveMap = texture;
 						maps.emissive = 0x808080;
 						maps.emissive = 0x808080;
 						break;
 						break;
-
 					case 'Luminous THREE.Color':
 					case 'Luminous THREE.Color':
 						maps.emissive = 0x808080;
 						maps.emissive = 0x808080;
 						break;
 						break;
-
 					case 'Metallic':
 					case 'Metallic':
 						maps.metalnessMap = texture;
 						maps.metalnessMap = texture;
 						maps.metalness = 1;
 						maps.metalness = 1;
 						break;
 						break;
-
 					case 'Transparency':
 					case 'Transparency':
 					case 'Alpha':
 					case 'Alpha':
 						maps.alphaMap = texture;
 						maps.alphaMap = texture;
 						maps.transparent = true;
 						maps.transparent = true;
 						break;
 						break;
-
 					case 'Normal':
 					case 'Normal':
 						maps.normalMap = texture;
 						maps.normalMap = texture;
 						if ( node.amplitude !== undefined ) maps.normalScale = new THREE.Vector2( node.amplitude, node.amplitude );
 						if ( node.amplitude !== undefined ) maps.normalScale = new THREE.Vector2( node.amplitude, node.amplitude );
 						break;
 						break;
-
 					case 'Bump':
 					case 'Bump':
 						maps.bumpMap = texture;
 						maps.bumpMap = texture;
 						break;
 						break;
 
 
 				}
 				}
 
 
-			} // LWO BSDF materials can have both spec and rough, but this is not valid in three
-
+			}
 
 
+			// LWO BSDF materials can have both spec and rough, but this is not valid in three
 			if ( maps.roughnessMap && maps.specularMap ) delete maps.specularMap;
 			if ( maps.roughnessMap && maps.specularMap ) delete maps.specularMap;
 			return maps;
 			return maps;
 
 
-		} // maps can also be defined on individual material attributes, parse those here
-		// This occurs on Standard (Phong) surfaces
-
+		}
 
 
+		// maps can also be defined on individual material attributes, parse those here
+		// This occurs on Standard (Phong) surfaces
 		parseAttributeImageMaps( attributes, textures, maps ) {
 		parseAttributeImageMaps( attributes, textures, maps ) {
 
 
 			for ( const name in attributes ) {
 			for ( const name in attributes ) {
 
 
 				const attribute = attributes[ name ];
 				const attribute = attributes[ name ];
-
 				if ( attribute.maps ) {
 				if ( attribute.maps ) {
 
 
 					const mapData = attribute.maps[ 0 ];
 					const mapData = attribute.maps[ 0 ];
@@ -456,47 +425,38 @@
 					const texture = this.loadTexture( path );
 					const texture = this.loadTexture( path );
 					if ( mapData.wrap !== undefined ) texture.wrapS = this.getWrappingType( mapData.wrap.w );
 					if ( mapData.wrap !== undefined ) texture.wrapS = this.getWrappingType( mapData.wrap.w );
 					if ( mapData.wrap !== undefined ) texture.wrapT = this.getWrappingType( mapData.wrap.h );
 					if ( mapData.wrap !== undefined ) texture.wrapT = this.getWrappingType( mapData.wrap.h );
-
 					switch ( name ) {
 					switch ( name ) {
 
 
 						case 'Color':
 						case 'Color':
 							maps.map = texture;
 							maps.map = texture;
 							break;
 							break;
-
 						case 'Diffuse':
 						case 'Diffuse':
 							maps.aoMap = texture;
 							maps.aoMap = texture;
 							break;
 							break;
-
 						case 'Roughness':
 						case 'Roughness':
 							maps.roughnessMap = texture;
 							maps.roughnessMap = texture;
 							maps.roughness = 1;
 							maps.roughness = 1;
 							break;
 							break;
-
 						case 'Specular':
 						case 'Specular':
 							maps.specularMap = texture;
 							maps.specularMap = texture;
 							maps.specular = 0xffffff;
 							maps.specular = 0xffffff;
 							break;
 							break;
-
 						case 'Luminosity':
 						case 'Luminosity':
 							maps.emissiveMap = texture;
 							maps.emissiveMap = texture;
 							maps.emissive = 0x808080;
 							maps.emissive = 0x808080;
 							break;
 							break;
-
 						case 'Metallic':
 						case 'Metallic':
 							maps.metalnessMap = texture;
 							maps.metalnessMap = texture;
 							maps.metalness = 1;
 							maps.metalness = 1;
 							break;
 							break;
-
 						case 'Transparency':
 						case 'Transparency':
 						case 'Alpha':
 						case 'Alpha':
 							maps.alphaMap = texture;
 							maps.alphaMap = texture;
 							maps.transparent = true;
 							maps.transparent = true;
 							break;
 							break;
-
 						case 'Normal':
 						case 'Normal':
 							maps.normalMap = texture;
 							maps.normalMap = texture;
 							break;
 							break;
-
 						case 'Bump':
 						case 'Bump':
 							maps.bumpMap = texture;
 							maps.bumpMap = texture;
 							break;
 							break;
@@ -508,17 +468,16 @@
 			}
 			}
 
 
 		}
 		}
-
 		parseAttributes( attributes, maps ) {
 		parseAttributes( attributes, maps ) {
 
 
-			const params = {}; // don't use color data if color map is present
+			const params = {};
 
 
+			// don't use color data if color map is present
 			if ( attributes.Color && ! maps.map ) {
 			if ( attributes.Color && ! maps.map ) {
 
 
 				params.color = new THREE.Color().fromArray( attributes.Color.value );
 				params.color = new THREE.Color().fromArray( attributes.Color.value );
 
 
 			} else params.color = new THREE.Color();
 			} else params.color = new THREE.Color();
-
 			if ( attributes.Transparency && attributes.Transparency.value !== 0 ) {
 			if ( attributes.Transparency && attributes.Transparency.value !== 0 ) {
 
 
 				params.opacity = 1 - attributes.Transparency.value;
 				params.opacity = 1 - attributes.Transparency.value;
@@ -533,15 +492,11 @@
 			return params;
 			return params;
 
 
 		}
 		}
-
-		parsePhysicalAttributes( params, attributes
-			/*, maps*/
-		) {
+		parsePhysicalAttributes( params, attributes /*, maps*/ ) {
 
 
 			if ( attributes.Clearcoat && attributes.Clearcoat.value > 0 ) {
 			if ( attributes.Clearcoat && attributes.Clearcoat.value > 0 ) {
 
 
 				params.clearcoat = attributes.Clearcoat.value;
 				params.clearcoat = attributes.Clearcoat.value;
-
 				if ( attributes[ 'Clearcoat Gloss' ] ) {
 				if ( attributes[ 'Clearcoat Gloss' ] ) {
 
 
 					params.clearcoatRoughness = 0.5 * ( 1 - attributes[ 'Clearcoat Gloss' ].value );
 					params.clearcoatRoughness = 0.5 * ( 1 - attributes[ 'Clearcoat Gloss' ].value );
@@ -551,13 +506,11 @@
 			}
 			}
 
 
 		}
 		}
-
 		parseStandardAttributes( params, attributes, maps ) {
 		parseStandardAttributes( params, attributes, maps ) {
 
 
 			if ( attributes.Luminous ) {
 			if ( attributes.Luminous ) {
 
 
 				params.emissiveIntensity = attributes.Luminous.value;
 				params.emissiveIntensity = attributes.Luminous.value;
-
 				if ( attributes[ 'Luminous THREE.Color' ] && ! maps.emissive ) {
 				if ( attributes[ 'Luminous THREE.Color' ] && ! maps.emissive ) {
 
 
 					params.emissive = new THREE.Color().fromArray( attributes[ 'Luminous THREE.Color' ].value );
 					params.emissive = new THREE.Color().fromArray( attributes[ 'Luminous THREE.Color' ].value );
@@ -574,12 +527,10 @@
 			if ( attributes.Metallic && ! maps.metalnessMap ) params.metalness = attributes.Metallic.value;
 			if ( attributes.Metallic && ! maps.metalnessMap ) params.metalness = attributes.Metallic.value;
 
 
 		}
 		}
-
 		parsePhongAttributes( params, attributes, maps ) {
 		parsePhongAttributes( params, attributes, maps ) {
 
 
 			if ( attributes[ 'Refraction Index' ] ) params.refractionRatio = 0.98 / attributes[ 'Refraction Index' ].value;
 			if ( attributes[ 'Refraction Index' ] ) params.refractionRatio = 0.98 / attributes[ 'Refraction Index' ].value;
 			if ( attributes.Diffuse ) params.color.multiplyScalar( attributes.Diffuse.value );
 			if ( attributes.Diffuse ) params.color.multiplyScalar( attributes.Diffuse.value );
-
 			if ( attributes.Reflection ) {
 			if ( attributes.Reflection ) {
 
 
 				params.reflectivity = attributes.Reflection.value;
 				params.reflectivity = attributes.Reflection.value;
@@ -590,7 +541,6 @@
 			if ( attributes.Luminosity ) {
 			if ( attributes.Luminosity ) {
 
 
 				params.emissiveIntensity = attributes.Luminosity.value;
 				params.emissiveIntensity = attributes.Luminosity.value;
-
 				if ( ! maps.emissiveMap && ! maps.map ) {
 				if ( ! maps.emissiveMap && ! maps.map ) {
 
 
 					params.emissive = params.color;
 					params.emissive = params.color;
@@ -601,9 +551,9 @@
 
 
 				}
 				}
 
 
-			} // parse specular if there is no roughness - we will interpret the material as 'Phong' in this case
-
+			}
 
 
+			// parse specular if there is no roughness - we will interpret the material as 'Phong' in this case
 			if ( ! attributes.Roughness && attributes.Specular && ! maps.specularMap ) {
 			if ( ! attributes.Roughness && attributes.Specular && ! maps.specularMap ) {
 
 
 				if ( attributes[ 'Color Highlight' ] ) {
 				if ( attributes[ 'Color Highlight' ] ) {
@@ -621,17 +571,16 @@
 			if ( params.specular && attributes.Glossiness ) params.shininess = 7 + Math.pow( 2, attributes.Glossiness.value * 12 + 2 );
 			if ( params.specular && attributes.Glossiness ) params.shininess = 7 + Math.pow( 2, attributes.Glossiness.value * 12 + 2 );
 
 
 		}
 		}
-
 		parseEnvMap( connections, maps, attributes ) {
 		parseEnvMap( connections, maps, attributes ) {
 
 
 			if ( connections.envMap ) {
 			if ( connections.envMap ) {
 
 
 				const envMap = this.loadTexture( connections.envMap );
 				const envMap = this.loadTexture( connections.envMap );
-
 				if ( attributes.transparent && attributes.opacity < 0.999 ) {
 				if ( attributes.transparent && attributes.opacity < 0.999 ) {
 
 
-					envMap.mapping = THREE.EquirectangularRefractionMapping; // Reflectivity and refraction mapping don't work well together in Phong materials
+					envMap.mapping = THREE.EquirectangularRefractionMapping;
 
 
+					// Reflectivity and refraction mapping don't work well together in Phong materials
 					if ( attributes.reflectivity !== undefined ) {
 					if ( attributes.reflectivity !== undefined ) {
 
 
 						delete attributes.reflectivity;
 						delete attributes.reflectivity;
@@ -648,29 +597,25 @@
 					attributes.opacity = 1; // transparency fades out refraction, forcing opacity to 1 ensures a closer visual match to the material in Lightwave.
 					attributes.opacity = 1; // transparency fades out refraction, forcing opacity to 1 ensures a closer visual match to the material in Lightwave.
 
 
 				} else envMap.mapping = THREE.EquirectangularReflectionMapping;
 				} else envMap.mapping = THREE.EquirectangularReflectionMapping;
-
 				maps.envMap = envMap;
 				maps.envMap = envMap;
 
 
 			}
 			}
 
 
-		} // get texture defined at top level by its index
-
+		}
 
 
+		// get texture defined at top level by its index
 		getTexturePathByIndex( index ) {
 		getTexturePathByIndex( index ) {
 
 
 			let fileName = '';
 			let fileName = '';
 			if ( ! _lwoTree.textures ) return fileName;
 			if ( ! _lwoTree.textures ) return fileName;
-
 			_lwoTree.textures.forEach( function ( texture ) {
 			_lwoTree.textures.forEach( function ( texture ) {
 
 
 				if ( texture.index === index ) fileName = texture.fileName;
 				if ( texture.index === index ) fileName = texture.fileName;
 
 
 			} );
 			} );
-
 			return fileName;
 			return fileName;
 
 
 		}
 		}
-
 		loadTexture( path ) {
 		loadTexture( path ) {
 
 
 			if ( ! path ) return null;
 			if ( ! path ) return null;
@@ -681,9 +626,9 @@
 			} );
 			} );
 			return texture;
 			return texture;
 
 
-		} // 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge
-
+		}
 
 
+		// 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge
 		getWrappingType( num ) {
 		getWrappingType( num ) {
 
 
 			switch ( num ) {
 			switch ( num ) {
@@ -691,20 +636,16 @@
 				case 0:
 				case 0:
 					console.warn( 'LWOLoader: "Reset" texture wrapping type is not supported in three.js' );
 					console.warn( 'LWOLoader: "Reset" texture wrapping type is not supported in three.js' );
 					return THREE.ClampToEdgeWrapping;
 					return THREE.ClampToEdgeWrapping;
-
 				case 1:
 				case 1:
 					return THREE.RepeatWrapping;
 					return THREE.RepeatWrapping;
-
 				case 2:
 				case 2:
 					return THREE.MirroredRepeatWrapping;
 					return THREE.MirroredRepeatWrapping;
-
 				case 3:
 				case 3:
 					return THREE.ClampToEdgeWrapping;
 					return THREE.ClampToEdgeWrapping;
 
 
 			}
 			}
 
 
 		}
 		}
-
 		getMaterialType( nodeData ) {
 		getMaterialType( nodeData ) {
 
 
 			if ( nodeData.Clearcoat && nodeData.Clearcoat.value > 0 ) return THREE.MeshPhysicalMaterial;
 			if ( nodeData.Clearcoat && nodeData.Clearcoat.value > 0 ) return THREE.MeshPhysicalMaterial;
@@ -714,7 +655,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	class GeometryParser {
 	class GeometryParser {
 
 
 		parse( geoData, layer ) {
 		parse( geoData, layer ) {
@@ -726,17 +666,20 @@
 			this.parseGroups( geometry, geoData );
 			this.parseGroups( geometry, geoData );
 			geometry.computeVertexNormals();
 			geometry.computeVertexNormals();
 			this.parseUVs( geometry, layer, indices );
 			this.parseUVs( geometry, layer, indices );
-			this.parseMorphTargets( geometry, layer, indices ); // TODO: z may need to be reversed to account for coordinate system change
+			this.parseMorphTargets( geometry, layer, indices );
 
 
-			geometry.translate( - layer.pivot[ 0 ], - layer.pivot[ 1 ], - layer.pivot[ 2 ] ); // let userData = geometry.userData;
+			// TODO: z may need to be reversed to account for coordinate system change
+			geometry.translate( - layer.pivot[ 0 ], - layer.pivot[ 1 ], - layer.pivot[ 2 ] );
+
+			// let userData = geometry.userData;
 			// geometry = geometry.toNonIndexed()
 			// geometry = geometry.toNonIndexed()
 			// geometry.userData = userData;
 			// geometry.userData = userData;
 
 
 			return geometry;
 			return geometry;
 
 
-		} // split quads into tris
-
+		}
 
 
+		// split quads into tris
 		splitIndices( indices, polygonDimensions ) {
 		splitIndices( indices, polygonDimensions ) {
 
 
 			const remappedIndices = [];
 			const remappedIndices = [];
@@ -768,9 +711,9 @@
 			} );
 			} );
 			return remappedIndices;
 			return remappedIndices;
 
 
-		} // NOTE: currently ignoring poly indices and assuming that they are intelligently ordered
-
+		}
 
 
+		// NOTE: currently ignoring poly indices and assuming that they are intelligently ordered
 		parseGroups( geometry, geoData ) {
 		parseGroups( geometry, geoData ) {
 
 
 			const tags = _lwoTree.tags;
 			const tags = _lwoTree.tags;
@@ -780,24 +723,20 @@
 			if ( geoData.type === 'points' ) elemSize = 1;
 			if ( geoData.type === 'points' ) elemSize = 1;
 			const remappedIndices = this.splitMaterialIndices( geoData.polygonDimensions, geoData.materialIndices );
 			const remappedIndices = this.splitMaterialIndices( geoData.polygonDimensions, geoData.materialIndices );
 			let indexNum = 0; // create new indices in numerical order
 			let indexNum = 0; // create new indices in numerical order
-
 			const indexPairs = {}; // original indices mapped to numerical indices
 			const indexPairs = {}; // original indices mapped to numerical indices
 
 
 			let prevMaterialIndex;
 			let prevMaterialIndex;
 			let materialIndex;
 			let materialIndex;
 			let prevStart = 0;
 			let prevStart = 0;
 			let currentCount = 0;
 			let currentCount = 0;
-
 			for ( let i = 0; i < remappedIndices.length; i += 2 ) {
 			for ( let i = 0; i < remappedIndices.length; i += 2 ) {
 
 
 				materialIndex = remappedIndices[ i + 1 ];
 				materialIndex = remappedIndices[ i + 1 ];
 				if ( i === 0 ) matNames[ indexNum ] = tags[ materialIndex ];
 				if ( i === 0 ) matNames[ indexNum ] = tags[ materialIndex ];
 				if ( prevMaterialIndex === undefined ) prevMaterialIndex = materialIndex;
 				if ( prevMaterialIndex === undefined ) prevMaterialIndex = materialIndex;
-
 				if ( materialIndex !== prevMaterialIndex ) {
 				if ( materialIndex !== prevMaterialIndex ) {
 
 
 					let currentIndex;
 					let currentIndex;
-
 					if ( indexPairs[ tags[ prevMaterialIndex ] ] ) {
 					if ( indexPairs[ tags[ prevMaterialIndex ] ] ) {
 
 
 						currentIndex = indexPairs[ tags[ prevMaterialIndex ] ];
 						currentIndex = indexPairs[ tags[ prevMaterialIndex ] ];
@@ -820,13 +759,12 @@
 
 
 				currentCount += elemSize;
 				currentCount += elemSize;
 
 
-			} // the loop above doesn't add the last group, do that here.
-
+			}
 
 
+			// the loop above doesn't add the last group, do that here.
 			if ( geometry.groups.length > 0 ) {
 			if ( geometry.groups.length > 0 ) {
 
 
 				let currentIndex;
 				let currentIndex;
-
 				if ( indexPairs[ tags[ materialIndex ] ] ) {
 				if ( indexPairs[ tags[ materialIndex ] ] ) {
 
 
 					currentIndex = indexPairs[ tags[ materialIndex ] ];
 					currentIndex = indexPairs[ tags[ materialIndex ] ];
@@ -841,13 +779,12 @@
 
 
 				geometry.addGroup( prevStart, currentCount, currentIndex );
 				geometry.addGroup( prevStart, currentCount, currentIndex );
 
 
-			} // Mat names from TAGS chunk, used to build up an array of materials for this geometry
-
+			}
 
 
+			// Mat names from TAGS chunk, used to build up an array of materials for this geometry
 			geometry.userData.matNames = matNames;
 			geometry.userData.matNames = matNames;
 
 
 		}
 		}
-
 		splitMaterialIndices( polygonDimensions, indices ) {
 		splitMaterialIndices( polygonDimensions, indices ) {
 
 
 			const remappedIndices = [];
 			const remappedIndices = [];
@@ -875,7 +812,9 @@
 			} );
 			} );
 			return remappedIndices;
 			return remappedIndices;
 
 
-		} // UV maps:
+		}
+
+		// UV maps:
 		// 1: are defined via index into an array of points, not into a geometry
 		// 1: are defined via index into an array of points, not into a geometry
 		// - the geometry is also defined by an index into this array, but the indexes may not match
 		// - the geometry is also defined by an index into this array, but the indexes may not match
 		// 2: there can be any number of UV maps for a single geometry. Here these are combined,
 		// 2: there can be any number of UV maps for a single geometry. Here these are combined,
@@ -884,8 +823,6 @@
 		// 4: UV maps can be VMAP or VMAD (discontinuous, to allow for seams). In practice, most
 		// 4: UV maps can be VMAP or VMAD (discontinuous, to allow for seams). In practice, most
 		// UV maps are defined as partially VMAP and partially VMAD
 		// UV maps are defined as partially VMAP and partially VMAD
 		// VMADs are currently not supported
 		// VMADs are currently not supported
-
-
 		parseUVs( geometry, layer ) {
 		parseUVs( geometry, layer ) {
 
 
 			// start by creating a UV map set to zero for the whole geometry
 			// start by creating a UV map set to zero for the whole geometry
@@ -894,7 +831,6 @@
 				return 0;
 				return 0;
 
 
 			} );
 			} );
-
 			for ( const name in layer.uvs ) {
 			for ( const name in layer.uvs ) {
 
 
 				const uvs = layer.uvs[ name ].uvs;
 				const uvs = layer.uvs[ name ].uvs;
@@ -911,11 +847,9 @@
 			geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( remappedUVs, 2 ) );
 			geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( remappedUVs, 2 ) );
 
 
 		}
 		}
-
 		parseMorphTargets( geometry, layer ) {
 		parseMorphTargets( geometry, layer ) {
 
 
 			let num = 0;
 			let num = 0;
-
 			for ( const name in layer.morphTargets ) {
 			for ( const name in layer.morphTargets ) {
 
 
 				const remappedPoints = geometry.attributes.position.array.slice();
 				const remappedPoints = geometry.attributes.position.array.slice();
@@ -950,8 +884,9 @@
 
 
 		}
 		}
 
 
-	} // ************** UTILITY FUNCTIONS **************
+	}
 
 
+	// ************** UTILITY FUNCTIONS **************
 
 
 	function extractParentUrl( url, dir ) {
 	function extractParentUrl( url, dir ) {
 
 

+ 27 - 77
examples/js/loaders/LogLuvLoader.js

@@ -8,7 +8,6 @@
 			this.type = THREE.HalfFloatType;
 			this.type = THREE.HalfFloatType;
 
 
 		}
 		}
-
 		parse( buffer ) {
 		parse( buffer ) {
 
 
 			const ifds = UTIF.decode( buffer );
 			const ifds = UTIF.decode( buffer );
@@ -24,7 +23,6 @@
 			};
 			};
 
 
 		}
 		}
-
 		setDataType( value ) {
 		setDataType( value ) {
 
 
 			this.type = value;
 			this.type = value;
@@ -32,30 +30,26 @@
 
 
 		}
 		}
 
 
-	} // from https://github.com/photopea/UTIF.js (MIT License)
+	}
 
 
+	// from https://github.com/photopea/UTIF.js (MIT License)
 
 
 	const UTIF = {};
 	const UTIF = {};
-
 	UTIF.decode = function ( buff, prm ) {
 	UTIF.decode = function ( buff, prm ) {
 
 
 		if ( prm == null ) prm = {
 		if ( prm == null ) prm = {
 			parseMN: true,
 			parseMN: true,
 			debug: false
 			debug: false
 		}; // read MakerNote, debug
 		}; // read MakerNote, debug
-
 		var data = new Uint8Array( buff ),
 		var data = new Uint8Array( buff ),
 			offset = 0;
 			offset = 0;
-
 		var id = UTIF._binBE.readASCII( data, offset, 2 );
 		var id = UTIF._binBE.readASCII( data, offset, 2 );
-
 		offset += 2;
 		offset += 2;
 		var bin = id == 'II' ? UTIF._binLE : UTIF._binBE;
 		var bin = id == 'II' ? UTIF._binLE : UTIF._binBE;
 		bin.readUshort( data, offset );
 		bin.readUshort( data, offset );
 		offset += 2;
 		offset += 2;
 		var ifdo = bin.readUint( data, offset );
 		var ifdo = bin.readUint( data, offset );
 		var ifds = [];
 		var ifds = [];
-
 		while ( true ) {
 		while ( true ) {
 
 
 			var cnt = bin.readUshort( data, ifdo ),
 			var cnt = bin.readUshort( data, ifdo ),
@@ -68,7 +62,6 @@
 			}
 			}
 
 
 			UTIF._readIFD( bin, data, ifdo, ifds, 0, prm );
 			UTIF._readIFD( bin, data, ifdo, ifds, 0, prm );
-
 			ifdo = bin.readUint( data, ifdo + 2 + cnt * 12 );
 			ifdo = bin.readUint( data, ifdo + 2 + cnt * 12 );
 			if ( ifdo == 0 ) break;
 			if ( ifdo == 0 ) break;
 
 
@@ -82,26 +75,19 @@
 
 
 		if ( img.data ) return;
 		if ( img.data ) return;
 		var data = new Uint8Array( buff );
 		var data = new Uint8Array( buff );
-
 		var id = UTIF._binBE.readASCII( data, 0, 2 );
 		var id = UTIF._binBE.readASCII( data, 0, 2 );
-
 		if ( img[ 't256' ] == null ) return; // No width => probably not an image
 		if ( img[ 't256' ] == null ) return; // No width => probably not an image
-
 		img.isLE = id == 'II';
 		img.isLE = id == 'II';
 		img.width = img[ 't256' ][ 0 ]; //delete img["t256"];
 		img.width = img[ 't256' ][ 0 ]; //delete img["t256"];
-
 		img.height = img[ 't257' ][ 0 ]; //delete img["t257"];
 		img.height = img[ 't257' ][ 0 ]; //delete img["t257"];
 
 
 		var cmpr = img[ 't259' ] ? img[ 't259' ][ 0 ] : 1; //delete img["t259"];
 		var cmpr = img[ 't259' ] ? img[ 't259' ][ 0 ] : 1; //delete img["t259"];
-
 		var fo = img[ 't266' ] ? img[ 't266' ][ 0 ] : 1; //delete img["t266"];
 		var fo = img[ 't266' ] ? img[ 't266' ][ 0 ] : 1; //delete img["t266"];
-
 		if ( img[ 't284' ] && img[ 't284' ][ 0 ] == 2 ) console.log( 'PlanarConfiguration 2 should not be used!' );
 		if ( img[ 't284' ] && img[ 't284' ][ 0 ] == 2 ) console.log( 'PlanarConfiguration 2 should not be used!' );
 		if ( cmpr == 7 && img[ 't258' ] && img[ 't258' ].length > 3 ) img[ 't258' ] = img[ 't258' ].slice( 0, 3 );
 		if ( cmpr == 7 && img[ 't258' ] && img[ 't258' ].length > 3 ) img[ 't258' ] = img[ 't258' ].slice( 0, 3 );
 		var bipp; // bits per pixel
 		var bipp; // bits per pixel
-
-		if ( img[ 't258' ] ) bipp = Math.min( 32, img[ 't258' ][ 0 ] ) * img[ 't258' ].length; else bipp = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1; // Some .NEF files have t258==14, even though they use 16 bits per pixel
-
+		if ( img[ 't258' ] ) bipp = Math.min( 32, img[ 't258' ][ 0 ] ) * img[ 't258' ].length; else bipp = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1;
+		// Some .NEF files have t258==14, even though they use 16 bits per pixel
 		if ( cmpr == 1 && img[ 't279' ] != null && img[ 't278' ] && img[ 't262' ][ 0 ] == 32803 ) {
 		if ( cmpr == 1 && img[ 't279' ] != null && img[ 't278' ] && img[ 't262' ][ 0 ] == 32803 ) {
 
 
 			bipp = Math.round( img[ 't279' ][ 0 ] * 8 / ( img.width * img[ 't278' ][ 0 ] ) );
 			bipp = Math.round( img[ 't279' ][ 0 ] * 8 / ( img.width * img[ 't278' ][ 0 ] ) );
@@ -113,11 +99,10 @@
 		if ( soff == null ) soff = img[ 't324' ];
 		if ( soff == null ) soff = img[ 't324' ];
 		var bcnt = img[ 't279' ];
 		var bcnt = img[ 't279' ];
 		if ( cmpr == 1 && soff.length == 1 ) bcnt = [ img.height * ( bipl >>> 3 ) ];
 		if ( cmpr == 1 && soff.length == 1 ) bcnt = [ img.height * ( bipl >>> 3 ) ];
-		if ( bcnt == null ) bcnt = img[ 't325' ]; //bcnt[0] = Math.min(bcnt[0], data.length);  // Hasselblad, "RAW_HASSELBLAD_H3D39II.3FR"
-
+		if ( bcnt == null ) bcnt = img[ 't325' ];
+		//bcnt[0] = Math.min(bcnt[0], data.length);  // Hasselblad, "RAW_HASSELBLAD_H3D39II.3FR"
 		var bytes = new Uint8Array( img.height * ( bipl >>> 3 ) ),
 		var bytes = new Uint8Array( img.height * ( bipl >>> 3 ) ),
 			bilen = 0;
 			bilen = 0;
-
 		if ( img[ 't322' ] != null ) {
 		if ( img[ 't322' ] != null ) {
 
 
 			var tw = img[ 't322' ][ 0 ],
 			var tw = img[ 't322' ][ 0 ],
@@ -125,16 +110,12 @@
 			var tx = Math.floor( ( img.width + tw - 1 ) / tw );
 			var tx = Math.floor( ( img.width + tw - 1 ) / tw );
 			var ty = Math.floor( ( img.height + th - 1 ) / th );
 			var ty = Math.floor( ( img.height + th - 1 ) / th );
 			var tbuff = new Uint8Array( Math.ceil( tw * th * bipp / 8 ) | 0 );
 			var tbuff = new Uint8Array( Math.ceil( tw * th * bipp / 8 ) | 0 );
-
 			for ( var y = 0; y < ty; y ++ ) for ( var x = 0; x < tx; x ++ ) {
 			for ( var y = 0; y < ty; y ++ ) for ( var x = 0; x < tx; x ++ ) {
 
 
 				var i = y * tx + x;
 				var i = y * tx + x;
-
 				for ( var j = 0; j < tbuff.length; j ++ ) tbuff[ j ] = 0;
 				for ( var j = 0; j < tbuff.length; j ++ ) tbuff[ j ] = 0;
-
-				UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, tbuff, 0, fo ); // Might be required for 7 too. Need to check
-
-
+				UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, tbuff, 0, fo );
+				// Might be required for 7 too. Need to check
 				if ( cmpr == 6 ) bytes = tbuff; else UTIF._copyTile( tbuff, Math.ceil( tw * bipp / 8 ) | 0, th, bytes, Math.ceil( img.width * bipp / 8 ) | 0, img.height, Math.ceil( x * tw * bipp / 8 ) | 0, y * th );
 				if ( cmpr == 6 ) bytes = tbuff; else UTIF._copyTile( tbuff, Math.ceil( tw * bipp / 8 ) | 0, th, bytes, Math.ceil( img.width * bipp / 8 ) | 0, img.height, Math.ceil( x * tw * bipp / 8 ) | 0, y * th );
 
 
 			}
 			}
@@ -145,11 +126,9 @@
 
 
 			var rps = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height;
 			var rps = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height;
 			rps = Math.min( rps, img.height );
 			rps = Math.min( rps, img.height );
-
 			for ( var i = 0; i < soff.length; i ++ ) {
 			for ( var i = 0; i < soff.length; i ++ ) {
 
 
 				UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, bytes, Math.ceil( bilen / 8 ) | 0, fo );
 				UTIF.decode._decompress( img, ifds, data, soff[ i ], bcnt[ i ], cmpr, bytes, Math.ceil( bilen / 8 ) | 0, fo );
-
 				bilen += bipl * rps;
 				bilen += bipl * rps;
 
 
 			}
 			}
@@ -166,20 +145,23 @@
 
 
 		//console.log("compression", cmpr);
 		//console.log("compression", cmpr);
 		//var time = Date.now();
 		//var time = Date.now();
-		if ( cmpr == 34676 ) UTIF.decode._decodeLogLuv32( img, data, off, len, tgt, toff ); else console.log( 'Unsupported compression', cmpr ); //console.log(Date.now()-time);
+		if ( cmpr == 34676 ) UTIF.decode._decodeLogLuv32( img, data, off, len, tgt, toff ); else console.log( 'Unsupported compression', cmpr );
+
+		//console.log(Date.now()-time);
 
 
 		var bps = img[ 't258' ] ? Math.min( 32, img[ 't258' ][ 0 ] ) : 1;
 		var bps = img[ 't258' ] ? Math.min( 32, img[ 't258' ][ 0 ] ) : 1;
 		var noc = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1,
 		var noc = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1,
 			bpp = bps * noc >>> 3,
 			bpp = bps * noc >>> 3,
 			h = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height,
 			h = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height,
-			bpl = Math.ceil( bps * noc * img.width / 8 ); // convert to Little Endian  /*
+			bpl = Math.ceil( bps * noc * img.width / 8 );
 
 
-		if ( bps == 16 && ! img.isLE && img[ 't33422' ] == null ) // not DNG
+		// convert to Little Endian  /*
+		if ( bps == 16 && ! img.isLE && img[ 't33422' ] == null )
+		// not DNG
 			for ( var y = 0; y < h; y ++ ) {
 			for ( var y = 0; y < h; y ++ ) {
 
 
 				//console.log("fixing endianity");
 				//console.log("fixing endianity");
 				var roff = toff + y * bpl;
 				var roff = toff + y * bpl;
-
 				for ( var x = 1; x < bpl; x += 2 ) {
 				for ( var x = 1; x < bpl; x += 2 ) {
 
 
 					var t = tgt[ roff + x ];
 					var t = tgt[ roff + x ];
@@ -221,29 +203,23 @@
 			qw = w * 4;
 			qw = w * 4;
 		var io = 0,
 		var io = 0,
 			out = new Uint8Array( qw );
 			out = new Uint8Array( qw );
-
 		while ( io < len ) {
 		while ( io < len ) {
 
 
 			var oo = 0;
 			var oo = 0;
-
 			while ( oo < qw ) {
 			while ( oo < qw ) {
 
 
 				var c = data[ off + io ];
 				var c = data[ off + io ];
 				io ++;
 				io ++;
-
 				if ( c < 128 ) {
 				if ( c < 128 ) {
 
 
 					for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io + j ];
 					for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io + j ];
-
 					oo += c;
 					oo += c;
 					io += c;
 					io += c;
 
 
 				} else {
 				} else {
 
 
 					c = c - 126;
 					c = c - 126;
-
 					for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io ];
 					for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io ];
-
 					oo += c;
 					oo += c;
 					io ++;
 					io ++;
 
 
@@ -265,9 +241,9 @@
 
 
 	};
 	};
 
 
-	UTIF.tags = {}; //UTIF.ttypes = {  256:3,257:3,258:3,   259:3, 262:3,  273:4,  274:3, 277:3,278:4,279:4, 282:5, 283:5, 284:3, 286:5,287:5, 296:3, 305:2, 306:2, 338:3, 513:4, 514:4, 34665:4  };
+	UTIF.tags = {};
+	//UTIF.ttypes = {  256:3,257:3,258:3,   259:3, 262:3,  273:4,  274:3, 277:3,278:4,279:4, 282:5, 283:5, 284:3, 286:5,287:5, 296:3, 305:2, 306:2, 338:3, 513:4, 514:4, 34665:4  };
 	// start at tag 250
 	// start at tag 250
-
 	UTIF._types = function () {
 	UTIF._types = function () {
 
 
 		var main = new Array( 250 );
 		var main = new Array( 250 );
@@ -339,14 +315,12 @@
 		};
 		};
 
 
 	}();
 	}();
-
 	UTIF._readIFD = function ( bin, data, offset, ifds, depth, prm ) {
 	UTIF._readIFD = function ( bin, data, offset, ifds, depth, prm ) {
 
 
 		var cnt = bin.readUshort( data, offset );
 		var cnt = bin.readUshort( data, offset );
 		offset += 2;
 		offset += 2;
 		var ifd = {};
 		var ifd = {};
 		if ( prm.debug ) console.log( '   '.repeat( depth ), ifds.length - 1, '>>>----------------' );
 		if ( prm.debug ) console.log( '   '.repeat( depth ), ifds.length - 1, '>>>----------------' );
-
 		for ( var i = 0; i < cnt; i ++ ) {
 		for ( var i = 0; i < cnt; i ++ ) {
 
 
 			var tag = bin.readUshort( data, offset );
 			var tag = bin.readUshort( data, offset );
@@ -357,8 +331,8 @@
 			offset += 4;
 			offset += 4;
 			var voff = bin.readUint( data, offset );
 			var voff = bin.readUint( data, offset );
 			offset += 4;
 			offset += 4;
-			var arr = []; //ifd["t"+tag+"-"+UTIF.tags[tag]] = arr;
-
+			var arr = [];
+			//ifd["t"+tag+"-"+UTIF.tags[tag]] = arr;
 			if ( type == 1 || type == 7 ) {
 			if ( type == 1 || type == 7 ) {
 
 
 				arr = new Uint8Array( data.buffer, num < 5 ? offset - 4 : voff, num );
 				arr = new Uint8Array( data.buffer, num < 5 ? offset - 4 : voff, num );
@@ -389,7 +363,6 @@
 			if ( type == 5 || type == 10 ) {
 			if ( type == 5 || type == 10 ) {
 
 
 				var ri = type == 5 ? bin.readUint : bin.readInt;
 				var ri = type == 5 ? bin.readUint : bin.readInt;
-
 				for ( var j = 0; j < num; j ++ ) arr.push( [ ri( data, voff + j * 8 ), ri( data, voff + j * 8 + 4 ) ] );
 				for ( var j = 0; j < num; j ++ ) arr.push( [ ri( data, voff + j * 8 ), ri( data, voff + j * 8 + 4 ) ] );
 
 
 			}
 			}
@@ -428,18 +401,14 @@
 
 
 			if ( prm.debug ) console.log( '   '.repeat( depth ), tag, type, UTIF.tags[ tag ], arr );
 			if ( prm.debug ) console.log( '   '.repeat( depth ), tag, type, UTIF.tags[ tag ], arr );
 			ifd[ 't' + tag ] = arr;
 			ifd[ 't' + tag ] = arr;
-
 			if ( tag == 330 || tag == 34665 || tag == 34853 || tag == 50740 && bin.readUshort( data, bin.readUint( arr, 0 ) ) < 300 || tag == 61440 ) {
 			if ( tag == 330 || tag == 34665 || tag == 34853 || tag == 50740 && bin.readUshort( data, bin.readUint( arr, 0 ) ) < 300 || tag == 61440 ) {
 
 
 				var oarr = tag == 50740 ? [ bin.readUint( arr, 0 ) ] : arr;
 				var oarr = tag == 50740 ? [ bin.readUint( arr, 0 ) ] : arr;
 				var subfd = [];
 				var subfd = [];
-
 				for ( var j = 0; j < oarr.length; j ++ ) UTIF._readIFD( bin, data, oarr[ j ], subfd, depth + 1, prm );
 				for ( var j = 0; j < oarr.length; j ++ ) UTIF._readIFD( bin, data, oarr[ j ], subfd, depth + 1, prm );
-
 				if ( tag == 330 ) ifd.subIFD = subfd;
 				if ( tag == 330 ) ifd.subIFD = subfd;
 				if ( tag == 34665 ) ifd.exifIFD = subfd[ 0 ];
 				if ( tag == 34665 ) ifd.exifIFD = subfd[ 0 ];
 				if ( tag == 34853 ) ifd.gpsiIFD = subfd[ 0 ]; //console.log("gps", subfd[0]);  }
 				if ( tag == 34853 ) ifd.gpsiIFD = subfd[ 0 ]; //console.log("gps", subfd[0]);  }
-
 				if ( tag == 50740 ) ifd.dngPrvt = subfd[ 0 ];
 				if ( tag == 50740 ) ifd.dngPrvt = subfd[ 0 ];
 				if ( tag == 61440 ) ifd.fujiIFD = subfd[ 0 ];
 				if ( tag == 61440 ) ifd.fujiIFD = subfd[ 0 ];
 
 
@@ -447,14 +416,12 @@
 
 
 			if ( tag == 37500 && prm.parseMN ) {
 			if ( tag == 37500 && prm.parseMN ) {
 
 
-				var mn = arr; //console.log(bin.readASCII(mn,0,mn.length), mn);
-
+				var mn = arr;
+				//console.log(bin.readASCII(mn,0,mn.length), mn);
 				if ( bin.readASCII( mn, 0, 5 ) == 'Nikon' ) ifd.makerNote = UTIF[ 'decode' ]( mn.slice( 10 ).buffer )[ 0 ]; else if ( bin.readUshort( data, voff ) < 300 && bin.readUshort( data, voff + 4 ) <= 12 ) {
 				if ( bin.readASCII( mn, 0, 5 ) == 'Nikon' ) ifd.makerNote = UTIF[ 'decode' ]( mn.slice( 10 ).buffer )[ 0 ]; else if ( bin.readUshort( data, voff ) < 300 && bin.readUshort( data, voff + 4 ) <= 12 ) {
 
 
 					var subsub = [];
 					var subsub = [];
-
 					UTIF._readIFD( bin, data, voff, subsub, depth + 1, prm );
 					UTIF._readIFD( bin, data, voff, subsub, depth + 1, prm );
-
 					ifd.makerNote = subsub[ 0 ];
 					ifd.makerNote = subsub[ 0 ];
 
 
 				}
 				}
@@ -476,17 +443,14 @@
 			area = w * h,
 			area = w * h,
 			data = out.data;
 			data = out.data;
 		let img;
 		let img;
-
 		switch ( type ) {
 		switch ( type ) {
 
 
 			case THREE.HalfFloatType:
 			case THREE.HalfFloatType:
 				img = new Uint16Array( area * 4 );
 				img = new Uint16Array( area * 4 );
 				break;
 				break;
-
 			case THREE.FloatType:
 			case THREE.FloatType:
 				img = new Float32Array( area * 4 );
 				img = new Float32Array( area * 4 );
 				break;
 				break;
-
 			default:
 			default:
 				console.error( 'THREE.LogLuvLoader: Unsupported texture data type:', type );
 				console.error( 'THREE.LogLuvLoader: Unsupported texture data type:', type );
 
 
@@ -495,7 +459,6 @@
 		let intp = out[ 't262' ] ? out[ 't262' ][ 0 ] : 2;
 		let intp = out[ 't262' ] ? out[ 't262' ][ 0 ] : 2;
 		const bps = out[ 't258' ] ? Math.min( 32, out[ 't258' ][ 0 ] ) : 1;
 		const bps = out[ 't258' ] ? Math.min( 32, out[ 't258' ][ 0 ] ) : 1;
 		if ( out[ 't262' ] == null && bps == 1 ) intp = 0;
 		if ( out[ 't262' ] == null && bps == 1 ) intp = 0;
-
 		if ( intp == 32845 ) {
 		if ( intp == 32845 ) {
 
 
 			for ( let y = 0; y < h; y ++ ) {
 			for ( let y = 0; y < h; y ++ ) {
@@ -507,20 +470,22 @@
 					let L = data[ si + 1 ] << 8 | data[ si ];
 					let L = data[ si + 1 ] << 8 | data[ si ];
 					L = Math.pow( 2, ( L + 0.5 ) / 256 - 64 );
 					L = Math.pow( 2, ( L + 0.5 ) / 256 - 64 );
 					const u = ( data[ si + 3 ] + 0.5 ) / 410;
 					const u = ( data[ si + 3 ] + 0.5 ) / 410;
-					const v = ( data[ si + 5 ] + 0.5 ) / 410; // Luv to xyY
+					const v = ( data[ si + 5 ] + 0.5 ) / 410;
 
 
+					// Luv to xyY
 					const sX = 9 * u / ( 6 * u - 16 * v + 12 );
 					const sX = 9 * u / ( 6 * u - 16 * v + 12 );
 					const sY = 4 * v / ( 6 * u - 16 * v + 12 );
 					const sY = 4 * v / ( 6 * u - 16 * v + 12 );
-					const bY = L; // xyY to XYZ
+					const bY = L;
 
 
+					// xyY to XYZ
 					const X = sX * bY / sY,
 					const X = sX * bY / sY,
 						Y = bY,
 						Y = bY,
-						Z = ( 1 - sX - sY ) * bY / sY; // XYZ to linear RGB
+						Z = ( 1 - sX - sY ) * bY / sY;
 
 
+					// XYZ to linear RGB
 					const r = 2.690 * X - 1.276 * Y - 0.414 * Z;
 					const r = 2.690 * X - 1.276 * Y - 0.414 * Z;
 					const g = - 1.022 * X + 1.978 * Y + 0.044 * Z;
 					const g = - 1.022 * X + 1.978 * Y + 0.044 * Z;
 					const b = 0.061 * X - 0.224 * Y + 1.163 * Z;
 					const b = 0.061 * X - 0.224 * Y + 1.163 * Z;
-
 					if ( type === THREE.HalfFloatType ) {
 					if ( type === THREE.HalfFloatType ) {
 
 
 						img[ qi ] = THREE.DataUtils.toHalfFloat( Math.min( r, 65504 ) );
 						img[ qi ] = THREE.DataUtils.toHalfFloat( Math.min( r, 65504 ) );
@@ -555,7 +520,6 @@
 		nextZero: function ( data, o ) {
 		nextZero: function ( data, o ) {
 
 
 			while ( data[ o ] != 0 ) o ++;
 			while ( data[ o ] != 0 ) o ++;
-
 			return o;
 			return o;
 
 
 		},
 		},
@@ -595,27 +559,21 @@
 		readASCII: function ( buff, p, l ) {
 		readASCII: function ( buff, p, l ) {
 
 
 			var s = '';
 			var s = '';
-
 			for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] );
 			for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] );
-
 			return s;
 			return s;
 
 
 		},
 		},
 		readFloat: function ( buff, p ) {
 		readFloat: function ( buff, p ) {
 
 
 			var a = UTIF._binBE.ui8;
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + 3 - i ];
 			for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + 3 - i ];
-
 			return UTIF._binBE.fl32[ 0 ];
 			return UTIF._binBE.fl32[ 0 ];
 
 
 		},
 		},
 		readDouble: function ( buff, p ) {
 		readDouble: function ( buff, p ) {
 
 
 			var a = UTIF._binBE.ui8;
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + 7 - i ];
 			for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + 7 - i ];
-
 			return UTIF._binBE.fl64[ 0 ];
 			return UTIF._binBE.fl64[ 0 ];
 
 
 		},
 		},
@@ -651,7 +609,6 @@
 		writeDouble: function ( buff, p, n ) {
 		writeDouble: function ( buff, p, n ) {
 
 
 			UTIF._binBE.fl64[ 0 ] = n;
 			UTIF._binBE.fl64[ 0 ] = n;
-
 			for ( var i = 0; i < 8; i ++ ) buff[ p + i ] = UTIF._binBE.ui8[ 7 - i ];
 			for ( var i = 0; i < 8; i ++ ) buff[ p + i ] = UTIF._binBE.ui8[ 7 - i ];
 
 
 		}
 		}
@@ -701,18 +658,14 @@
 		readFloat: function ( buff, p ) {
 		readFloat: function ( buff, p ) {
 
 
 			var a = UTIF._binBE.ui8;
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + i ];
 			for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + i ];
-
 			return UTIF._binBE.fl32[ 0 ];
 			return UTIF._binBE.fl32[ 0 ];
 
 
 		},
 		},
 		readDouble: function ( buff, p ) {
 		readDouble: function ( buff, p ) {
 
 
 			var a = UTIF._binBE.ui8;
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + i ];
 			for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + i ];
-
 			return UTIF._binBE.fl64[ 0 ];
 			return UTIF._binBE.fl64[ 0 ];
 
 
 		},
 		},
@@ -742,18 +695,15 @@
 		},
 		},
 		writeASCII: UTIF._binBE.writeASCII
 		writeASCII: UTIF._binBE.writeASCII
 	};
 	};
-
 	UTIF._copyTile = function ( tb, tw, th, b, w, h, xoff, yoff ) {
 	UTIF._copyTile = function ( tb, tw, th, b, w, h, xoff, yoff ) {
 
 
 		//log("copyTile", tw, th,  w, h, xoff, yoff);
 		//log("copyTile", tw, th,  w, h, xoff, yoff);
 		var xlim = Math.min( tw, w - xoff );
 		var xlim = Math.min( tw, w - xoff );
 		var ylim = Math.min( th, h - yoff );
 		var ylim = Math.min( th, h - yoff );
-
 		for ( var y = 0; y < ylim; y ++ ) {
 		for ( var y = 0; y < ylim; y ++ ) {
 
 
 			var tof = ( yoff + y ) * w + xoff;
 			var tof = ( yoff + y ) * w + xoff;
 			var sof = y * tw;
 			var sof = y * tw;
-
 			for ( var x = 0; x < xlim; x ++ ) b[ tof + x ] = tb[ sof + x ];
 			for ( var x = 0; x < xlim; x ++ ) b[ tof + x ] = tb[ sof + x ];
 
 
 		}
 		}

+ 3 - 3
examples/js/loaders/LottieLoader.js

@@ -7,7 +7,6 @@
 			this._quality = value;
 			this._quality = value;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const quality = this._quality || 1;
 			const quality = this._quality || 1;
@@ -18,7 +17,9 @@
 			loader.setWithCredentials( this.withCredentials );
 			loader.setWithCredentials( this.withCredentials );
 			loader.load( url, function ( text ) {
 			loader.load( url, function ( text ) {
 
 
-				const data = JSON.parse( text ); // lottie uses container.offetWidth and offsetHeight
+				const data = JSON.parse( text );
+
+				// lottie uses container.offetWidth and offsetHeight
 				// to define width/height
 				// to define width/height
 
 
 				const container = document.createElement( 'div' );
 				const container = document.createElement( 'div' );
@@ -43,7 +44,6 @@
 
 
 				} );
 				} );
 				container.style.display = 'none';
 				container.style.display = 'none';
-
 				if ( onLoad !== undefined ) {
 				if ( onLoad !== undefined ) {
 
 
 					onLoad( texture );
 					onLoad( texture );

文件差異過大導致無法顯示
+ 0 - 0
examples/js/loaders/MD2Loader.js


+ 6 - 10
examples/js/loaders/MDDLoader.js

@@ -11,7 +11,6 @@
  * time values for each frame (sequence of float32)
  * time values for each frame (sequence of float32)
  * vertex data for each frame (sequence of float32)
  * vertex data for each frame (sequence of float32)
  */
  */
-
 	class MDDLoader extends THREE.Loader {
 	class MDDLoader extends THREE.Loader {
 
 
 		constructor( manager ) {
 		constructor( manager ) {
@@ -19,7 +18,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -33,17 +31,17 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			const view = new DataView( data );
 			const view = new DataView( data );
 			const totalFrames = view.getUint32( 0 );
 			const totalFrames = view.getUint32( 0 );
 			const totalPoints = view.getUint32( 4 );
 			const totalPoints = view.getUint32( 4 );
-			let offset = 8; // animation clip
+			let offset = 8;
+
+			// animation clip
 
 
 			const times = new Float32Array( totalFrames );
 			const times = new Float32Array( totalFrames );
 			const values = new Float32Array( totalFrames * totalFrames ).fill( 0 );
 			const values = new Float32Array( totalFrames * totalFrames ).fill( 0 );
-
 			for ( let i = 0; i < totalFrames; i ++ ) {
 			for ( let i = 0; i < totalFrames; i ++ ) {
 
 
 				times[ i ] = view.getFloat32( offset );
 				times[ i ] = view.getFloat32( offset );
@@ -53,23 +51,21 @@
 			}
 			}
 
 
 			const track = new THREE.NumberKeyframeTrack( '.morphTargetInfluences', times, values );
 			const track = new THREE.NumberKeyframeTrack( '.morphTargetInfluences', times, values );
-			const clip = new THREE.AnimationClip( 'default', times[ times.length - 1 ], [ track ] ); // morph targets
+			const clip = new THREE.AnimationClip( 'default', times[ times.length - 1 ], [ track ] );
 
 
-			const morphTargets = [];
+			// morph targets
 
 
+			const morphTargets = [];
 			for ( let i = 0; i < totalFrames; i ++ ) {
 			for ( let i = 0; i < totalFrames; i ++ ) {
 
 
 				const morphTarget = new Float32Array( totalPoints * 3 );
 				const morphTarget = new Float32Array( totalPoints * 3 );
-
 				for ( let j = 0; j < totalPoints; j ++ ) {
 				for ( let j = 0; j < totalPoints; j ++ ) {
 
 
 					const stride = j * 3;
 					const stride = j * 3;
 					morphTarget[ stride + 0 ] = view.getFloat32( offset );
 					morphTarget[ stride + 0 ] = view.getFloat32( offset );
 					offset += 4; // x
 					offset += 4; // x
-
 					morphTarget[ stride + 1 ] = view.getFloat32( offset );
 					morphTarget[ stride + 1 ] = view.getFloat32( offset );
 					offset += 4; // y
 					offset += 4; // y
-
 					morphTarget[ stride + 2 ] = view.getFloat32( offset );
 					morphTarget[ stride + 2 ] = view.getFloat32( offset );
 					offset += 4; // z
 					offset += 4; // z
 
 

文件差異過大導致無法顯示
+ 22 - 35
examples/js/loaders/MMDLoader.js


+ 18 - 47
examples/js/loaders/MTLLoader.js

@@ -11,6 +11,7 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
+
 		/**
 		/**
    * Loads and parses a MTL asset from a URL.
    * Loads and parses a MTL asset from a URL.
    *
    *
@@ -24,8 +25,6 @@
    * @note In order for relative texture references to resolve correctly
    * @note In order for relative texture references to resolve correctly
    * you must call setResourcePath() explicitly prior to load.
    * you must call setResourcePath() explicitly prior to load.
    */
    */
-
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -59,13 +58,13 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		setMaterialOptions( value ) {
 		setMaterialOptions( value ) {
 
 
 			this.materialOptions = value;
 			this.materialOptions = value;
 			return this;
 			return this;
 
 
 		}
 		}
+
 		/**
 		/**
    * Parses a MTL file.
    * Parses a MTL file.
    *
    *
@@ -77,20 +76,16 @@
    * @note In order for relative texture references to resolve correctly
    * @note In order for relative texture references to resolve correctly
    * you must call setResourcePath() explicitly prior to parse.
    * you must call setResourcePath() explicitly prior to parse.
    */
    */
-
-
 		parse( text, path ) {
 		parse( text, path ) {
 
 
 			const lines = text.split( '\n' );
 			const lines = text.split( '\n' );
 			let info = {};
 			let info = {};
 			const delimiter_pattern = /\s+/;
 			const delimiter_pattern = /\s+/;
 			const materialsInfo = {};
 			const materialsInfo = {};
-
 			for ( let i = 0; i < lines.length; i ++ ) {
 			for ( let i = 0; i < lines.length; i ++ ) {
 
 
 				let line = lines[ i ];
 				let line = lines[ i ];
 				line = line.trim();
 				line = line.trim();
-
 				if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
 				if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
 
 
 					// Blank line or comment ignore
 					// Blank line or comment ignore
@@ -103,10 +98,10 @@
 				key = key.toLowerCase();
 				key = key.toLowerCase();
 				let value = pos >= 0 ? line.substring( pos + 1 ) : '';
 				let value = pos >= 0 ? line.substring( pos + 1 ) : '';
 				value = value.trim();
 				value = value.trim();
-
 				if ( key === 'newmtl' ) {
 				if ( key === 'newmtl' ) {
 
 
 					// New material
 					// New material
+
 					info = {
 					info = {
 						name: value
 						name: value
 					};
 					};
@@ -138,6 +133,7 @@
 		}
 		}
 
 
 	}
 	}
+
 	/**
 	/**
  * Create a new MTLLoader.MaterialCreator
  * Create a new MTLLoader.MaterialCreator
  * @param baseUrl - Url relative to which textures are loaded
  * @param baseUrl - Url relative to which textures are loaded
@@ -153,7 +149,6 @@
  * @constructor
  * @constructor
  */
  */
 
 
-
 	class MaterialCreator {
 	class MaterialCreator {
 
 
 		constructor( baseUrl = '', options = {} ) {
 		constructor( baseUrl = '', options = {} ) {
@@ -169,20 +164,17 @@
 			this.wrap = this.options.wrap !== undefined ? this.options.wrap : THREE.RepeatWrapping;
 			this.wrap = this.options.wrap !== undefined ? this.options.wrap : THREE.RepeatWrapping;
 
 
 		}
 		}
-
 		setCrossOrigin( value ) {
 		setCrossOrigin( value ) {
 
 
 			this.crossOrigin = value;
 			this.crossOrigin = value;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setManager( value ) {
 		setManager( value ) {
 
 
 			this.manager = value;
 			this.manager = value;
 
 
 		}
 		}
-
 		setMaterials( materialsInfo ) {
 		setMaterials( materialsInfo ) {
 
 
 			this.materialsInfo = this.convert( materialsInfo );
 			this.materialsInfo = this.convert( materialsInfo );
@@ -191,31 +183,29 @@
 			this.nameLookup = {};
 			this.nameLookup = {};
 
 
 		}
 		}
-
 		convert( materialsInfo ) {
 		convert( materialsInfo ) {
 
 
 			if ( ! this.options ) return materialsInfo;
 			if ( ! this.options ) return materialsInfo;
 			const converted = {};
 			const converted = {};
-
 			for ( const mn in materialsInfo ) {
 			for ( const mn in materialsInfo ) {
 
 
 				// Convert materials info into normalized form based on options
 				// Convert materials info into normalized form based on options
+
 				const mat = materialsInfo[ mn ];
 				const mat = materialsInfo[ mn ];
 				const covmat = {};
 				const covmat = {};
 				converted[ mn ] = covmat;
 				converted[ mn ] = covmat;
-
 				for ( const prop in mat ) {
 				for ( const prop in mat ) {
 
 
 					let save = true;
 					let save = true;
 					let value = mat[ prop ];
 					let value = mat[ prop ];
 					const lprop = prop.toLowerCase();
 					const lprop = prop.toLowerCase();
-
 					switch ( lprop ) {
 					switch ( lprop ) {
 
 
 						case 'kd':
 						case 'kd':
 						case 'ka':
 						case 'ka':
 						case 'ks':
 						case 'ks':
 							// Diffuse color (color under white light) using RGB values
 							// Diffuse color (color under white light) using RGB values
+
 							if ( this.options && this.options.normalizeRGB ) {
 							if ( this.options && this.options.normalizeRGB ) {
 
 
 								value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
 								value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
@@ -227,6 +217,7 @@
 								if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) {
 								if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) {
 
 
 									// ignore
 									// ignore
+
 									save = false;
 									save = false;
 
 
 								}
 								}
@@ -234,7 +225,6 @@
 							}
 							}
 
 
 							break;
 							break;
-
 						default:
 						default:
 							break;
 							break;
 
 
@@ -253,7 +243,6 @@
 			return converted;
 			return converted;
 
 
 		}
 		}
-
 		preload() {
 		preload() {
 
 
 			for ( const mn in this.materialsInfo ) {
 			for ( const mn in this.materialsInfo ) {
@@ -263,17 +252,14 @@
 			}
 			}
 
 
 		}
 		}
-
 		getIndex( materialName ) {
 		getIndex( materialName ) {
 
 
 			return this.nameLookup[ materialName ];
 			return this.nameLookup[ materialName ];
 
 
 		}
 		}
-
 		getAsArray() {
 		getAsArray() {
 
 
 			let index = 0;
 			let index = 0;
-
 			for ( const mn in this.materialsInfo ) {
 			for ( const mn in this.materialsInfo ) {
 
 
 				this.materialsArray[ index ] = this.create( mn );
 				this.materialsArray[ index ] = this.create( mn );
@@ -285,7 +271,6 @@
 			return this.materialsArray;
 			return this.materialsArray;
 
 
 		}
 		}
-
 		create( materialName ) {
 		create( materialName ) {
 
 
 			if ( this.materials[ materialName ] === undefined ) {
 			if ( this.materials[ materialName ] === undefined ) {
@@ -297,21 +282,21 @@
 			return this.materials[ materialName ];
 			return this.materials[ materialName ];
 
 
 		}
 		}
-
 		createMaterial_( materialName ) {
 		createMaterial_( materialName ) {
 
 
 			// Create material
 			// Create material
+
 			const scope = this;
 			const scope = this;
 			const mat = this.materialsInfo[ materialName ];
 			const mat = this.materialsInfo[ materialName ];
 			const params = {
 			const params = {
 				name: materialName,
 				name: materialName,
 				side: this.side
 				side: this.side
 			};
 			};
-
 			function resolveURL( baseUrl, url ) {
 			function resolveURL( baseUrl, url ) {
 
 
-				if ( typeof url !== 'string' || url === '' ) return ''; // Absolute URL
+				if ( typeof url !== 'string' || url === '' ) return '';
 
 
+				// Absolute URL
 				if ( /^https?:\/\//i.test( url ) ) return url;
 				if ( /^https?:\/\//i.test( url ) ) return url;
 				return baseUrl + url;
 				return baseUrl + url;
 
 
@@ -327,7 +312,6 @@
 				map.offset.copy( texParams.offset );
 				map.offset.copy( texParams.offset );
 				map.wrapS = scope.wrap;
 				map.wrapS = scope.wrap;
 				map.wrapT = scope.wrap;
 				map.wrapT = scope.wrap;
-
 				if ( mapType === 'map' || mapType === 'emissiveMap' ) {
 				if ( mapType === 'map' || mapType === 'emissiveMap' ) {
 
 
 					map.encoding = THREE.sRGBEncoding;
 					map.encoding = THREE.sRGBEncoding;
@@ -343,65 +327,61 @@
 				const value = mat[ prop ];
 				const value = mat[ prop ];
 				let n;
 				let n;
 				if ( value === '' ) continue;
 				if ( value === '' ) continue;
-
 				switch ( prop.toLowerCase() ) {
 				switch ( prop.toLowerCase() ) {
 
 
 					// Ns is material specular exponent
 					// Ns is material specular exponent
+
 					case 'kd':
 					case 'kd':
 						// Diffuse color (color under white light) using RGB values
 						// Diffuse color (color under white light) using RGB values
+
 						params.color = new THREE.Color().fromArray( value ).convertSRGBToLinear();
 						params.color = new THREE.Color().fromArray( value ).convertSRGBToLinear();
 						break;
 						break;
-
 					case 'ks':
 					case 'ks':
 						// Specular color (color when light is reflected from shiny surface) using RGB values
 						// Specular color (color when light is reflected from shiny surface) using RGB values
 						params.specular = new THREE.Color().fromArray( value ).convertSRGBToLinear();
 						params.specular = new THREE.Color().fromArray( value ).convertSRGBToLinear();
 						break;
 						break;
-
 					case 'ke':
 					case 'ke':
 						// Emissive using RGB values
 						// Emissive using RGB values
 						params.emissive = new THREE.Color().fromArray( value ).convertSRGBToLinear();
 						params.emissive = new THREE.Color().fromArray( value ).convertSRGBToLinear();
 						break;
 						break;
-
 					case 'map_kd':
 					case 'map_kd':
 						// Diffuse texture map
 						// Diffuse texture map
+
 						setMapForType( 'map', value );
 						setMapForType( 'map', value );
 						break;
 						break;
-
 					case 'map_ks':
 					case 'map_ks':
 						// Specular map
 						// Specular map
+
 						setMapForType( 'specularMap', value );
 						setMapForType( 'specularMap', value );
 						break;
 						break;
-
 					case 'map_ke':
 					case 'map_ke':
 						// Emissive map
 						// Emissive map
+
 						setMapForType( 'emissiveMap', value );
 						setMapForType( 'emissiveMap', value );
 						break;
 						break;
-
 					case 'norm':
 					case 'norm':
 						setMapForType( 'normalMap', value );
 						setMapForType( 'normalMap', value );
 						break;
 						break;
-
 					case 'map_bump':
 					case 'map_bump':
 					case 'bump':
 					case 'bump':
 						// Bump texture map
 						// Bump texture map
+
 						setMapForType( 'bumpMap', value );
 						setMapForType( 'bumpMap', value );
 						break;
 						break;
-
 					case 'map_d':
 					case 'map_d':
 						// Alpha map
 						// Alpha map
+
 						setMapForType( 'alphaMap', value );
 						setMapForType( 'alphaMap', value );
 						params.transparent = true;
 						params.transparent = true;
 						break;
 						break;
-
 					case 'ns':
 					case 'ns':
 						// The specular exponent (defines the focus of the specular highlight)
 						// The specular exponent (defines the focus of the specular highlight)
 						// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
 						// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
+
 						params.shininess = parseFloat( value );
 						params.shininess = parseFloat( value );
 						break;
 						break;
-
 					case 'd':
 					case 'd':
 						n = parseFloat( value );
 						n = parseFloat( value );
-
 						if ( n < 1 ) {
 						if ( n < 1 ) {
 
 
 							params.opacity = n;
 							params.opacity = n;
@@ -410,11 +390,9 @@
 						}
 						}
 
 
 						break;
 						break;
-
 					case 'tr':
 					case 'tr':
 						n = parseFloat( value );
 						n = parseFloat( value );
 						if ( this.options && this.options.invertTrProperty ) n = 1 - n;
 						if ( this.options && this.options.invertTrProperty ) n = 1 - n;
-
 						if ( n > 0 ) {
 						if ( n > 0 ) {
 
 
 							params.opacity = 1 - n;
 							params.opacity = 1 - n;
@@ -423,7 +401,6 @@
 						}
 						}
 
 
 						break;
 						break;
-
 					default:
 					default:
 						break;
 						break;
 
 
@@ -435,7 +412,6 @@
 			return this.materials[ materialName ];
 			return this.materials[ materialName ];
 
 
 		}
 		}
-
 		getTextureParams( value, matParams ) {
 		getTextureParams( value, matParams ) {
 
 
 			const texParams = {
 			const texParams = {
@@ -445,7 +421,6 @@
 			const items = value.split( /\s+/ );
 			const items = value.split( /\s+/ );
 			let pos;
 			let pos;
 			pos = items.indexOf( '-bm' );
 			pos = items.indexOf( '-bm' );
-
 			if ( pos >= 0 ) {
 			if ( pos >= 0 ) {
 
 
 				matParams.bumpScale = parseFloat( items[ pos + 1 ] );
 				matParams.bumpScale = parseFloat( items[ pos + 1 ] );
@@ -454,7 +429,6 @@
 			}
 			}
 
 
 			pos = items.indexOf( '-s' );
 			pos = items.indexOf( '-s' );
-
 			if ( pos >= 0 ) {
 			if ( pos >= 0 ) {
 
 
 				texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
 				texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
@@ -463,7 +437,6 @@
 			}
 			}
 
 
 			pos = items.indexOf( '-o' );
 			pos = items.indexOf( '-o' );
-
 			if ( pos >= 0 ) {
 			if ( pos >= 0 ) {
 
 
 				texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
 				texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
@@ -475,12 +448,10 @@
 			return texParams;
 			return texParams;
 
 
 		}
 		}
-
 		loadTexture( url, mapping, onLoad, onProgress, onError ) {
 		loadTexture( url, mapping, onLoad, onProgress, onError ) {
 
 
 			const manager = this.manager !== undefined ? this.manager : THREE.DefaultLoadingManager;
 			const manager = this.manager !== undefined ? this.manager : THREE.DefaultLoadingManager;
 			let loader = manager.getHandler( url );
 			let loader = manager.getHandler( url );
-
 			if ( loader === null ) {
 			if ( loader === null ) {
 
 
 				loader = new THREE.TextureLoader( manager );
 				loader = new THREE.TextureLoader( manager );

+ 44 - 84
examples/js/loaders/NRRDLoader.js

@@ -7,7 +7,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -41,18 +40,15 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			// this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X
 			// this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X
+
 			let _data = data;
 			let _data = data;
 			let _dataPointer = 0;
 			let _dataPointer = 0;
-
 			const _nativeLittleEndian = new Int8Array( new Int16Array( [ 1 ] ).buffer )[ 0 ] > 0;
 			const _nativeLittleEndian = new Int8Array( new Int16Array( [ 1 ] ).buffer )[ 0 ] > 0;
-
 			const _littleEndian = true;
 			const _littleEndian = true;
 			const headerObject = {};
 			const headerObject = {};
-
 			function scan( type, chunks ) {
 			function scan( type, chunks ) {
 
 
 				if ( chunks === undefined || chunks === null ) {
 				if ( chunks === undefined || chunks === null ) {
@@ -63,60 +59,51 @@
 
 
 				let _chunkSize = 1;
 				let _chunkSize = 1;
 				let _array_type = Uint8Array;
 				let _array_type = Uint8Array;
-
 				switch ( type ) {
 				switch ( type ) {
 
 
 					// 1 byte data types
 					// 1 byte data types
 					case 'uchar':
 					case 'uchar':
 						break;
 						break;
-
 					case 'schar':
 					case 'schar':
 						_array_type = Int8Array;
 						_array_type = Int8Array;
 						break;
 						break;
 						// 2 byte data types
 						// 2 byte data types
-
 					case 'ushort':
 					case 'ushort':
 						_array_type = Uint16Array;
 						_array_type = Uint16Array;
 						_chunkSize = 2;
 						_chunkSize = 2;
 						break;
 						break;
-
 					case 'sshort':
 					case 'sshort':
 						_array_type = Int16Array;
 						_array_type = Int16Array;
 						_chunkSize = 2;
 						_chunkSize = 2;
 						break;
 						break;
 						// 4 byte data types
 						// 4 byte data types
-
 					case 'uint':
 					case 'uint':
 						_array_type = Uint32Array;
 						_array_type = Uint32Array;
 						_chunkSize = 4;
 						_chunkSize = 4;
 						break;
 						break;
-
 					case 'sint':
 					case 'sint':
 						_array_type = Int32Array;
 						_array_type = Int32Array;
 						_chunkSize = 4;
 						_chunkSize = 4;
 						break;
 						break;
-
 					case 'float':
 					case 'float':
 						_array_type = Float32Array;
 						_array_type = Float32Array;
 						_chunkSize = 4;
 						_chunkSize = 4;
 						break;
 						break;
-
 					case 'complex':
 					case 'complex':
 						_array_type = Float64Array;
 						_array_type = Float64Array;
 						_chunkSize = 8;
 						_chunkSize = 8;
 						break;
 						break;
-
 					case 'double':
 					case 'double':
 						_array_type = Float64Array;
 						_array_type = Float64Array;
 						_chunkSize = 8;
 						_chunkSize = 8;
 						break;
 						break;
 
 
-				} // increase the data pointer in-place
-
-
-				let _bytes = new _array_type( _data.slice( _dataPointer, _dataPointer += chunks * _chunkSize ) ); // if required, flip the endianness of the bytes
+				}
 
 
+				// increase the data pointer in-place
+				let _bytes = new _array_type( _data.slice( _dataPointer, _dataPointer += chunks * _chunkSize ) );
 
 
+				// if required, flip the endianness of the bytes
 				if ( _nativeLittleEndian != _littleEndian ) {
 				if ( _nativeLittleEndian != _littleEndian ) {
 
 
 					// we need to flip here since the format doesn't match the native endianness
 					// we need to flip here since the format doesn't match the native endianness
@@ -129,18 +116,18 @@
 					// if only one chunk was requested, just return one value
 					// if only one chunk was requested, just return one value
 					return _bytes[ 0 ];
 					return _bytes[ 0 ];
 
 
-				} // return the byte array
-
+				}
 
 
+				// return the byte array
 				return _bytes;
 				return _bytes;
 
 
-			} //Flips typed array endianness in-place. Based on https://github.com/kig/DataStream.js/blob/master/DataStream.js.
+			}
 
 
+			//Flips typed array endianness in-place. Based on https://github.com/kig/DataStream.js/blob/master/DataStream.js.
 
 
 			function flipEndianness( array, chunkSize ) {
 			function flipEndianness( array, chunkSize ) {
 
 
 				const u8 = new Uint8Array( array.buffer, array.byteOffset, array.byteLength );
 				const u8 = new Uint8Array( array.buffer, array.byteOffset, array.byteLength );
-
 				for ( let i = 0; i < array.byteLength; i += chunkSize ) {
 				for ( let i = 0; i < array.byteLength; i += chunkSize ) {
 
 
 					for ( let j = i + chunkSize - 1, k = i; j > k; j --, k ++ ) {
 					for ( let j = i + chunkSize - 1, k = i; j > k; j --, k ++ ) {
@@ -155,19 +142,16 @@
 
 
 				return array;
 				return array;
 
 
-			} //parse the header
-
+			}
 
 
+			//parse the header
 			function parseHeader( header ) {
 			function parseHeader( header ) {
 
 
 				let data, field, fn, i, l, m, _i, _len;
 				let data, field, fn, i, l, m, _i, _len;
-
 				const lines = header.split( /\r?\n/ );
 				const lines = header.split( /\r?\n/ );
-
 				for ( _i = 0, _len = lines.length; _i < _len; _i ++ ) {
 				for ( _i = 0, _len = lines.length; _i < _len; _i ++ ) {
 
 
 					l = lines[ _i ];
 					l = lines[ _i ];
-
 					if ( l.match( /NRRD\d+/ ) ) {
 					if ( l.match( /NRRD\d+/ ) ) {
 
 
 						headerObject.isNrrd = true;
 						headerObject.isNrrd = true;
@@ -177,7 +161,6 @@
 						field = m[ 1 ].trim();
 						field = m[ 1 ].trim();
 						data = m[ 2 ].trim();
 						data = m[ 2 ].trim();
 						fn = _fieldFunctions[ field ];
 						fn = _fieldFunctions[ field ];
-
 						if ( fn ) {
 						if ( fn ) {
 
 
 							fn.call( headerObject, data );
 							fn.call( headerObject, data );
@@ -210,8 +193,9 @@
 					headerObject.vectors = [];
 					headerObject.vectors = [];
 					headerObject.vectors.push( [ 1, 0, 0 ] );
 					headerObject.vectors.push( [ 1, 0, 0 ] );
 					headerObject.vectors.push( [ 0, 1, 0 ] );
 					headerObject.vectors.push( [ 0, 1, 0 ] );
-					headerObject.vectors.push( [ 0, 0, 1 ] ); //apply spacing if defined
+					headerObject.vectors.push( [ 0, 0, 1 ] );
 
 
+					//apply spacing if defined
 					if ( headerObject.spacings ) {
 					if ( headerObject.spacings ) {
 
 
 						for ( i = 0; i <= 2; i ++ ) {
 						for ( i = 0; i <= 2; i ++ ) {
@@ -232,23 +216,22 @@
 
 
 				}
 				}
 
 
-			} //parse the data when registred as one of this type : 'text', 'ascii', 'txt'
-
+			}
 
 
+			//parse the data when registred as one of this type : 'text', 'ascii', 'txt'
 			function parseDataAsText( data, start, end ) {
 			function parseDataAsText( data, start, end ) {
 
 
 				let number = '';
 				let number = '';
 				start = start || 0;
 				start = start || 0;
 				end = end || data.length;
 				end = end || data.length;
-				let value; //length of the result is the product of the sizes
-
+				let value;
+				//length of the result is the product of the sizes
 				const lengthOfTheResult = headerObject.sizes.reduce( function ( previous, current ) {
 				const lengthOfTheResult = headerObject.sizes.reduce( function ( previous, current ) {
 
 
 					return previous * current;
 					return previous * current;
 
 
 				}, 1 );
 				}, 1 );
 				let base = 10;
 				let base = 10;
-
 				if ( headerObject.encoding === 'hex' ) {
 				if ( headerObject.encoding === 'hex' ) {
 
 
 					base = 16;
 					base = 16;
@@ -258,7 +241,6 @@
 				const result = new headerObject.__array( lengthOfTheResult );
 				const result = new headerObject.__array( lengthOfTheResult );
 				let resultIndex = 0;
 				let resultIndex = 0;
 				let parsingFunction = parseInt;
 				let parsingFunction = parseInt;
-
 				if ( headerObject.__array === Float32Array || headerObject.__array === Float64Array ) {
 				if ( headerObject.__array === Float32Array || headerObject.__array === Float64Array ) {
 
 
 					parsingFunction = parseFloat;
 					parsingFunction = parseFloat;
@@ -267,8 +249,8 @@
 
 
 				for ( let i = start; i < end; i ++ ) {
 				for ( let i = start; i < end; i ++ ) {
 
 
-					value = data[ i ]; //if value is not a space
-
+					value = data[ i ];
+					//if value is not a space
 					if ( ( value < 9 || value > 13 ) && value !== 32 ) {
 					if ( ( value < 9 || value > 13 ) && value !== 32 ) {
 
 
 						number += String.fromCharCode( value );
 						number += String.fromCharCode( value );
@@ -300,31 +282,28 @@
 			}
 			}
 
 
 			const _bytes = scan( 'uchar', data.byteLength );
 			const _bytes = scan( 'uchar', data.byteLength );
-
 			const _length = _bytes.length;
 			const _length = _bytes.length;
 			let _header = null;
 			let _header = null;
 			let _data_start = 0;
 			let _data_start = 0;
 			let i;
 			let i;
-
 			for ( i = 1; i < _length; i ++ ) {
 			for ( i = 1; i < _length; i ++ ) {
 
 
 				if ( _bytes[ i - 1 ] == 10 && _bytes[ i ] == 10 ) {
 				if ( _bytes[ i - 1 ] == 10 && _bytes[ i ] == 10 ) {
 
 
 					// we found two line breaks in a row
 					// we found two line breaks in a row
 					// now we know what the header is
 					// now we know what the header is
-					_header = this.parseChars( _bytes, 0, i - 2 ); // this is were the data starts
-
+					_header = this.parseChars( _bytes, 0, i - 2 );
+					// this is were the data starts
 					_data_start = i + 1;
 					_data_start = i + 1;
 					break;
 					break;
 
 
 				}
 				}
 
 
-			} // parse the header
-
+			}
 
 
+			// parse the header
 			parseHeader( _header );
 			parseHeader( _header );
 			_data = _bytes.subarray( _data_start ); // the data without header
 			_data = _bytes.subarray( _data_start ); // the data without header
-
 			if ( headerObject.encoding.substring( 0, 2 ) === 'gz' ) {
 			if ( headerObject.encoding.substring( 0, 2 ) === 'gz' ) {
 
 
 				// we need to decompress the datastream
 				// we need to decompress the datastream
@@ -339,7 +318,6 @@
 
 
 				//we need to copy the array to create a new array buffer, else we retrieve the original arraybuffer with the header
 				//we need to copy the array to create a new array buffer, else we retrieve the original arraybuffer with the header
 				const _copy = new Uint8Array( _data.length );
 				const _copy = new Uint8Array( _data.length );
-
 				for ( let i = 0; i < _data.length; i ++ ) {
 				for ( let i = 0; i < _data.length; i ++ ) {
 
 
 					_copy[ i ] = _data[ i ];
 					_copy[ i ] = _data[ i ];
@@ -348,29 +326,31 @@
 
 
 				_data = _copy;
 				_data = _copy;
 
 
-			} // .. let's use the underlying array buffer
-
+			}
 
 
+			// .. let's use the underlying array buffer
 			_data = _data.buffer;
 			_data = _data.buffer;
 			const volume = new THREE.Volume();
 			const volume = new THREE.Volume();
-			volume.header = headerObject; //
+			volume.header = headerObject;
+			//
 			// parse the (unzipped) data to a datastream of the correct type
 			// parse the (unzipped) data to a datastream of the correct type
 			//
 			//
-
-			volume.data = new headerObject.__array( _data ); // get the min and max intensities
-
+			volume.data = new headerObject.__array( _data );
+			// get the min and max intensities
 			const min_max = volume.computeMinMax();
 			const min_max = volume.computeMinMax();
 			const min = min_max[ 0 ];
 			const min = min_max[ 0 ];
-			const max = min_max[ 1 ]; // attach the scalar range to the volume
-
+			const max = min_max[ 1 ];
+			// attach the scalar range to the volume
 			volume.windowLow = min;
 			volume.windowLow = min;
-			volume.windowHigh = max; // get the image dimensions
+			volume.windowHigh = max;
 
 
+			// get the image dimensions
 			volume.dimensions = [ headerObject.sizes[ 0 ], headerObject.sizes[ 1 ], headerObject.sizes[ 2 ] ];
 			volume.dimensions = [ headerObject.sizes[ 0 ], headerObject.sizes[ 1 ], headerObject.sizes[ 2 ] ];
 			volume.xLength = volume.dimensions[ 0 ];
 			volume.xLength = volume.dimensions[ 0 ];
 			volume.yLength = volume.dimensions[ 1 ];
 			volume.yLength = volume.dimensions[ 1 ];
-			volume.zLength = volume.dimensions[ 2 ]; // Identify axis order in the space-directions matrix from the header if possible.
+			volume.zLength = volume.dimensions[ 2 ];
 
 
+			// Identify axis order in the space-directions matrix from the header if possible.
 			if ( headerObject.vectors ) {
 			if ( headerObject.vectors ) {
 
 
 				const xIndex = headerObject.vectors.findIndex( vector => vector[ 0 ] !== 0 );
 				const xIndex = headerObject.vectors.findIndex( vector => vector[ 0 ] !== 0 );
@@ -386,17 +366,17 @@
 
 
 				volume.axisOrder = [ 'x', 'y', 'z' ];
 				volume.axisOrder = [ 'x', 'y', 'z' ];
 
 
-			} // spacing
-
+			}
 
 
+			// spacing
 			const spacingX = new THREE.Vector3().fromArray( headerObject.vectors[ 0 ] ).length();
 			const spacingX = new THREE.Vector3().fromArray( headerObject.vectors[ 0 ] ).length();
 			const spacingY = new THREE.Vector3().fromArray( headerObject.vectors[ 1 ] ).length();
 			const spacingY = new THREE.Vector3().fromArray( headerObject.vectors[ 1 ] ).length();
 			const spacingZ = new THREE.Vector3().fromArray( headerObject.vectors[ 2 ] ).length();
 			const spacingZ = new THREE.Vector3().fromArray( headerObject.vectors[ 2 ] ).length();
-			volume.spacing = [ spacingX, spacingY, spacingZ ]; // Create IJKtoRAS matrix
+			volume.spacing = [ spacingX, spacingY, spacingZ ];
 
 
+			// Create IJKtoRAS matrix
 			volume.matrix = new THREE.Matrix4();
 			volume.matrix = new THREE.Matrix4();
 			const transitionMatrix = new THREE.Matrix4();
 			const transitionMatrix = new THREE.Matrix4();
-
 			if ( headerObject.space === 'left-posterior-superior' ) {
 			if ( headerObject.space === 'left-posterior-superior' ) {
 
 
 				transitionMatrix.set( - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
 				transitionMatrix.set( - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
@@ -422,9 +402,10 @@
 
 
 			volume.inverseMatrix = new THREE.Matrix4();
 			volume.inverseMatrix = new THREE.Matrix4();
 			volume.inverseMatrix.copy( volume.matrix ).invert();
 			volume.inverseMatrix.copy( volume.matrix ).invert();
-			volume.RASDimensions = new THREE.Vector3( volume.xLength, volume.yLength, volume.zLength ).applyMatrix4( volume.matrix ).round().toArray().map( Math.abs ); // .. and set the default threshold
-			// only if the threshold was not already set
+			volume.RASDimensions = new THREE.Vector3( volume.xLength, volume.yLength, volume.zLength ).applyMatrix4( volume.matrix ).round().toArray().map( Math.abs );
 
 
+			// .. and set the default threshold
+			// only if the threshold was not already set
 			if ( volume.lowerThreshold === - Infinity ) {
 			if ( volume.lowerThreshold === - Infinity ) {
 
 
 				volume.lowerThreshold = min;
 				volume.lowerThreshold = min;
@@ -440,7 +421,6 @@
 			return volume;
 			return volume;
 
 
 		}
 		}
-
 		parseChars( array, start, end ) {
 		parseChars( array, start, end ) {
 
 
 			// without borders, use the whole array
 			// without borders, use the whole array
@@ -456,10 +436,9 @@
 
 
 			}
 			}
 
 
-			let output = ''; // create and append the chars
-
+			let output = '';
+			// create and append the chars
 			let i = 0;
 			let i = 0;
-
 			for ( i = start; i < end; ++ i ) {
 			for ( i = start; i < end; ++ i ) {
 
 
 				output += String.fromCharCode( array[ i ] );
 				output += String.fromCharCode( array[ i ] );
@@ -471,7 +450,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	const _fieldFunctions = {
 	const _fieldFunctions = {
 		type: function ( data ) {
 		type: function ( data ) {
 
 
@@ -483,13 +461,11 @@
 				case 'uint8_t':
 				case 'uint8_t':
 					this.__array = Uint8Array;
 					this.__array = Uint8Array;
 					break;
 					break;
-
 				case 'signed char':
 				case 'signed char':
 				case 'int8':
 				case 'int8':
 				case 'int8_t':
 				case 'int8_t':
 					this.__array = Int8Array;
 					this.__array = Int8Array;
 					break;
 					break;
-
 				case 'short':
 				case 'short':
 				case 'short int':
 				case 'short int':
 				case 'signed short':
 				case 'signed short':
@@ -498,7 +474,6 @@
 				case 'int16_t':
 				case 'int16_t':
 					this.__array = Int16Array;
 					this.__array = Int16Array;
 					break;
 					break;
-
 				case 'ushort':
 				case 'ushort':
 				case 'unsigned short':
 				case 'unsigned short':
 				case 'unsigned short int':
 				case 'unsigned short int':
@@ -506,29 +481,24 @@
 				case 'uint16_t':
 				case 'uint16_t':
 					this.__array = Uint16Array;
 					this.__array = Uint16Array;
 					break;
 					break;
-
 				case 'int':
 				case 'int':
 				case 'signed int':
 				case 'signed int':
 				case 'int32':
 				case 'int32':
 				case 'int32_t':
 				case 'int32_t':
 					this.__array = Int32Array;
 					this.__array = Int32Array;
 					break;
 					break;
-
 				case 'uint':
 				case 'uint':
 				case 'unsigned int':
 				case 'unsigned int':
 				case 'uint32':
 				case 'uint32':
 				case 'uint32_t':
 				case 'uint32_t':
 					this.__array = Uint32Array;
 					this.__array = Uint32Array;
 					break;
 					break;
-
 				case 'float':
 				case 'float':
 					this.__array = Float32Array;
 					this.__array = Float32Array;
 					break;
 					break;
-
 				case 'double':
 				case 'double':
 					this.__array = Float64Array;
 					this.__array = Float64Array;
 					break;
 					break;
-
 				default:
 				default:
 					throw new Error( 'Unsupported NRRD data type: ' + data );
 					throw new Error( 'Unsupported NRRD data type: ' + data );
 
 
@@ -558,13 +528,10 @@
 			return this.sizes = function () {
 			return this.sizes = function () {
 
 
 				const _ref = data.split( /\s+/ );
 				const _ref = data.split( /\s+/ );
-
 				const _results = [];
 				const _results = [];
-
 				for ( let _i = 0, _len = _ref.length; _i < _len; _i ++ ) {
 				for ( let _i = 0, _len = _ref.length; _i < _len; _i ++ ) {
 
 
 					i = _ref[ _i ];
 					i = _ref[ _i ];
-
 					_results.push( parseInt( i, 10 ) );
 					_results.push( parseInt( i, 10 ) );
 
 
 				}
 				}
@@ -591,21 +558,16 @@
 			return this.vectors = function () {
 			return this.vectors = function () {
 
 
 				const _results = [];
 				const _results = [];
-
 				for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) {
 				for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) {
 
 
 					v = parts[ _i ];
 					v = parts[ _i ];
-
 					_results.push( function () {
 					_results.push( function () {
 
 
 						const _ref = v.slice( 1, - 1 ).split( /,/ );
 						const _ref = v.slice( 1, - 1 ).split( /,/ );
-
 						const _results2 = [];
 						const _results2 = [];
-
 						for ( let _j = 0, _len2 = _ref.length; _j < _len2; _j ++ ) {
 						for ( let _j = 0, _len2 = _ref.length; _j < _len2; _j ++ ) {
 
 
 							f = _ref[ _j ];
 							f = _ref[ _j ];
-
 							_results2.push( parseFloat( f ) );
 							_results2.push( parseFloat( f ) );
 
 
 						}
 						}
@@ -628,11 +590,9 @@
 			return this.spacings = function () {
 			return this.spacings = function () {
 
 
 				const _results = [];
 				const _results = [];
-
 				for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) {
 				for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) {
 
 
 					f = parts[ _i ];
 					f = parts[ _i ];
-
 					_results.push( parseFloat( f ) );
 					_results.push( parseFloat( f ) );
 
 
 				}
 				}

+ 50 - 65
examples/js/loaders/OBJLoader.js

@@ -1,26 +1,20 @@
 ( function () {
 ( function () {
 
 
-	const _object_pattern = /^[og]\s*(.+)?/; // mtllib file_reference
-
-	const _material_library_pattern = /^mtllib /; // usemtl material_name
-
-	const _material_use_pattern = /^usemtl /; // usemap map_name
-
+	// o object_name | g group_name
+	const _object_pattern = /^[og]\s*(.+)?/;
+	// mtllib file_reference
+	const _material_library_pattern = /^mtllib /;
+	// usemtl material_name
+	const _material_use_pattern = /^usemtl /;
+	// usemap map_name
 	const _map_use_pattern = /^usemap /;
 	const _map_use_pattern = /^usemap /;
 	const _face_vertex_data_separator_pattern = /\s+/;
 	const _face_vertex_data_separator_pattern = /\s+/;
-
 	const _vA = new THREE.Vector3();
 	const _vA = new THREE.Vector3();
-
 	const _vB = new THREE.Vector3();
 	const _vB = new THREE.Vector3();
-
 	const _vC = new THREE.Vector3();
 	const _vC = new THREE.Vector3();
-
 	const _ab = new THREE.Vector3();
 	const _ab = new THREE.Vector3();
-
 	const _cb = new THREE.Vector3();
 	const _cb = new THREE.Vector3();
-
 	const _color = new THREE.Color();
 	const _color = new THREE.Color();
-
 	function ParserState() {
 	function ParserState() {
 
 
 		const state = {
 		const state = {
@@ -45,7 +39,6 @@
 				}
 				}
 
 
 				const previousMaterial = this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined;
 				const previousMaterial = this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined;
-
 				if ( this.object && typeof this.object._finalize === 'function' ) {
 				if ( this.object && typeof this.object._finalize === 'function' ) {
 
 
 					this.object._finalize( true );
 					this.object._finalize( true );
@@ -66,10 +59,10 @@
 					smooth: true,
 					smooth: true,
 					startMaterial: function ( name, libraries ) {
 					startMaterial: function ( name, libraries ) {
 
 
-						const previous = this._finalize( false ); // New usemtl declaration overwrites an inherited material, except if faces were declared
-						// after the material, then it must be preserved for proper MultiMaterial continuation.
-
+						const previous = this._finalize( false );
 
 
+						// New usemtl declaration overwrites an inherited material, except if faces were declared
+						// after the material, then it must be preserved for proper MultiMaterial continuation.
 						if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
 						if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
 
 
 							this.materials.splice( previous.index, 1 );
 							this.materials.splice( previous.index, 1 );
@@ -120,16 +113,15 @@
 					_finalize: function ( end ) {
 					_finalize: function ( end ) {
 
 
 						const lastMultiMaterial = this.currentMaterial();
 						const lastMultiMaterial = this.currentMaterial();
-
 						if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
 						if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
 
 
 							lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
 							lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
 							lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
 							lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
 							lastMultiMaterial.inherited = false;
 							lastMultiMaterial.inherited = false;
 
 
-						} // Ignore objects tail materials if no face declarations followed them before a new o/g started.
-
+						}
 
 
+						// Ignore objects tail materials if no face declarations followed them before a new o/g started.
 						if ( end && this.materials.length > 1 ) {
 						if ( end && this.materials.length > 1 ) {
 
 
 							for ( let mi = this.materials.length - 1; mi >= 0; mi -- ) {
 							for ( let mi = this.materials.length - 1; mi >= 0; mi -- ) {
@@ -142,9 +134,9 @@
 
 
 							}
 							}
 
 
-						} // Guarantee at least one empty material, this makes the creation later more straight forward.
-
+						}
 
 
+						// Guarantee at least one empty material, this makes the creation later more straight forward.
 						if ( end && this.materials.length === 0 ) {
 						if ( end && this.materials.length === 0 ) {
 
 
 							this.materials.push( {
 							this.materials.push( {
@@ -157,7 +149,9 @@
 						return lastMultiMaterial;
 						return lastMultiMaterial;
 
 
 					}
 					}
-				}; // Inherit previous objects material.
+				};
+
+				// Inherit previous objects material.
 				// Spec tells us that a declared material must be set to all objects until a new material is declared.
 				// Spec tells us that a declared material must be set to all objects until a new material is declared.
 				// If a usemtl declaration is encountered while this new object is being parsed, it will
 				// If a usemtl declaration is encountered while this new object is being parsed, it will
 				// overwrite the inherited material. Exception being that there was already face declarations
 				// overwrite the inherited material. Exception being that there was already face declarations
@@ -237,21 +231,13 @@
 
 
 				const src = this.vertices;
 				const src = this.vertices;
 				const dst = this.object.geometry.normals;
 				const dst = this.object.geometry.normals;
-
 				_vA.fromArray( src, a );
 				_vA.fromArray( src, a );
-
 				_vB.fromArray( src, b );
 				_vB.fromArray( src, b );
-
 				_vC.fromArray( src, c );
 				_vC.fromArray( src, c );
-
 				_cb.subVectors( _vC, _vB );
 				_cb.subVectors( _vC, _vB );
-
 				_ab.subVectors( _vA, _vB );
 				_ab.subVectors( _vA, _vB );
-
 				_cb.cross( _ab );
 				_cb.cross( _ab );
-
 				_cb.normalize();
 				_cb.normalize();
-
 				dst.push( _cb.x, _cb.y, _cb.z );
 				dst.push( _cb.x, _cb.y, _cb.z );
 				dst.push( _cb.x, _cb.y, _cb.z );
 				dst.push( _cb.x, _cb.y, _cb.z );
 				dst.push( _cb.x, _cb.y, _cb.z );
 				dst.push( _cb.x, _cb.y, _cb.z );
@@ -297,7 +283,9 @@
 				let ib = this.parseVertexIndex( b, vLen );
 				let ib = this.parseVertexIndex( b, vLen );
 				let ic = this.parseVertexIndex( c, vLen );
 				let ic = this.parseVertexIndex( c, vLen );
 				this.addVertex( ia, ib, ic );
 				this.addVertex( ia, ib, ic );
-				this.addColor( ia, ib, ic ); // normals
+				this.addColor( ia, ib, ic );
+
+				// normals
 
 
 				if ( na !== undefined && na !== '' ) {
 				if ( na !== undefined && na !== '' ) {
 
 
@@ -311,8 +299,9 @@
 
 
 					this.addFaceNormal( ia, ib, ic );
 					this.addFaceNormal( ia, ib, ic );
 
 
-				} // uvs
+				}
 
 
+				// uvs
 
 
 				if ( ua !== undefined && ua !== '' ) {
 				if ( ua !== undefined && ua !== '' ) {
 
 
@@ -326,6 +315,7 @@
 				} else {
 				} else {
 
 
 					// add placeholder values (for inconsistent face definitions)
 					// add placeholder values (for inconsistent face definitions)
+
 					this.addDefaultUV();
 					this.addDefaultUV();
 
 
 				}
 				}
@@ -335,7 +325,6 @@
 
 
 				this.object.geometry.type = 'Points';
 				this.object.geometry.type = 'Points';
 				const vLen = this.vertices.length;
 				const vLen = this.vertices.length;
-
 				for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
 				for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
 
 
 					const index = this.parseVertexIndex( vertices[ vi ], vLen );
 					const index = this.parseVertexIndex( vertices[ vi ], vLen );
@@ -350,7 +339,6 @@
 				this.object.geometry.type = 'Line';
 				this.object.geometry.type = 'Line';
 				const vLen = this.vertices.length;
 				const vLen = this.vertices.length;
 				const uvLen = this.uvs.length;
 				const uvLen = this.uvs.length;
-
 				for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
 				for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
 
 
 					this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
 					this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
@@ -368,8 +356,9 @@
 		state.startObject( '', false );
 		state.startObject( '', false );
 		return state;
 		return state;
 
 
-	} //
+	}
 
 
+	//
 
 
 	class OBJLoader extends THREE.Loader {
 	class OBJLoader extends THREE.Loader {
 
 
@@ -379,7 +368,6 @@
 			this.materials = null;
 			this.materials = null;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -412,18 +400,15 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		setMaterials( materials ) {
 		setMaterials( materials ) {
 
 
 			this.materials = materials;
 			this.materials = materials;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		parse( text ) {
 		parse( text ) {
 
 
 			const state = new ParserState();
 			const state = new ParserState();
-
 			if ( text.indexOf( '\r\n' ) !== - 1 ) {
 			if ( text.indexOf( '\r\n' ) !== - 1 ) {
 
 
 				// This is faster than String.split with regex that splits on both
 				// This is faster than String.split with regex that splits on both
@@ -440,43 +425,38 @@
 
 
 			const lines = text.split( '\n' );
 			const lines = text.split( '\n' );
 			let result = [];
 			let result = [];
-
 			for ( let i = 0, l = lines.length; i < l; i ++ ) {
 			for ( let i = 0, l = lines.length; i < l; i ++ ) {
 
 
 				const line = lines[ i ].trimStart();
 				const line = lines[ i ].trimStart();
 				if ( line.length === 0 ) continue;
 				if ( line.length === 0 ) continue;
-				const lineFirstChar = line.charAt( 0 ); // @todo invoke passed in handler if any
+				const lineFirstChar = line.charAt( 0 );
 
 
+				// @todo invoke passed in handler if any
 				if ( lineFirstChar === '#' ) continue;
 				if ( lineFirstChar === '#' ) continue;
-
 				if ( lineFirstChar === 'v' ) {
 				if ( lineFirstChar === 'v' ) {
 
 
 					const data = line.split( _face_vertex_data_separator_pattern );
 					const data = line.split( _face_vertex_data_separator_pattern );
-
 					switch ( data[ 0 ] ) {
 					switch ( data[ 0 ] ) {
 
 
 						case 'v':
 						case 'v':
 							state.vertices.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );
 							state.vertices.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );
-
 							if ( data.length >= 7 ) {
 							if ( data.length >= 7 ) {
 
 
 								_color.setRGB( parseFloat( data[ 4 ] ), parseFloat( data[ 5 ] ), parseFloat( data[ 6 ] ) ).convertSRGBToLinear();
 								_color.setRGB( parseFloat( data[ 4 ] ), parseFloat( data[ 5 ] ), parseFloat( data[ 6 ] ) ).convertSRGBToLinear();
-
 								state.colors.push( _color.r, _color.g, _color.b );
 								state.colors.push( _color.r, _color.g, _color.b );
 
 
 							} else {
 							} else {
 
 
 								// if no colors are defined, add placeholders so color and vertex indices match
 								// if no colors are defined, add placeholders so color and vertex indices match
+
 								state.colors.push( undefined, undefined, undefined );
 								state.colors.push( undefined, undefined, undefined );
 
 
 							}
 							}
 
 
 							break;
 							break;
-
 						case 'vn':
 						case 'vn':
 							state.normals.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );
 							state.normals.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );
 							break;
 							break;
-
 						case 'vt':
 						case 'vt':
 							state.uvs.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ) );
 							state.uvs.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ) );
 							break;
 							break;
@@ -487,12 +467,13 @@
 
 
 					const lineData = line.slice( 1 ).trim();
 					const lineData = line.slice( 1 ).trim();
 					const vertexData = lineData.split( _face_vertex_data_separator_pattern );
 					const vertexData = lineData.split( _face_vertex_data_separator_pattern );
-					const faceVertices = []; // Parse the face vertex data into an easy to work with format
+					const faceVertices = [];
+
+					// Parse the face vertex data into an easy to work with format
 
 
 					for ( let j = 0, jl = vertexData.length; j < jl; j ++ ) {
 					for ( let j = 0, jl = vertexData.length; j < jl; j ++ ) {
 
 
 						const vertex = vertexData[ j ];
 						const vertex = vertexData[ j ];
-
 						if ( vertex.length > 0 ) {
 						if ( vertex.length > 0 ) {
 
 
 							const vertexParts = vertex.split( '/' );
 							const vertexParts = vertex.split( '/' );
@@ -500,11 +481,11 @@
 
 
 						}
 						}
 
 
-					} // Draw an edge between the first vertex and all subsequent vertices to form an n-gon
+					}
 
 
+					// Draw an edge between the first vertex and all subsequent vertices to form an n-gon
 
 
 					const v1 = faceVertices[ 0 ];
 					const v1 = faceVertices[ 0 ];
-
 					for ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {
 					for ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {
 
 
 						const v2 = faceVertices[ j ];
 						const v2 = faceVertices[ j ];
@@ -518,7 +499,6 @@
 					const lineParts = line.substring( 1 ).trim().split( ' ' );
 					const lineParts = line.substring( 1 ).trim().split( ' ' );
 					let lineVertices = [];
 					let lineVertices = [];
 					const lineUVs = [];
 					const lineUVs = [];
-
 					if ( line.indexOf( '/' ) === - 1 ) {
 					if ( line.indexOf( '/' ) === - 1 ) {
 
 
 						lineVertices = lineParts;
 						lineVertices = lineParts;
@@ -548,6 +528,7 @@
 					// o object_name
 					// o object_name
 					// or
 					// or
 					// g group_name
 					// g group_name
+
 					// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
 					// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
 					// let name = result[ 0 ].slice( 1 ).trim();
 					// let name = result[ 0 ].slice( 1 ).trim();
 					const name = ( ' ' + result[ 0 ].slice( 1 ).trim() ).slice( 1 );
 					const name = ( ' ' + result[ 0 ].slice( 1 ).trim() ).slice( 1 );
@@ -556,22 +537,28 @@
 				} else if ( _material_use_pattern.test( line ) ) {
 				} else if ( _material_use_pattern.test( line ) ) {
 
 
 					// material
 					// material
+
 					state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
 					state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
 
 
 				} else if ( _material_library_pattern.test( line ) ) {
 				} else if ( _material_library_pattern.test( line ) ) {
 
 
 					// mtl file
 					// mtl file
+
 					state.materialLibraries.push( line.substring( 7 ).trim() );
 					state.materialLibraries.push( line.substring( 7 ).trim() );
 
 
 				} else if ( _map_use_pattern.test( line ) ) {
 				} else if ( _map_use_pattern.test( line ) ) {
 
 
 					// the line is parsed but ignored since the loader assumes textures are defined MTL files
 					// the line is parsed but ignored since the loader assumes textures are defined MTL files
 					// (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)
 					// (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)
+
 					console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' );
 					console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' );
 
 
 				} else if ( lineFirstChar === 's' ) {
 				} else if ( lineFirstChar === 's' ) {
 
 
-					result = line.split( ' ' ); // smooth shading
+					result = line.split( ' ' );
+
+					// smooth shading
+
 					// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
 					// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
 					// but does not define a usemtl for each face set.
 					// but does not define a usemtl for each face set.
 					// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
 					// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
@@ -588,7 +575,6 @@
         	 * surfaces, smoothing groups are either turned on or off; there is no difference between values greater
         	 * surfaces, smoothing groups are either turned on or off; there is no difference between values greater
         	 * than 0."
         	 * than 0."
         	 */
         	 */
-
 					if ( result.length > 1 ) {
 					if ( result.length > 1 ) {
 
 
 						const value = result[ 1 ].trim().toLowerCase();
 						const value = result[ 1 ].trim().toLowerCase();
@@ -618,7 +604,6 @@
 			const container = new THREE.Group();
 			const container = new THREE.Group();
 			container.materialLibraries = [].concat( state.materialLibraries );
 			container.materialLibraries = [].concat( state.materialLibraries );
 			const hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 );
 			const hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 );
-
 			if ( hasPrimitives === true ) {
 			if ( hasPrimitives === true ) {
 
 
 				for ( let i = 0, l = state.objects.length; i < l; i ++ ) {
 				for ( let i = 0, l = state.objects.length; i < l; i ++ ) {
@@ -628,12 +613,12 @@
 					const materials = object.materials;
 					const materials = object.materials;
 					const isLine = geometry.type === 'Line';
 					const isLine = geometry.type === 'Line';
 					const isPoints = geometry.type === 'Points';
 					const isPoints = geometry.type === 'Points';
-					let hasVertexColors = false; // Skip o/g line declarations that did not follow with any faces
+					let hasVertexColors = false;
 
 
+					// Skip o/g line declarations that did not follow with any faces
 					if ( geometry.vertices.length === 0 ) continue;
 					if ( geometry.vertices.length === 0 ) continue;
 					const buffergeometry = new THREE.BufferGeometry();
 					const buffergeometry = new THREE.BufferGeometry();
 					buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );
 					buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );
-
 					if ( geometry.normals.length > 0 ) {
 					if ( geometry.normals.length > 0 ) {
 
 
 						buffergeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );
 						buffergeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );
@@ -651,21 +636,21 @@
 
 
 						buffergeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );
 						buffergeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );
 
 
-					} // Create materials
+					}
 
 
+					// Create materials
 
 
 					const createdMaterials = [];
 					const createdMaterials = [];
-
 					for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
 					for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
 
 
 						const sourceMaterial = materials[ mi ];
 						const sourceMaterial = materials[ mi ];
 						const materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors;
 						const materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors;
 						let material = state.materials[ materialHash ];
 						let material = state.materials[ materialHash ];
-
 						if ( this.materials !== null ) {
 						if ( this.materials !== null ) {
 
 
-							material = this.materials.create( sourceMaterial.name ); // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
+							material = this.materials.create( sourceMaterial.name );
 
 
+							// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
 							if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {
 							if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {
 
 
 								const materialLine = new THREE.LineBasicMaterial();
 								const materialLine = new THREE.LineBasicMaterial();
@@ -716,11 +701,11 @@
 
 
 						createdMaterials.push( material );
 						createdMaterials.push( material );
 
 
-					} // Create mesh
+					}
 
 
+					// Create mesh
 
 
 					let mesh;
 					let mesh;
-
 					if ( createdMaterials.length > 1 ) {
 					if ( createdMaterials.length > 1 ) {
 
 
 						for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
 						for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
@@ -770,6 +755,7 @@
 			} else {
 			} else {
 
 
 				// if there is only the default parser state object with no geometry data, interpret data as point cloud
 				// if there is only the default parser state object with no geometry data, interpret data as point cloud
+
 				if ( state.vertices.length > 0 ) {
 				if ( state.vertices.length > 0 ) {
 
 
 					const material = new THREE.PointsMaterial( {
 					const material = new THREE.PointsMaterial( {
@@ -778,7 +764,6 @@
 					} );
 					} );
 					const buffergeometry = new THREE.BufferGeometry();
 					const buffergeometry = new THREE.BufferGeometry();
 					buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( state.vertices, 3 ) );
 					buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( state.vertices, 3 ) );
-
 					if ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) {
 					if ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) {
 
 
 						buffergeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( state.colors, 3 ) );
 						buffergeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( state.colors, 3 ) );

+ 34 - 29
examples/js/loaders/PCDLoader.js

@@ -8,7 +8,6 @@
 			this.littleEndian = true;
 			this.littleEndian = true;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -42,10 +41,10 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			// from https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js
 			// from https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js
+
 			function decompressLZF( inData, outLength ) {
 			function decompressLZF( inData, outLength ) {
 
 
 				const inLength = inData.length;
 				const inLength = inData.length;
@@ -55,17 +54,14 @@
 				let ctrl;
 				let ctrl;
 				let len;
 				let len;
 				let ref;
 				let ref;
-
 				do {
 				do {
 
 
 					ctrl = inData[ inPtr ++ ];
 					ctrl = inData[ inPtr ++ ];
-
 					if ( ctrl < 1 << 5 ) {
 					if ( ctrl < 1 << 5 ) {
 
 
 						ctrl ++;
 						ctrl ++;
 						if ( outPtr + ctrl > outLength ) throw new Error( 'Output buffer is not large enough' );
 						if ( outPtr + ctrl > outLength ) throw new Error( 'Output buffer is not large enough' );
 						if ( inPtr + ctrl > inLength ) throw new Error( 'Invalid compressed data' );
 						if ( inPtr + ctrl > inLength ) throw new Error( 'Invalid compressed data' );
-
 						do {
 						do {
 
 
 							outData[ outPtr ++ ] = inData[ inPtr ++ ];
 							outData[ outPtr ++ ] = inData[ inPtr ++ ];
@@ -77,7 +73,6 @@
 						len = ctrl >> 5;
 						len = ctrl >> 5;
 						ref = outPtr - ( ( ctrl & 0x1f ) << 8 ) - 1;
 						ref = outPtr - ( ( ctrl & 0x1f ) << 8 ) - 1;
 						if ( inPtr >= inLength ) throw new Error( 'Invalid compressed data' );
 						if ( inPtr >= inLength ) throw new Error( 'Invalid compressed data' );
-
 						if ( len === 7 ) {
 						if ( len === 7 ) {
 
 
 							len += inData[ inPtr ++ ];
 							len += inData[ inPtr ++ ];
@@ -89,7 +84,6 @@
 						if ( outPtr + len + 2 > outLength ) throw new Error( 'Output buffer is not large enough' );
 						if ( outPtr + len + 2 > outLength ) throw new Error( 'Output buffer is not large enough' );
 						if ( ref < 0 ) throw new Error( 'Invalid compressed data' );
 						if ( ref < 0 ) throw new Error( 'Invalid compressed data' );
 						if ( ref >= outPtr ) throw new Error( 'Invalid compressed data' );
 						if ( ref >= outPtr ) throw new Error( 'Invalid compressed data' );
-
 						do {
 						do {
 
 
 							outData[ outPtr ++ ] = outData[ ref ++ ];
 							outData[ outPtr ++ ] = outData[ ref ++ ];
@@ -111,9 +105,13 @@
 				const result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.slice( result1 - 1 ) );
 				const result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.slice( result1 - 1 ) );
 				PCDheader.data = result2[ 1 ];
 				PCDheader.data = result2[ 1 ];
 				PCDheader.headerLen = result2[ 0 ].length + result1;
 				PCDheader.headerLen = result2[ 0 ].length + result1;
-				PCDheader.str = data.slice( 0, PCDheader.headerLen ); // remove comments
+				PCDheader.str = data.slice( 0, PCDheader.headerLen );
 
 
-				PCDheader.str = PCDheader.str.replace( /\#.*/gi, '' ); // parse
+				// remove comments
+
+				PCDheader.str = PCDheader.str.replace( /\#.*/gi, '' );
+
+				// parse
 
 
 				PCDheader.version = /VERSION (.*)/i.exec( PCDheader.str );
 				PCDheader.version = /VERSION (.*)/i.exec( PCDheader.str );
 				PCDheader.fields = /FIELDS (.*)/i.exec( PCDheader.str );
 				PCDheader.fields = /FIELDS (.*)/i.exec( PCDheader.str );
@@ -123,7 +121,9 @@
 				PCDheader.width = /WIDTH (.*)/i.exec( PCDheader.str );
 				PCDheader.width = /WIDTH (.*)/i.exec( PCDheader.str );
 				PCDheader.height = /HEIGHT (.*)/i.exec( PCDheader.str );
 				PCDheader.height = /HEIGHT (.*)/i.exec( PCDheader.str );
 				PCDheader.viewpoint = /VIEWPOINT (.*)/i.exec( PCDheader.str );
 				PCDheader.viewpoint = /VIEWPOINT (.*)/i.exec( PCDheader.str );
-				PCDheader.points = /POINTS (.*)/i.exec( PCDheader.str ); // evaluate
+				PCDheader.points = /POINTS (.*)/i.exec( PCDheader.str );
+
+				// evaluate
 
 
 				if ( PCDheader.version !== null ) PCDheader.version = parseFloat( PCDheader.version[ 1 ] );
 				if ( PCDheader.version !== null ) PCDheader.version = parseFloat( PCDheader.version[ 1 ] );
 				PCDheader.fields = PCDheader.fields !== null ? PCDheader.fields[ 1 ].split( ' ' ) : [];
 				PCDheader.fields = PCDheader.fields !== null ? PCDheader.fields[ 1 ].split( ' ' ) : [];
@@ -133,7 +133,6 @@
 				if ( PCDheader.viewpoint !== null ) PCDheader.viewpoint = PCDheader.viewpoint[ 1 ];
 				if ( PCDheader.viewpoint !== null ) PCDheader.viewpoint = PCDheader.viewpoint[ 1 ];
 				if ( PCDheader.points !== null ) PCDheader.points = parseInt( PCDheader.points[ 1 ], 10 );
 				if ( PCDheader.points !== null ) PCDheader.points = parseInt( PCDheader.points[ 1 ], 10 );
 				if ( PCDheader.points === null ) PCDheader.points = PCDheader.width * PCDheader.height;
 				if ( PCDheader.points === null ) PCDheader.points = PCDheader.width * PCDheader.height;
-
 				if ( PCDheader.size !== null ) {
 				if ( PCDheader.size !== null ) {
 
 
 					PCDheader.size = PCDheader.size[ 1 ].split( ' ' ).map( function ( x ) {
 					PCDheader.size = PCDheader.size[ 1 ].split( ' ' ).map( function ( x ) {
@@ -155,7 +154,6 @@
 				} else {
 				} else {
 
 
 					PCDheader.count = [];
 					PCDheader.count = [];
-
 					for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
 					for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
 
 
 						PCDheader.count.push( 1 );
 						PCDheader.count.push( 1 );
@@ -166,7 +164,6 @@
 
 
 				PCDheader.offset = {};
 				PCDheader.offset = {};
 				let sizeSum = 0;
 				let sizeSum = 0;
-
 				for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
 				for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
 
 
 					if ( PCDheader.data === 'ascii' ) {
 					if ( PCDheader.data === 'ascii' ) {
@@ -180,35 +177,40 @@
 
 
 					}
 					}
 
 
-				} // for binary only
+				}
 
 
+				// for binary only
 
 
 				PCDheader.rowSize = sizeSum;
 				PCDheader.rowSize = sizeSum;
 				return PCDheader;
 				return PCDheader;
 
 
 			}
 			}
 
 
-			const textData = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); // parse header (always ascii format)
+			const textData = THREE.LoaderUtils.decodeText( new Uint8Array( data ) );
+
+			// parse header (always ascii format)
 
 
-			const PCDheader = parseHeader( textData ); // parse data
+			const PCDheader = parseHeader( textData );
+
+			// parse data
 
 
 			const position = [];
 			const position = [];
 			const normal = [];
 			const normal = [];
 			const color = [];
 			const color = [];
 			const intensity = [];
 			const intensity = [];
-			const label = []; // ascii
+			const label = [];
+
+			// ascii
 
 
 			if ( PCDheader.data === 'ascii' ) {
 			if ( PCDheader.data === 'ascii' ) {
 
 
 				const offset = PCDheader.offset;
 				const offset = PCDheader.offset;
 				const pcdData = textData.slice( PCDheader.headerLen );
 				const pcdData = textData.slice( PCDheader.headerLen );
 				const lines = pcdData.split( '\n' );
 				const lines = pcdData.split( '\n' );
-
 				for ( let i = 0, l = lines.length; i < l; i ++ ) {
 				for ( let i = 0, l = lines.length; i < l; i ++ ) {
 
 
 					if ( lines[ i ] === '' ) continue;
 					if ( lines[ i ] === '' ) continue;
 					const line = lines[ i ].split( ' ' );
 					const line = lines[ i ].split( ' ' );
-
 					if ( offset.x !== undefined ) {
 					if ( offset.x !== undefined ) {
 
 
 						position.push( parseFloat( line[ offset.x ] ) );
 						position.push( parseFloat( line[ offset.x ] ) );
@@ -223,7 +225,6 @@
 						const rgb_type = PCDheader.type[ rgb_field_index ];
 						const rgb_type = PCDheader.type[ rgb_field_index ];
 						const float = parseFloat( line[ offset.rgb ] );
 						const float = parseFloat( line[ offset.rgb ] );
 						let rgb = float;
 						let rgb = float;
-
 						if ( rgb_type === 'F' ) {
 						if ( rgb_type === 'F' ) {
 
 
 							// treat float values as int
 							// treat float values as int
@@ -263,12 +264,14 @@
 
 
 				}
 				}
 
 
-			} // binary-compressed
+			}
+
+			// binary-compressed
+
 			// normally data in PCD files are organized as array of structures: XYZRGBXYZRGB
 			// normally data in PCD files are organized as array of structures: XYZRGBXYZRGB
 			// binary compressed PCD files organize their data as structure of arrays: XXYYZZRGBRGB
 			// binary compressed PCD files organize their data as structure of arrays: XXYYZZRGBRGB
 			// that requires a totally different parsing approach compared to non-compressed data
 			// that requires a totally different parsing approach compared to non-compressed data
 
 
-
 			if ( PCDheader.data === 'binary_compressed' ) {
 			if ( PCDheader.data === 'binary_compressed' ) {
 
 
 				const sizes = new Uint32Array( data.slice( PCDheader.headerLen, PCDheader.headerLen + 8 ) );
 				const sizes = new Uint32Array( data.slice( PCDheader.headerLen, PCDheader.headerLen + 8 ) );
@@ -277,7 +280,6 @@
 				const decompressed = decompressLZF( new Uint8Array( data, PCDheader.headerLen + 8, compressedSize ), decompressedSize );
 				const decompressed = decompressLZF( new Uint8Array( data, PCDheader.headerLen + 8, compressedSize ), decompressedSize );
 				const dataview = new DataView( decompressed.buffer );
 				const dataview = new DataView( decompressed.buffer );
 				const offset = PCDheader.offset;
 				const offset = PCDheader.offset;
-
 				for ( let i = 0; i < PCDheader.points; i ++ ) {
 				for ( let i = 0; i < PCDheader.points; i ++ ) {
 
 
 					if ( offset.x !== undefined ) {
 					if ( offset.x !== undefined ) {
@@ -327,14 +329,14 @@
 
 
 				}
 				}
 
 
-			} // binary
+			}
 
 
+			// binary
 
 
 			if ( PCDheader.data === 'binary' ) {
 			if ( PCDheader.data === 'binary' ) {
 
 
 				const dataview = new DataView( data, PCDheader.headerLen );
 				const dataview = new DataView( data, PCDheader.headerLen );
 				const offset = PCDheader.offset;
 				const offset = PCDheader.offset;
-
 				for ( let i = 0, row = 0; i < PCDheader.points; i ++, row += PCDheader.rowSize ) {
 				for ( let i = 0, row = 0; i < PCDheader.points; i ++, row += PCDheader.rowSize ) {
 
 
 					if ( offset.x !== undefined ) {
 					if ( offset.x !== undefined ) {
@@ -375,8 +377,9 @@
 
 
 				}
 				}
 
 
-			} // build geometry
+			}
 
 
+			// build geometry
 
 
 			const geometry = new THREE.BufferGeometry();
 			const geometry = new THREE.BufferGeometry();
 			if ( position.length > 0 ) geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) );
 			if ( position.length > 0 ) geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) );
@@ -384,18 +387,20 @@
 			if ( color.length > 0 ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) );
 			if ( color.length > 0 ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) );
 			if ( intensity.length > 0 ) geometry.setAttribute( 'intensity', new THREE.Float32BufferAttribute( intensity, 1 ) );
 			if ( intensity.length > 0 ) geometry.setAttribute( 'intensity', new THREE.Float32BufferAttribute( intensity, 1 ) );
 			if ( label.length > 0 ) geometry.setAttribute( 'label', new THREE.Int32BufferAttribute( label, 1 ) );
 			if ( label.length > 0 ) geometry.setAttribute( 'label', new THREE.Int32BufferAttribute( label, 1 ) );
-			geometry.computeBoundingSphere(); // build material
+			geometry.computeBoundingSphere();
+
+			// build material
 
 
 			const material = new THREE.PointsMaterial( {
 			const material = new THREE.PointsMaterial( {
 				size: 0.005
 				size: 0.005
 			} );
 			} );
-
 			if ( color.length > 0 ) {
 			if ( color.length > 0 ) {
 
 
 				material.vertexColors = true;
 				material.vertexColors = true;
 
 
-			} // build point cloud
+			}
 
 
+			// build point cloud
 
 
 			return new THREE.Points( geometry, material );
 			return new THREE.Points( geometry, material );
 
 

+ 17 - 13
examples/js/loaders/PDBLoader.js

@@ -7,7 +7,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -39,8 +38,9 @@
 
 
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
-		} // Based on CanvasMol PDB parser
+		}
 
 
+		// Based on CanvasMol PDB parser
 
 
 		parse( text ) {
 		parse( text ) {
 
 
@@ -65,18 +65,17 @@
 			function parseBond( start, length, satom, i ) {
 			function parseBond( start, length, satom, i ) {
 
 
 				const eatom = parseInt( lines[ i ].slice( start, start + length ) );
 				const eatom = parseInt( lines[ i ].slice( start, start + length ) );
-
 				if ( eatom ) {
 				if ( eatom ) {
 
 
 					const h = hash( satom, eatom );
 					const h = hash( satom, eatom );
-
 					if ( _bhash[ h ] === undefined ) {
 					if ( _bhash[ h ] === undefined ) {
 
 
 						_bonds.push( [ satom - 1, eatom - 1, 1 ] );
 						_bonds.push( [ satom - 1, eatom - 1, 1 ] );
-
 						_bhash[ h ] = _bonds.length - 1;
 						_bhash[ h ] = _bonds.length - 1;
 
 
-					} else { // doesn't really work as almost all PDBs
+					} else {
+
+						// doesn't really work as almost all PDBs
 						// have just normal bonds appearing multiple
 						// have just normal bonds appearing multiple
 						// times instead of being double/triple bonds
 						// times instead of being double/triple bonds
 						// bonds[bhash[h]][2] += 1;
 						// bonds[bhash[h]][2] += 1;
@@ -99,7 +98,9 @@
 				const geometryBonds = build.geometryBonds;
 				const geometryBonds = build.geometryBonds;
 				const verticesAtoms = [];
 				const verticesAtoms = [];
 				const colorsAtoms = [];
 				const colorsAtoms = [];
-				const verticesBonds = []; // atoms
+				const verticesBonds = [];
+
+				// atoms
 
 
 				for ( let i = 0, l = atoms.length; i < l; i ++ ) {
 				for ( let i = 0, l = atoms.length; i < l; i ++ ) {
 
 
@@ -113,8 +114,9 @@
 					const b = atom[ 3 ][ 2 ] / 255;
 					const b = atom[ 3 ][ 2 ] / 255;
 					colorsAtoms.push( r, g, b );
 					colorsAtoms.push( r, g, b );
 
 
-				} // bonds
+				}
 
 
+				// bonds
 
 
 				for ( let i = 0, l = _bonds.length; i < l; i ++ ) {
 				for ( let i = 0, l = _bonds.length; i < l; i ++ ) {
 
 
@@ -132,8 +134,9 @@
 					z = endAtom[ 2 ];
 					z = endAtom[ 2 ];
 					verticesBonds.push( x, y, z );
 					verticesBonds.push( x, y, z );
 
 
-				} // build geometry
+				}
 
 
+				// build geometry
 
 
 				geometryAtoms.setAttribute( 'position', new THREE.Float32BufferAttribute( verticesAtoms, 3 ) );
 				geometryAtoms.setAttribute( 'position', new THREE.Float32BufferAttribute( verticesAtoms, 3 ) );
 				geometryAtoms.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsAtoms, 3 ) );
 				geometryAtoms.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsAtoms, 3 ) );
@@ -265,10 +268,11 @@
 			const atoms = [];
 			const atoms = [];
 			const _bonds = [];
 			const _bonds = [];
 			const _bhash = {};
 			const _bhash = {};
-			const _atomMap = {}; // parse
+			const _atomMap = {};
 
 
-			const lines = text.split( '\n' );
+			// parse
 
 
+			const lines = text.split( '\n' );
 			for ( let i = 0, l = lines.length; i < l; i ++ ) {
 			for ( let i = 0, l = lines.length; i < l; i ++ ) {
 
 
 				if ( lines[ i ].slice( 0, 4 ) === 'ATOM' || lines[ i ].slice( 0, 6 ) === 'HETATM' ) {
 				if ( lines[ i ].slice( 0, 4 ) === 'ATOM' || lines[ i ].slice( 0, 6 ) === 'HETATM' ) {
@@ -278,7 +282,6 @@
 					const z = parseFloat( lines[ i ].slice( 46, 53 ) );
 					const z = parseFloat( lines[ i ].slice( 46, 53 ) );
 					const index = parseInt( lines[ i ].slice( 6, 11 ) ) - 1;
 					const index = parseInt( lines[ i ].slice( 6, 11 ) ) - 1;
 					let e = trim( lines[ i ].slice( 76, 78 ) ).toLowerCase();
 					let e = trim( lines[ i ].slice( 76, 78 ) ).toLowerCase();
-
 					if ( e === '' ) {
 					if ( e === '' ) {
 
 
 						e = trim( lines[ i ].slice( 12, 14 ) ).toLowerCase();
 						e = trim( lines[ i ].slice( 12, 14 ) ).toLowerCase();
@@ -299,8 +302,9 @@
 
 
 				}
 				}
 
 
-			} // build and return geometry
+			}
 
 
+			// build and return geometry
 
 
 			return buildGeometry();
 			return buildGeometry();
 
 

+ 9 - 39
examples/js/loaders/PLYLoader.js

@@ -27,7 +27,6 @@
  */
  */
 
 
 	const _color = new THREE.Color();
 	const _color = new THREE.Color();
-
 	class PLYLoader extends THREE.Loader {
 	class PLYLoader extends THREE.Loader {
 
 
 		constructor( manager ) {
 		constructor( manager ) {
@@ -36,7 +35,6 @@
 			this.propertyNameMapping = {};
 			this.propertyNameMapping = {};
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -70,13 +68,11 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		setPropertyNameMapping( mapping ) {
 		setPropertyNameMapping( mapping ) {
 
 
 			this.propertyNameMapping = mapping;
 			this.propertyNameMapping = mapping;
 
 
 		}
 		}
-
 		parse( data ) {
 		parse( data ) {
 
 
 			function parseHeader( data ) {
 			function parseHeader( data ) {
@@ -85,7 +81,6 @@
 				let headerText = '';
 				let headerText = '';
 				let headerLength = 0;
 				let headerLength = 0;
 				const result = patternHeader.exec( data );
 				const result = patternHeader.exec( data );
-
 				if ( result !== null ) {
 				if ( result !== null ) {
 
 
 					headerText = result[ 1 ];
 					headerText = result[ 1 ];
@@ -101,13 +96,11 @@
 				};
 				};
 				const lines = headerText.split( /\r\n|\r|\n/ );
 				const lines = headerText.split( /\r\n|\r|\n/ );
 				let currentElement;
 				let currentElement;
-
 				function make_ply_element_property( propertValues, propertyNameMapping ) {
 				function make_ply_element_property( propertValues, propertyNameMapping ) {
 
 
 					const property = {
 					const property = {
 						type: propertValues[ 0 ]
 						type: propertValues[ 0 ]
 					};
 					};
-
 					if ( property.type === 'list' ) {
 					if ( property.type === 'list' ) {
 
 
 						property.name = propertValues[ 3 ];
 						property.name = propertValues[ 3 ];
@@ -138,18 +131,15 @@
 					const lineValues = line.split( /\s+/ );
 					const lineValues = line.split( /\s+/ );
 					const lineType = lineValues.shift();
 					const lineType = lineValues.shift();
 					line = lineValues.join( ' ' );
 					line = lineValues.join( ' ' );
-
 					switch ( lineType ) {
 					switch ( lineType ) {
 
 
 						case 'format':
 						case 'format':
 							header.format = lineValues[ 0 ];
 							header.format = lineValues[ 0 ];
 							header.version = lineValues[ 1 ];
 							header.version = lineValues[ 1 ];
 							break;
 							break;
-
 						case 'comment':
 						case 'comment':
 							header.comments.push( line );
 							header.comments.push( line );
 							break;
 							break;
-
 						case 'element':
 						case 'element':
 							if ( currentElement !== undefined ) {
 							if ( currentElement !== undefined ) {
 
 
@@ -162,15 +152,12 @@
 							currentElement.count = parseInt( lineValues[ 1 ] );
 							currentElement.count = parseInt( lineValues[ 1 ] );
 							currentElement.properties = [];
 							currentElement.properties = [];
 							break;
 							break;
-
 						case 'property':
 						case 'property':
 							currentElement.properties.push( make_ply_element_property( lineValues, scope.propertyNameMapping ) );
 							currentElement.properties.push( make_ply_element_property( lineValues, scope.propertyNameMapping ) );
 							break;
 							break;
-
 						case 'obj_info':
 						case 'obj_info':
 							header.objInfo = line;
 							header.objInfo = line;
 							break;
 							break;
-
 						default:
 						default:
 							console.log( 'unhandled', lineType, lineValues );
 							console.log( 'unhandled', lineType, lineValues );
 
 
@@ -205,7 +192,6 @@
 					case 'int32':
 					case 'int32':
 					case 'uint32':
 					case 'uint32':
 						return parseInt( n );
 						return parseInt( n );
-
 					case 'float':
 					case 'float':
 					case 'double':
 					case 'double':
 					case 'float32':
 					case 'float32':
@@ -220,14 +206,12 @@
 
 
 				const values = line.split( /\s+/ );
 				const values = line.split( /\s+/ );
 				const element = {};
 				const element = {};
-
 				for ( let i = 0; i < properties.length; i ++ ) {
 				for ( let i = 0; i < properties.length; i ++ ) {
 
 
 					if ( properties[ i ].type === 'list' ) {
 					if ( properties[ i ].type === 'list' ) {
 
 
 						const list = [];
 						const list = [];
 						const n = parseASCIINumber( values.shift(), properties[ i ].countType );
 						const n = parseASCIINumber( values.shift(), properties[ i ].countType );
-
 						for ( let j = 0; j < n; j ++ ) {
 						for ( let j = 0; j < n; j ++ ) {
 
 
 							list.push( parseASCIINumber( values.shift(), properties[ i ].itemType ) );
 							list.push( parseASCIINumber( values.shift(), properties[ i ].itemType ) );
@@ -251,6 +235,7 @@
 			function parseASCII( data, header ) {
 			function parseASCII( data, header ) {
 
 
 				// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
 				// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
+
 				const buffer = {
 				const buffer = {
 					indices: [],
 					indices: [],
 					vertices: [],
 					vertices: [],
@@ -262,7 +247,6 @@
 				let result;
 				let result;
 				const patternBody = /end_header\s([\s\S]*)$/;
 				const patternBody = /end_header\s([\s\S]*)$/;
 				let body = '';
 				let body = '';
-
 				if ( ( result = patternBody.exec( data ) ) !== null ) {
 				if ( ( result = patternBody.exec( data ) ) !== null ) {
 
 
 					body = result[ 1 ];
 					body = result[ 1 ];
@@ -272,12 +256,10 @@
 				const lines = body.split( /\r\n|\r|\n/ );
 				const lines = body.split( /\r\n|\r|\n/ );
 				let currentElement = 0;
 				let currentElement = 0;
 				let currentElementCount = 0;
 				let currentElementCount = 0;
-
 				for ( let i = 0; i < lines.length; i ++ ) {
 				for ( let i = 0; i < lines.length; i ++ ) {
 
 
 					let line = lines[ i ];
 					let line = lines[ i ];
 					line = line.trim();
 					line = line.trim();
-
 					if ( line === '' ) {
 					if ( line === '' ) {
 
 
 						continue;
 						continue;
@@ -303,7 +285,9 @@
 
 
 			function postProcess( buffer ) {
 			function postProcess( buffer ) {
 
 
-				let geometry = new THREE.BufferGeometry(); // mandatory buffer data
+				let geometry = new THREE.BufferGeometry();
+
+				// mandatory buffer data
 
 
 				if ( buffer.indices.length > 0 ) {
 				if ( buffer.indices.length > 0 ) {
 
 
@@ -311,7 +295,9 @@
 
 
 				}
 				}
 
 
-				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) ); // optional buffer data
+				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) );
+
+				// optional buffer data
 
 
 				if ( buffer.normals.length > 0 ) {
 				if ( buffer.normals.length > 0 ) {
 
 
@@ -369,11 +355,9 @@
 				const attrR = findAttrName( [ 'red', 'diffuse_red', 'r', 'diffuse_r' ] );
 				const attrR = findAttrName( [ 'red', 'diffuse_red', 'r', 'diffuse_r' ] );
 				const attrG = findAttrName( [ 'green', 'diffuse_green', 'g', 'diffuse_g' ] );
 				const attrG = findAttrName( [ 'green', 'diffuse_green', 'g', 'diffuse_g' ] );
 				const attrB = findAttrName( [ 'blue', 'diffuse_blue', 'b', 'diffuse_b' ] );
 				const attrB = findAttrName( [ 'blue', 'diffuse_blue', 'b', 'diffuse_b' ] );
-
 				if ( elementName === 'vertex' ) {
 				if ( elementName === 'vertex' ) {
 
 
 					buffer.vertices.push( element[ attrX ], element[ attrY ], element[ attrZ ] );
 					buffer.vertices.push( element[ attrX ], element[ attrY ], element[ attrZ ] );
-
 					if ( attrNX !== null && attrNY !== null && attrNZ !== null ) {
 					if ( attrNX !== null && attrNY !== null && attrNZ !== null ) {
 
 
 						buffer.normals.push( element[ attrNX ], element[ attrNY ], element[ attrNZ ] );
 						buffer.normals.push( element[ attrNX ], element[ attrNY ], element[ attrNZ ] );
@@ -389,7 +373,6 @@
 					if ( attrR !== null && attrG !== null && attrB !== null ) {
 					if ( attrR !== null && attrG !== null && attrB !== null ) {
 
 
 						_color.setRGB( element[ attrR ] / 255.0, element[ attrG ] / 255.0, element[ attrB ] / 255.0 ).convertSRGBToLinear();
 						_color.setRGB( element[ attrR ] / 255.0, element[ attrG ] / 255.0, element[ attrB ] / 255.0 ).convertSRGBToLinear();
-
 						buffer.colors.push( _color.r, _color.g, _color.b );
 						buffer.colors.push( _color.r, _color.g, _color.b );
 
 
 					}
 					}
@@ -397,13 +380,10 @@
 				} else if ( elementName === 'face' ) {
 				} else if ( elementName === 'face' ) {
 
 
 					const vertex_indices = element.vertex_indices || element.vertex_index; // issue #9338
 					const vertex_indices = element.vertex_indices || element.vertex_index; // issue #9338
-
 					const texcoord = element.texcoord;
 					const texcoord = element.texcoord;
-
 					if ( vertex_indices.length === 3 ) {
 					if ( vertex_indices.length === 3 ) {
 
 
 						buffer.indices.push( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 2 ] );
 						buffer.indices.push( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 2 ] );
-
 						if ( texcoord && texcoord.length === 6 ) {
 						if ( texcoord && texcoord.length === 6 ) {
 
 
 							buffer.faceVertexUvs.push( texcoord[ 0 ], texcoord[ 1 ] );
 							buffer.faceVertexUvs.push( texcoord[ 0 ], texcoord[ 1 ] );
@@ -431,31 +411,24 @@
 					case 'int8':
 					case 'int8':
 					case 'char':
 					case 'char':
 						return [ dataview.getInt8( at ), 1 ];
 						return [ dataview.getInt8( at ), 1 ];
-
 					case 'uint8':
 					case 'uint8':
 					case 'uchar':
 					case 'uchar':
 						return [ dataview.getUint8( at ), 1 ];
 						return [ dataview.getUint8( at ), 1 ];
-
 					case 'int16':
 					case 'int16':
 					case 'short':
 					case 'short':
 						return [ dataview.getInt16( at, little_endian ), 2 ];
 						return [ dataview.getInt16( at, little_endian ), 2 ];
-
 					case 'uint16':
 					case 'uint16':
 					case 'ushort':
 					case 'ushort':
 						return [ dataview.getUint16( at, little_endian ), 2 ];
 						return [ dataview.getUint16( at, little_endian ), 2 ];
-
 					case 'int32':
 					case 'int32':
 					case 'int':
 					case 'int':
 						return [ dataview.getInt32( at, little_endian ), 4 ];
 						return [ dataview.getInt32( at, little_endian ), 4 ];
-
 					case 'uint32':
 					case 'uint32':
 					case 'uint':
 					case 'uint':
 						return [ dataview.getUint32( at, little_endian ), 4 ];
 						return [ dataview.getUint32( at, little_endian ), 4 ];
-
 					case 'float32':
 					case 'float32':
 					case 'float':
 					case 'float':
 						return [ dataview.getFloat32( at, little_endian ), 4 ];
 						return [ dataview.getFloat32( at, little_endian ), 4 ];
-
 					case 'float64':
 					case 'float64':
 					case 'double':
 					case 'double':
 						return [ dataview.getFloat64( at, little_endian ), 8 ];
 						return [ dataview.getFloat64( at, little_endian ), 8 ];
@@ -469,7 +442,6 @@
 				const element = {};
 				const element = {};
 				let result,
 				let result,
 					read = 0;
 					read = 0;
-
 				for ( let i = 0; i < properties.length; i ++ ) {
 				for ( let i = 0; i < properties.length; i ++ ) {
 
 
 					if ( properties[ i ].type === 'list' ) {
 					if ( properties[ i ].type === 'list' ) {
@@ -478,7 +450,6 @@
 						result = binaryRead( dataview, at + read, properties[ i ].countType, little_endian );
 						result = binaryRead( dataview, at + read, properties[ i ].countType, little_endian );
 						const n = result[ 0 ];
 						const n = result[ 0 ];
 						read += result[ 1 ];
 						read += result[ 1 ];
-
 						for ( let j = 0; j < n; j ++ ) {
 						for ( let j = 0; j < n; j ++ ) {
 
 
 							result = binaryRead( dataview, at + read, properties[ i ].itemType, little_endian );
 							result = binaryRead( dataview, at + read, properties[ i ].itemType, little_endian );
@@ -517,7 +488,6 @@
 				const body = new DataView( data, header.headerLength );
 				const body = new DataView( data, header.headerLength );
 				let result,
 				let result,
 					loc = 0;
 					loc = 0;
-
 				for ( let currentElement = 0; currentElement < header.elements.length; currentElement ++ ) {
 				for ( let currentElement = 0; currentElement < header.elements.length; currentElement ++ ) {
 
 
 					for ( let currentElementCount = 0; currentElementCount < header.elements[ currentElement ].count; currentElementCount ++ ) {
 					for ( let currentElementCount = 0; currentElementCount < header.elements[ currentElement ].count; currentElementCount ++ ) {
@@ -533,12 +503,12 @@
 
 
 				return postProcess( buffer );
 				return postProcess( buffer );
 
 
-			} //
+			}
 
 
+			//
 
 
 			let geometry;
 			let geometry;
 			const scope = this;
 			const scope = this;
-
 			if ( data instanceof ArrayBuffer ) {
 			if ( data instanceof ArrayBuffer ) {
 
 
 				const text = THREE.LoaderUtils.decodeText( new Uint8Array( data ) );
 				const text = THREE.LoaderUtils.decodeText( new Uint8Array( data ) );

+ 11 - 22
examples/js/loaders/PRWMLoader.js

@@ -5,11 +5,11 @@
  */
  */
 
 
 	let bigEndianPlatform = null;
 	let bigEndianPlatform = null;
+
 	/**
 	/**
 	 * Check if the endianness of the platform is big-endian (most significant bit first)
 	 * Check if the endianness of the platform is big-endian (most significant bit first)
 	 * @returns {boolean} True if big-endian, false if little-endian
 	 * @returns {boolean} True if big-endian, false if little-endian
 	 */
 	 */
-
 	function isBigEndianPlatform() {
 	function isBigEndianPlatform() {
 
 
 		if ( bigEndianPlatform === null ) {
 		if ( bigEndianPlatform === null ) {
@@ -18,20 +18,19 @@
 				uint8Array = new Uint8Array( buffer ),
 				uint8Array = new Uint8Array( buffer ),
 				uint16Array = new Uint16Array( buffer );
 				uint16Array = new Uint16Array( buffer );
 			uint8Array[ 0 ] = 0xAA; // set first byte
 			uint8Array[ 0 ] = 0xAA; // set first byte
-
 			uint8Array[ 1 ] = 0xBB; // set second byte
 			uint8Array[ 1 ] = 0xBB; // set second byte
-
 			bigEndianPlatform = uint16Array[ 0 ] === 0xAABB;
 			bigEndianPlatform = uint16Array[ 0 ] === 0xAABB;
 
 
 		}
 		}
 
 
 		return bigEndianPlatform;
 		return bigEndianPlatform;
 
 
-	} // match the values defined in the spec to the TypedArray types
-
+	}
 
 
-	const InvertedEncodingTypes = [ null, Float32Array, null, Int8Array, Int16Array, null, Int32Array, Uint8Array, Uint16Array, null, Uint32Array ]; // define the method to use on a DataView, corresponding the TypedArray type
+	// match the values defined in the spec to the TypedArray types
+	const InvertedEncodingTypes = [ null, Float32Array, null, Int8Array, Int16Array, null, Int32Array, Uint8Array, Uint16Array, null, Uint32Array ];
 
 
+	// define the method to use on a DataView, corresponding the TypedArray type
 	const getMethods = {
 	const getMethods = {
 		Uint16Array: 'getUint16',
 		Uint16Array: 'getUint16',
 		Uint32Array: 'getUint32',
 		Uint32Array: 'getUint32',
@@ -40,12 +39,10 @@
 		Float32Array: 'getFloat32',
 		Float32Array: 'getFloat32',
 		Float64Array: 'getFloat64'
 		Float64Array: 'getFloat64'
 	};
 	};
-
 	function copyFromBuffer( sourceArrayBuffer, viewType, position, length, fromBigEndian ) {
 	function copyFromBuffer( sourceArrayBuffer, viewType, position, length, fromBigEndian ) {
 
 
 		const bytesPerElement = viewType.BYTES_PER_ELEMENT;
 		const bytesPerElement = viewType.BYTES_PER_ELEMENT;
 		let result;
 		let result;
-
 		if ( fromBigEndian === isBigEndianPlatform() || bytesPerElement === 1 ) {
 		if ( fromBigEndian === isBigEndianPlatform() || bytesPerElement === 1 ) {
 
 
 			result = new viewType( sourceArrayBuffer, position, length );
 			result = new viewType( sourceArrayBuffer, position, length );
@@ -56,7 +53,6 @@
 				getMethod = getMethods[ viewType.name ],
 				getMethod = getMethods[ viewType.name ],
 				littleEndian = ! fromBigEndian;
 				littleEndian = ! fromBigEndian;
 			result = new viewType( length );
 			result = new viewType( length );
-
 			for ( let i = 0; i < length; i ++ ) {
 			for ( let i = 0; i < length; i ++ ) {
 
 
 				result[ i ] = readView[ getMethod ]( i * bytesPerElement, littleEndian );
 				result[ i ] = readView[ getMethod ]( i * bytesPerElement, littleEndian );
@@ -80,7 +76,6 @@
 			attributesNumber = flags & 0x1F;
 			attributesNumber = flags & 0x1F;
 		let valuesNumber = 0,
 		let valuesNumber = 0,
 			indicesNumber = 0;
 			indicesNumber = 0;
-
 		if ( bigEndian ) {
 		if ( bigEndian ) {
 
 
 			valuesNumber = ( array[ 2 ] << 16 ) + ( array[ 3 ] << 8 ) + array[ 4 ];
 			valuesNumber = ( array[ 2 ] << 16 ) + ( array[ 3 ] << 8 ) + array[ 4 ];
@@ -92,8 +87,8 @@
 			indicesNumber = array[ 5 ] + ( array[ 6 ] << 8 ) + ( array[ 7 ] << 16 );
 			indicesNumber = array[ 5 ] + ( array[ 6 ] << 8 ) + ( array[ 7 ] << 16 );
 
 
 		}
 		}
-		/** PRELIMINARY CHECKS **/
 
 
+		/** PRELIMINARY CHECKS **/
 
 
 		if ( version === 0 ) {
 		if ( version === 0 ) {
 
 
@@ -118,21 +113,18 @@
 			}
 			}
 
 
 		}
 		}
-		/** PARSING **/
 
 
+		/** PARSING **/
 
 
 		let pos = 8;
 		let pos = 8;
 		const attributes = {};
 		const attributes = {};
-
 		for ( let i = 0; i < attributesNumber; i ++ ) {
 		for ( let i = 0; i < attributesNumber; i ++ ) {
 
 
 			let attributeName = '';
 			let attributeName = '';
-
 			while ( pos < array.length ) {
 			while ( pos < array.length ) {
 
 
 				const char = array[ pos ];
 				const char = array[ pos ];
 				pos ++;
 				pos ++;
-
 				if ( char === 0 ) {
 				if ( char === 0 ) {
 
 
 					break;
 					break;
@@ -150,8 +142,9 @@
 			const cardinality = ( flags >> 4 & 0x03 ) + 1;
 			const cardinality = ( flags >> 4 & 0x03 ) + 1;
 			const encodingType = flags & 0x0F;
 			const encodingType = flags & 0x0F;
 			const arrayType = InvertedEncodingTypes[ encodingType ];
 			const arrayType = InvertedEncodingTypes[ encodingType ];
-			pos ++; // padding to next multiple of 4
+			pos ++;
 
 
+			// padding to next multiple of 4
 			pos = Math.ceil( pos / 4 ) * 4;
 			pos = Math.ceil( pos / 4 ) * 4;
 			const values = copyFromBuffer( buffer, arrayType, pos, cardinality * valuesNumber, bigEndian );
 			const values = copyFromBuffer( buffer, arrayType, pos, cardinality * valuesNumber, bigEndian );
 			pos += arrayType.BYTES_PER_ELEMENT * cardinality * valuesNumber;
 			pos += arrayType.BYTES_PER_ELEMENT * cardinality * valuesNumber;
@@ -165,7 +158,6 @@
 
 
 		pos = Math.ceil( pos / 4 ) * 4;
 		pos = Math.ceil( pos / 4 ) * 4;
 		let indices = null;
 		let indices = null;
-
 		if ( indexedGeometry ) {
 		if ( indexedGeometry ) {
 
 
 			indices = copyFromBuffer( buffer, indicesType === 1 ? Uint32Array : Uint16Array, pos, indicesNumber, bigEndian );
 			indices = copyFromBuffer( buffer, indicesType === 1 ? Uint32Array : Uint16Array, pos, indicesNumber, bigEndian );
@@ -178,8 +170,9 @@
 			indices: indices
 			indices: indices
 		};
 		};
 
 
-	} // Define the public interface
+	}
 
 
+	// Define the public interface
 
 
 	class PRWMLoader extends THREE.Loader {
 	class PRWMLoader extends THREE.Loader {
 
 
@@ -188,7 +181,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			const scope = this;
 			const scope = this;
@@ -223,13 +215,11 @@
 			}, onProgress, onError );
 			}, onProgress, onError );
 
 
 		}
 		}
-
 		parse( arrayBuffer ) {
 		parse( arrayBuffer ) {
 
 
 			const data = decodePrwm( arrayBuffer ),
 			const data = decodePrwm( arrayBuffer ),
 				attributesKey = Object.keys( data.attributes ),
 				attributesKey = Object.keys( data.attributes ),
 				bufferGeometry = new THREE.BufferGeometry();
 				bufferGeometry = new THREE.BufferGeometry();
-
 			for ( let i = 0; i < attributesKey.length; i ++ ) {
 			for ( let i = 0; i < attributesKey.length; i ++ ) {
 
 
 				const attribute = data.attributes[ attributesKey[ i ] ];
 				const attribute = data.attributes[ attributesKey[ i ] ];
@@ -246,7 +236,6 @@
 			return bufferGeometry;
 			return bufferGeometry;
 
 
 		}
 		}
-
 		static isBigEndianPlatform() {
 		static isBigEndianPlatform() {
 
 
 			return isBigEndianPlatform();
 			return isBigEndianPlatform();

+ 7 - 16
examples/js/loaders/PVRLoader.js

@@ -13,7 +13,6 @@
 			super( manager );
 			super( manager );
 
 
 		}
 		}
-
 		parse( buffer, loadMipmaps ) {
 		parse( buffer, loadMipmaps ) {
 
 
 			const headerLengthInt = 13;
 			const headerLengthInt = 13;
@@ -23,15 +22,16 @@
 				header: header,
 				header: header,
 				loadMipmaps: loadMipmaps
 				loadMipmaps: loadMipmaps
 			};
 			};
-
 			if ( header[ 0 ] === 0x03525650 ) {
 			if ( header[ 0 ] === 0x03525650 ) {
 
 
 				// PVR v3
 				// PVR v3
+
 				return _parseV3( pvrDatas );
 				return _parseV3( pvrDatas );
 
 
 			} else if ( header[ 11 ] === 0x21525650 ) {
 			} else if ( header[ 11 ] === 0x21525650 ) {
 
 
 				// PVR v2
 				// PVR v2
+
 				return _parseV2( pvrDatas );
 				return _parseV2( pvrDatas );
 
 
 			} else {
 			} else {
@@ -43,7 +43,6 @@
 		}
 		}
 
 
 	}
 	}
-
 	function _parseV3( pvrDatas ) {
 	function _parseV3( pvrDatas ) {
 
 
 		const header = pvrDatas.header;
 		const header = pvrDatas.header;
@@ -55,7 +54,6 @@
 			// numSurfs = header[ 9 ],
 			// numSurfs = header[ 9 ],
 			numFaces = header[ 10 ],
 			numFaces = header[ 10 ],
 			numMipmaps = header[ 11 ];
 			numMipmaps = header[ 11 ];
-
 		switch ( pixelFormat ) {
 		switch ( pixelFormat ) {
 
 
 			case 0:
 			case 0:
@@ -63,25 +61,21 @@
 				bpp = 2;
 				bpp = 2;
 				format = THREE.RGB_PVRTC_2BPPV1_Format;
 				format = THREE.RGB_PVRTC_2BPPV1_Format;
 				break;
 				break;
-
 			case 1:
 			case 1:
 				// PVRTC 2bpp RGBA
 				// PVRTC 2bpp RGBA
 				bpp = 2;
 				bpp = 2;
 				format = THREE.RGBA_PVRTC_2BPPV1_Format;
 				format = THREE.RGBA_PVRTC_2BPPV1_Format;
 				break;
 				break;
-
 			case 2:
 			case 2:
 				// PVRTC 4bpp RGB
 				// PVRTC 4bpp RGB
 				bpp = 4;
 				bpp = 4;
 				format = THREE.RGB_PVRTC_4BPPV1_Format;
 				format = THREE.RGB_PVRTC_4BPPV1_Format;
 				break;
 				break;
-
 			case 3:
 			case 3:
 				// PVRTC 4bpp RGBA
 				// PVRTC 4bpp RGBA
 				bpp = 4;
 				bpp = 4;
 				format = THREE.RGBA_PVRTC_4BPPV1_Format;
 				format = THREE.RGBA_PVRTC_4BPPV1_Format;
 				break;
 				break;
-
 			default:
 			default:
 				console.error( 'THREE.PVRLoader: Unsupported PVR format:', pixelFormat );
 				console.error( 'THREE.PVRLoader: Unsupported PVR format:', pixelFormat );
 
 
@@ -120,9 +114,7 @@
 			PVRTC_4 = 25;
 			PVRTC_4 = 25;
 		const formatFlags = flags & TYPE_MASK;
 		const formatFlags = flags & TYPE_MASK;
 		let bpp, format;
 		let bpp, format;
-
 		const _hasAlpha = bitmaskAlpha > 0;
 		const _hasAlpha = bitmaskAlpha > 0;
-
 		if ( formatFlags === PVRTC_4 ) {
 		if ( formatFlags === PVRTC_4 ) {
 
 
 			format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format;
 			format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format;
@@ -145,9 +137,10 @@
 		pvrDatas.width = width;
 		pvrDatas.width = width;
 		pvrDatas.height = height;
 		pvrDatas.height = height;
 		pvrDatas.numSurfaces = numSurfs;
 		pvrDatas.numSurfaces = numSurfs;
-		pvrDatas.numMipmaps = numMipmaps + 1; // guess cubemap type seems tricky in v2
-		// it juste a pvr containing 6 surface (no explicit cubemap type)
+		pvrDatas.numMipmaps = numMipmaps + 1;
 
 
+		// guess cubemap type seems tricky in v2
+		// it juste a pvr containing 6 surface (no explicit cubemap type)
 		pvrDatas.isCubemap = numSurfs === 6;
 		pvrDatas.isCubemap = numSurfs === 6;
 		return _extract( pvrDatas );
 		return _extract( pvrDatas );
 
 
@@ -173,7 +166,6 @@
 			heightBlocks = 0;
 			heightBlocks = 0;
 		const bpp = pvrDatas.bpp,
 		const bpp = pvrDatas.bpp,
 			numSurfs = pvrDatas.numSurfaces;
 			numSurfs = pvrDatas.numSurfaces;
-
 		if ( bpp === 2 ) {
 		if ( bpp === 2 ) {
 
 
 			blockWidth = 8;
 			blockWidth = 8;
@@ -189,18 +181,17 @@
 		blockSize = blockWidth * blockHeight * bpp / 8;
 		blockSize = blockWidth * blockHeight * bpp / 8;
 		pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs;
 		pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs;
 		let mipLevel = 0;
 		let mipLevel = 0;
-
 		while ( mipLevel < pvrDatas.numMipmaps ) {
 		while ( mipLevel < pvrDatas.numMipmaps ) {
 
 
 			const sWidth = pvrDatas.width >> mipLevel,
 			const sWidth = pvrDatas.width >> mipLevel,
 				sHeight = pvrDatas.height >> mipLevel;
 				sHeight = pvrDatas.height >> mipLevel;
 			widthBlocks = sWidth / blockWidth;
 			widthBlocks = sWidth / blockWidth;
-			heightBlocks = sHeight / blockHeight; // Clamp to minimum number of blocks
+			heightBlocks = sHeight / blockHeight;
 
 
+			// Clamp to minimum number of blocks
 			if ( widthBlocks < 2 ) widthBlocks = 2;
 			if ( widthBlocks < 2 ) widthBlocks = 2;
 			if ( heightBlocks < 2 ) heightBlocks = 2;
 			if ( heightBlocks < 2 ) heightBlocks = 2;
 			dataSize = widthBlocks * heightBlocks * blockSize;
 			dataSize = widthBlocks * heightBlocks * blockSize;
-
 			for ( let surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
 			for ( let surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
 
 
 				const byteArray = new Uint8Array( buffer, dataOffset, dataSize );
 				const byteArray = new Uint8Array( buffer, dataOffset, dataSize );

+ 36 - 61
examples/js/loaders/RGBELoader.js

@@ -1,5 +1,6 @@
 ( function () {
 ( function () {
 
 
+	// https://github.com/mrdoob/three.js/issues/5552
 	// http://en.wikipedia.org/wiki/RGBE_image_format
 	// http://en.wikipedia.org/wiki/RGBE_image_format
 
 
 	class RGBELoader extends THREE.DataTextureLoader {
 	class RGBELoader extends THREE.DataTextureLoader {
@@ -9,16 +10,15 @@
 			super( manager );
 			super( manager );
 			this.type = THREE.HalfFloatType;
 			this.type = THREE.HalfFloatType;
 
 
-		} // adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html
+		}
 
 
+		// adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html
 
 
 		parse( buffer ) {
 		parse( buffer ) {
 
 
-			const
-				/* return codes for rgbe routines */
+			const /* return codes for rgbe routines */
 				//RGBE_RETURN_SUCCESS = 0,
 				//RGBE_RETURN_SUCCESS = 0,
 				RGBE_RETURN_FAILURE = - 1,
 				RGBE_RETURN_FAILURE = - 1,
-
 				/* default error routine.  change this to change error handling */
 				/* default error routine.  change this to change error handling */
 				rgbe_read_error = 1,
 				rgbe_read_error = 1,
 				rgbe_write_error = 2,
 				rgbe_write_error = 2,
@@ -31,15 +31,12 @@
 						case rgbe_read_error:
 						case rgbe_read_error:
 							console.error( 'THREE.RGBELoader Read Error: ' + ( msg || '' ) );
 							console.error( 'THREE.RGBELoader Read Error: ' + ( msg || '' ) );
 							break;
 							break;
-
 						case rgbe_write_error:
 						case rgbe_write_error:
 							console.error( 'THREE.RGBELoader Write Error: ' + ( msg || '' ) );
 							console.error( 'THREE.RGBELoader Write Error: ' + ( msg || '' ) );
 							break;
 							break;
-
 						case rgbe_format_error:
 						case rgbe_format_error:
 							console.error( 'THREE.RGBELoader Bad File Format: ' + ( msg || '' ) );
 							console.error( 'THREE.RGBELoader Bad File Format: ' + ( msg || '' ) );
 							break;
 							break;
-
 						default:
 						default:
 						case rgbe_memory_error:
 						case rgbe_memory_error:
 							console.error( 'THREE.RGBELoader: Error: ' + ( msg || '' ) );
 							console.error( 'THREE.RGBELoader: Error: ' + ( msg || '' ) );
@@ -49,7 +46,6 @@
 					return RGBE_RETURN_FAILURE;
 					return RGBE_RETURN_FAILURE;
 
 
 				},
 				},
-
 				/* offsets to red, green, and blue components in a data (float) pixel */
 				/* offsets to red, green, and blue components in a data (float) pixel */
 				//RGBE_DATA_RED = 0,
 				//RGBE_DATA_RED = 0,
 				//RGBE_DATA_GREEN = 1,
 				//RGBE_DATA_GREEN = 1,
@@ -72,7 +68,6 @@
 						len = 0,
 						len = 0,
 						s = '',
 						s = '',
 						chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );
 						chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );
-
 					while ( 0 > ( i = chunk.indexOf( NEWLINE ) ) && len < lineLimit && p < buffer.byteLength ) {
 					while ( 0 > ( i = chunk.indexOf( NEWLINE ) ) && len < lineLimit && p < buffer.byteLength ) {
 
 
 						s += chunk;
 						s += chunk;
@@ -85,11 +80,11 @@
 					if ( - 1 < i ) {
 					if ( - 1 < i ) {
 
 
 						/*for (i=l-1; i>=0; i--) {
 						/*for (i=l-1; i>=0; i--) {
-        	byteCode = m.charCodeAt(i);
-        	if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++;
-        	else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2;
-        	if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate
-        }*/
+          	byteCode = m.charCodeAt(i);
+          	if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++;
+          	else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2;
+          	if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate
+          }*/
 						if ( false !== consume ) buffer.pos += len + i + 1;
 						if ( false !== consume ) buffer.pos += len + i + 1;
 						return s + chunk.slice( 0, i );
 						return s + chunk.slice( 0, i );
 
 
@@ -98,7 +93,6 @@
 					return false;
 					return false;
 
 
 				},
 				},
-
 				/* minimal header reading.  modify if you want to parse more information */
 				/* minimal header reading.  modify if you want to parse more information */
 				RGBE_ReadHeader = function ( buffer ) {
 				RGBE_ReadHeader = function ( buffer ) {
 
 
@@ -111,41 +105,38 @@
 						// RGBE format header struct
 						// RGBE format header struct
 						header = {
 						header = {
 							valid: 0,
 							valid: 0,
-
 							/* indicate which fields are valid */
 							/* indicate which fields are valid */
-							string: '',
 
 
+							string: '',
 							/* the actual header string */
 							/* the actual header string */
-							comments: '',
 
 
+							comments: '',
 							/* comments found in header */
 							/* comments found in header */
-							programtype: 'RGBE',
 
 
+							programtype: 'RGBE',
 							/* listed at beginning of file to identify it after "#?". defaults to "RGBE" */
 							/* listed at beginning of file to identify it after "#?". defaults to "RGBE" */
-							format: '',
 
 
+							format: '',
 							/* RGBE format, default 32-bit_rle_rgbe */
 							/* RGBE format, default 32-bit_rle_rgbe */
-							gamma: 1.0,
 
 
+							gamma: 1.0,
 							/* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */
 							/* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */
-							exposure: 1.0,
 
 
+							exposure: 1.0,
 							/* a value of 1.0 in an image corresponds to <exposure> watts/steradian/m^2. defaults to 1.0 */
 							/* a value of 1.0 in an image corresponds to <exposure> watts/steradian/m^2. defaults to 1.0 */
-							width: 0,
-							height: 0
-							/* image dimensions, width/height */
 
 
+							width: 0,
+							height: 0 /* image dimensions, width/height */
 						};
 						};
-					let line, match;
 
 
+					let line, match;
 					if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) {
 					if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) {
 
 
 						return rgbe_error( rgbe_read_error, 'no header found' );
 						return rgbe_error( rgbe_read_error, 'no header found' );
 
 
 					}
 					}
-					/* if you want to require the magic token then uncomment the next line */
-
 
 
+					/* if you want to require the magic token then uncomment the next line */
 					if ( ! ( match = line.match( magic_token_re ) ) ) {
 					if ( ! ( match = line.match( magic_token_re ) ) ) {
 
 
 						return rgbe_error( rgbe_format_error, 'bad initial token' );
 						return rgbe_error( rgbe_format_error, 'bad initial token' );
@@ -155,13 +146,11 @@
 					header.valid |= RGBE_VALID_PROGRAMTYPE;
 					header.valid |= RGBE_VALID_PROGRAMTYPE;
 					header.programtype = match[ 1 ];
 					header.programtype = match[ 1 ];
 					header.string += line + '\n';
 					header.string += line + '\n';
-
 					while ( true ) {
 					while ( true ) {
 
 
 						line = fgets( buffer );
 						line = fgets( buffer );
 						if ( false === line ) break;
 						if ( false === line ) break;
 						header.string += line + '\n';
 						header.string += line + '\n';
-
 						if ( '#' === line.charAt( 0 ) ) {
 						if ( '#' === line.charAt( 0 ) ) {
 
 
 							header.comments += line + '\n';
 							header.comments += line + '\n';
@@ -218,10 +207,11 @@
 				RGBE_ReadPixels_RLE = function ( buffer, w, h ) {
 				RGBE_ReadPixels_RLE = function ( buffer, w, h ) {
 
 
 					const scanline_width = w;
 					const scanline_width = w;
-
-					if ( // run length encoding is not allowed so read flat
-						scanline_width < 8 || scanline_width > 0x7fff || // this file is not run length encoded
-      2 !== buffer[ 0 ] || 2 !== buffer[ 1 ] || buffer[ 2 ] & 0x80 ) {
+					if (
+					// run length encoding is not allowed so read flat
+						scanline_width < 8 || scanline_width > 0x7fff ||
+        // this file is not run length encoded
+        2 !== buffer[ 0 ] || 2 !== buffer[ 1 ] || buffer[ 2 ] & 0x80 ) {
 
 
 						// return the flat buffer
 						// return the flat buffer
 						return new Uint8Array( buffer );
 						return new Uint8Array( buffer );
@@ -235,7 +225,6 @@
 					}
 					}
 
 
 					const data_rgba = new Uint8Array( 4 * w * h );
 					const data_rgba = new Uint8Array( 4 * w * h );
-
 					if ( ! data_rgba.length ) {
 					if ( ! data_rgba.length ) {
 
 
 						return rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' );
 						return rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' );
@@ -247,8 +236,9 @@
 					const ptr_end = 4 * scanline_width;
 					const ptr_end = 4 * scanline_width;
 					const rgbeStart = new Uint8Array( 4 );
 					const rgbeStart = new Uint8Array( 4 );
 					const scanline_buffer = new Uint8Array( ptr_end );
 					const scanline_buffer = new Uint8Array( ptr_end );
-					let num_scanlines = h; // read in each successive scanline
+					let num_scanlines = h;
 
 
+					// read in each successive scanline
 					while ( num_scanlines > 0 && pos < buffer.byteLength ) {
 					while ( num_scanlines > 0 && pos < buffer.byteLength ) {
 
 
 						if ( pos + 4 > buffer.byteLength ) {
 						if ( pos + 4 > buffer.byteLength ) {
@@ -261,24 +251,21 @@
 						rgbeStart[ 1 ] = buffer[ pos ++ ];
 						rgbeStart[ 1 ] = buffer[ pos ++ ];
 						rgbeStart[ 2 ] = buffer[ pos ++ ];
 						rgbeStart[ 2 ] = buffer[ pos ++ ];
 						rgbeStart[ 3 ] = buffer[ pos ++ ];
 						rgbeStart[ 3 ] = buffer[ pos ++ ];
-
 						if ( 2 != rgbeStart[ 0 ] || 2 != rgbeStart[ 1 ] || ( rgbeStart[ 2 ] << 8 | rgbeStart[ 3 ] ) != scanline_width ) {
 						if ( 2 != rgbeStart[ 0 ] || 2 != rgbeStart[ 1 ] || ( rgbeStart[ 2 ] << 8 | rgbeStart[ 3 ] ) != scanline_width ) {
 
 
 							return rgbe_error( rgbe_format_error, 'bad rgbe scanline format' );
 							return rgbe_error( rgbe_format_error, 'bad rgbe scanline format' );
 
 
-						} // read each of the four channels for the scanline into the buffer
-						// first red, then green, then blue, then exponent
-
+						}
 
 
+						// read each of the four channels for the scanline into the buffer
+						// first red, then green, then blue, then exponent
 						let ptr = 0,
 						let ptr = 0,
 							count;
 							count;
-
 						while ( ptr < ptr_end && pos < buffer.byteLength ) {
 						while ( ptr < ptr_end && pos < buffer.byteLength ) {
 
 
 							count = buffer[ pos ++ ];
 							count = buffer[ pos ++ ];
 							const isEncodedRun = count > 128;
 							const isEncodedRun = count > 128;
 							if ( isEncodedRun ) count -= 128;
 							if ( isEncodedRun ) count -= 128;
-
 							if ( 0 === count || ptr + count > ptr_end ) {
 							if ( 0 === count || ptr + count > ptr_end ) {
 
 
 								return rgbe_error( rgbe_format_error, 'bad scanline data' );
 								return rgbe_error( rgbe_format_error, 'bad scanline data' );
@@ -289,12 +276,12 @@
 
 
 								// a (encoded) run of the same value
 								// a (encoded) run of the same value
 								const byteValue = buffer[ pos ++ ];
 								const byteValue = buffer[ pos ++ ];
-
 								for ( let i = 0; i < count; i ++ ) {
 								for ( let i = 0; i < count; i ++ ) {
 
 
 									scanline_buffer[ ptr ++ ] = byteValue;
 									scanline_buffer[ ptr ++ ] = byteValue;
 
 
-								} //ptr += count;
+								}
+								//ptr += count;
 
 
 							} else {
 							} else {
 
 
@@ -305,24 +292,20 @@
 
 
 							}
 							}
 
 
-						} // now convert data from buffer into rgba
-						// first red, then green, then blue, then exponent (alpha)
-
+						}
 
 
+						// now convert data from buffer into rgba
+						// first red, then green, then blue, then exponent (alpha)
 						const l = scanline_width; //scanline_buffer.byteLength;
 						const l = scanline_width; //scanline_buffer.byteLength;
-
 						for ( let i = 0; i < l; i ++ ) {
 						for ( let i = 0; i < l; i ++ ) {
 
 
 							let off = 0;
 							let off = 0;
 							data_rgba[ offset ] = scanline_buffer[ i + off ];
 							data_rgba[ offset ] = scanline_buffer[ i + off ];
 							off += scanline_width; //1;
 							off += scanline_width; //1;
-
 							data_rgba[ offset + 1 ] = scanline_buffer[ i + off ];
 							data_rgba[ offset + 1 ] = scanline_buffer[ i + off ];
 							off += scanline_width; //1;
 							off += scanline_width; //1;
-
 							data_rgba[ offset + 2 ] = scanline_buffer[ i + off ];
 							data_rgba[ offset + 2 ] = scanline_buffer[ i + off ];
 							off += scanline_width; //1;
 							off += scanline_width; //1;
-
 							data_rgba[ offset + 3 ] = scanline_buffer[ i + off ];
 							data_rgba[ offset + 3 ] = scanline_buffer[ i + off ];
 							offset += 4;
 							offset += 4;
 
 
@@ -350,8 +333,9 @@
 			const RGBEByteToRGBHalf = function ( sourceArray, sourceOffset, destArray, destOffset ) {
 			const RGBEByteToRGBHalf = function ( sourceArray, sourceOffset, destArray, destOffset ) {
 
 
 				const e = sourceArray[ sourceOffset + 3 ];
 				const e = sourceArray[ sourceOffset + 3 ];
-				const scale = Math.pow( 2.0, e - 128.0 ) / 255.0; // clamping to 65504, the maximum representable value in float16
+				const scale = Math.pow( 2.0, e - 128.0 ) / 255.0;
 
 
+				// clamping to 65504, the maximum representable value in float16
 				destArray[ destOffset + 0 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 0 ] * scale, 65504 ) );
 				destArray[ destOffset + 0 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 0 ] * scale, 65504 ) );
 				destArray[ destOffset + 1 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 1 ] * scale, 65504 ) );
 				destArray[ destOffset + 1 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 1 ] * scale, 65504 ) );
 				destArray[ destOffset + 2 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 2 ] * scale, 65504 ) );
 				destArray[ destOffset + 2 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 2 ] * scale, 65504 ) );
@@ -362,24 +346,20 @@
 			const byteArray = new Uint8Array( buffer );
 			const byteArray = new Uint8Array( buffer );
 			byteArray.pos = 0;
 			byteArray.pos = 0;
 			const rgbe_header_info = RGBE_ReadHeader( byteArray );
 			const rgbe_header_info = RGBE_ReadHeader( byteArray );
-
 			if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {
 			if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {
 
 
 				const w = rgbe_header_info.width,
 				const w = rgbe_header_info.width,
 					h = rgbe_header_info.height,
 					h = rgbe_header_info.height,
 					image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h );
 					image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h );
-
 				if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {
 				if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {
 
 
 					let data, type;
 					let data, type;
 					let numElements;
 					let numElements;
-
 					switch ( this.type ) {
 					switch ( this.type ) {
 
 
 						case THREE.FloatType:
 						case THREE.FloatType:
 							numElements = image_rgba_data.length / 4;
 							numElements = image_rgba_data.length / 4;
 							const floatArray = new Float32Array( numElements * 4 );
 							const floatArray = new Float32Array( numElements * 4 );
-
 							for ( let j = 0; j < numElements; j ++ ) {
 							for ( let j = 0; j < numElements; j ++ ) {
 
 
 								RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 4 );
 								RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 4 );
@@ -389,11 +369,9 @@
 							data = floatArray;
 							data = floatArray;
 							type = THREE.FloatType;
 							type = THREE.FloatType;
 							break;
 							break;
-
 						case THREE.HalfFloatType:
 						case THREE.HalfFloatType:
 							numElements = image_rgba_data.length / 4;
 							numElements = image_rgba_data.length / 4;
 							const halfArray = new Uint16Array( numElements * 4 );
 							const halfArray = new Uint16Array( numElements * 4 );
-
 							for ( let j = 0; j < numElements; j ++ ) {
 							for ( let j = 0; j < numElements; j ++ ) {
 
 
 								RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 4 );
 								RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 4 );
@@ -403,7 +381,6 @@
 							data = halfArray;
 							data = halfArray;
 							type = THREE.HalfFloatType;
 							type = THREE.HalfFloatType;
 							break;
 							break;
-
 						default:
 						default:
 							console.error( 'THREE.RGBELoader: unsupported type: ', this.type );
 							console.error( 'THREE.RGBELoader: unsupported type: ', this.type );
 							break;
 							break;
@@ -427,14 +404,12 @@
 			return null;
 			return null;
 
 
 		}
 		}
-
 		setDataType( value ) {
 		setDataType( value ) {
 
 
 			this.type = value;
 			this.type = value;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 		load( url, onLoad, onProgress, onError ) {
 
 
 			function onLoadCallback( texture, texData ) {
 			function onLoadCallback( texture, texData ) {

+ 26 - 87
examples/js/loaders/RGBMLoader.js

@@ -16,27 +16,23 @@
 			return this;
 			return this;
 
 
 		}
 		}
-
 		setMaxRange( value ) {
 		setMaxRange( value ) {
 
 
 			this.maxRange = value;
 			this.maxRange = value;
 			return this;
 			return this;
 
 
 		}
 		}
-
 		loadCubemap( urls, onLoad, onProgress, onError ) {
 		loadCubemap( urls, onLoad, onProgress, onError ) {
 
 
 			const texture = new THREE.CubeTexture();
 			const texture = new THREE.CubeTexture();
 			let loaded = 0;
 			let loaded = 0;
 			const scope = this;
 			const scope = this;
-
 			function loadTexture( i ) {
 			function loadTexture( i ) {
 
 
 				scope.load( urls[ i ], function ( image ) {
 				scope.load( urls[ i ], function ( image ) {
 
 
 					texture.images[ i ] = image;
 					texture.images[ i ] = image;
 					loaded ++;
 					loaded ++;
-
 					if ( loaded === 6 ) {
 					if ( loaded === 6 ) {
 
 
 						texture.needsUpdate = true;
 						texture.needsUpdate = true;
@@ -61,14 +57,15 @@
 			return texture;
 			return texture;
 
 
 		}
 		}
-
 		parse( buffer ) {
 		parse( buffer ) {
 
 
 			const img = UPNG.decode( buffer );
 			const img = UPNG.decode( buffer );
 			const rgba = UPNG.toRGBA8( img )[ 0 ];
 			const rgba = UPNG.toRGBA8( img )[ 0 ];
 			const data = new Uint8Array( rgba );
 			const data = new Uint8Array( rgba );
 			const size = img.width * img.height * 4;
 			const size = img.width * img.height * 4;
-			const output = this.type === THREE.HalfFloatType ? new Uint16Array( size ) : new Float32Array( size ); // decode RGBM
+			const output = this.type === THREE.HalfFloatType ? new Uint16Array( size ) : new Float32Array( size );
+
+			// decode RGBM
 
 
 			for ( let i = 0; i < data.length; i += 4 ) {
 			for ( let i = 0; i < data.length; i += 4 ) {
 
 
@@ -76,7 +73,6 @@
 				const g = data[ i + 1 ] / 255;
 				const g = data[ i + 1 ] / 255;
 				const b = data[ i + 2 ] / 255;
 				const b = data[ i + 2 ] / 255;
 				const a = data[ i + 3 ] / 255;
 				const a = data[ i + 3 ] / 255;
-
 				if ( this.type === THREE.HalfFloatType ) {
 				if ( this.type === THREE.HalfFloatType ) {
 
 
 					output[ i + 0 ] = THREE.DataUtils.toHalfFloat( Math.min( r * a * this.maxRange, 65504 ) );
 					output[ i + 0 ] = THREE.DataUtils.toHalfFloat( Math.min( r * a * this.maxRange, 65504 ) );
@@ -106,11 +102,11 @@
 
 
 		}
 		}
 
 
-	} // from https://github.com/photopea/UPNG.js (MIT License)
+	}
 
 
+	// from https://github.com/photopea/UPNG.js (MIT License)
 
 
 	var UPNG = {};
 	var UPNG = {};
-
 	UPNG.toRGBA8 = function ( out ) {
 	UPNG.toRGBA8 = function ( out ) {
 
 
 		var w = out.width,
 		var w = out.width,
@@ -122,7 +118,6 @@
 			img = new Uint8Array( len ),
 			img = new Uint8Array( len ),
 			empty = new Uint8Array( len ),
 			empty = new Uint8Array( len ),
 			prev = new Uint8Array( len );
 			prev = new Uint8Array( len );
-
 		for ( var i = 0; i < out.frames.length; i ++ ) {
 		for ( var i = 0; i < out.frames.length; i ++ ) {
 
 
 			var frm = out.frames[ i ];
 			var frm = out.frames[ i ];
@@ -146,7 +141,6 @@
 
 
 		var area = w * h,
 		var area = w * h,
 			bpp = UPNG.decode._getBPP( out );
 			bpp = UPNG.decode._getBPP( out );
-
 		var bpl = Math.ceil( w * bpp / 8 ); // bytes per line
 		var bpl = Math.ceil( w * bpp / 8 ); // bytes per line
 
 
 		var bf = new Uint8Array( area * 4 ),
 		var bf = new Uint8Array( area * 4 ),
@@ -154,10 +148,10 @@
 		var ctype = out.ctype,
 		var ctype = out.ctype,
 			depth = out.depth;
 			depth = out.depth;
 		var rs = UPNG._bin.readUshort;
 		var rs = UPNG._bin.readUshort;
-
 		if ( ctype == 6 ) {
 		if ( ctype == 6 ) {
 
 
 			// RGB + alpha
 			// RGB + alpha
+
 			var qarea = area << 2;
 			var qarea = area << 2;
 			if ( depth == 8 ) for ( var i = 0; i < qarea; i += 4 ) {
 			if ( depth == 8 ) for ( var i = 0; i < qarea; i += 4 ) {
 
 
@@ -177,8 +171,8 @@
 		} else if ( ctype == 2 ) {
 		} else if ( ctype == 2 ) {
 
 
 			// RGB
 			// RGB
-			var ts = out.tabs[ 'tRNS' ];
 
 
+			var ts = out.tabs[ 'tRNS' ];
 			if ( ts == null ) {
 			if ( ts == null ) {
 
 
 				if ( depth == 8 ) for ( var i = 0; i < area; i ++ ) {
 				if ( depth == 8 ) for ( var i = 0; i < area; i ++ ) {
@@ -223,15 +217,15 @@
 		} else if ( ctype == 3 ) {
 		} else if ( ctype == 3 ) {
 
 
 			// palette
 			// palette
+
 			var p = out.tabs[ 'PLTE' ],
 			var p = out.tabs[ 'PLTE' ],
 				ap = out.tabs[ 'tRNS' ],
 				ap = out.tabs[ 'tRNS' ],
-				tl = ap ? ap.length : 0; //console.log(p, ap);
-
+				tl = ap ? ap.length : 0;
+			//console.log(p, ap);
 			if ( depth == 1 ) for ( var y = 0; y < h; y ++ ) {
 			if ( depth == 1 ) for ( var y = 0; y < h; y ++ ) {
 
 
 				var s0 = y * bpl,
 				var s0 = y * bpl,
 					t0 = y * w;
 					t0 = y * w;
-
 				for ( var i = 0; i < w; i ++ ) {
 				for ( var i = 0; i < w; i ++ ) {
 
 
 					var qi = t0 + i << 2,
 					var qi = t0 + i << 2,
@@ -250,7 +244,6 @@
 
 
 				var s0 = y * bpl,
 				var s0 = y * bpl,
 					t0 = y * w;
 					t0 = y * w;
-
 				for ( var i = 0; i < w; i ++ ) {
 				for ( var i = 0; i < w; i ++ ) {
 
 
 					var qi = t0 + i << 2,
 					var qi = t0 + i << 2,
@@ -269,7 +262,6 @@
 
 
 				var s0 = y * bpl,
 				var s0 = y * bpl,
 					t0 = y * w;
 					t0 = y * w;
-
 				for ( var i = 0; i < w; i ++ ) {
 				for ( var i = 0; i < w; i ++ ) {
 
 
 					var qi = t0 + i << 2,
 					var qi = t0 + i << 2,
@@ -299,6 +291,7 @@
 		} else if ( ctype == 4 ) {
 		} else if ( ctype == 4 ) {
 
 
 			// gray + alpha
 			// gray + alpha
+
 			if ( depth == 8 ) for ( var i = 0; i < area; i ++ ) {
 			if ( depth == 8 ) for ( var i = 0; i < area; i ++ ) {
 
 
 				var qi = i << 2,
 				var qi = i << 2,
@@ -326,8 +319,8 @@
 		} else if ( ctype == 0 ) {
 		} else if ( ctype == 0 ) {
 
 
 			// gray
 			// gray
-			var tr = out.tabs[ 'tRNS' ] ? out.tabs[ 'tRNS' ] : - 1;
 
 
+			var tr = out.tabs[ 'tRNS' ] ? out.tabs[ 'tRNS' ] : - 1;
 			for ( var y = 0; y < h; y ++ ) {
 			for ( var y = 0; y < h; y ++ ) {
 
 
 				var off = y * bpl,
 				var off = y * bpl,
@@ -366,9 +359,9 @@
 
 
 			}
 			}
 
 
-		} //console.log(Date.now()-time);
-
+		}
 
 
+		//console.log(Date.now()-time);
 		return bf;
 		return bf;
 
 
 	};
 	};
@@ -386,21 +379,18 @@
 		};
 		};
 		var dd = new Uint8Array( data.length ),
 		var dd = new Uint8Array( data.length ),
 			doff = 0; // put all IDAT data into it
 			doff = 0; // put all IDAT data into it
-
 		var fd,
 		var fd,
 			foff = 0; // frames
 			foff = 0; // frames
-
 		var text, keyw, bfr;
 		var text, keyw, bfr;
 		var mgck = [ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a ];
 		var mgck = [ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a ];
-
 		for ( var i = 0; i < 8; i ++ ) if ( data[ i ] != mgck[ i ] ) throw new Error( 'The input is not a PNG file!' );
 		for ( var i = 0; i < 8; i ++ ) if ( data[ i ] != mgck[ i ] ) throw new Error( 'The input is not a PNG file!' );
-
 		while ( offset < data.length ) {
 		while ( offset < data.length ) {
 
 
 			var len = bin.readUint( data, offset );
 			var len = bin.readUint( data, offset );
 			offset += 4;
 			offset += 4;
 			var type = bin.readASCII( data, offset, 4 );
 			var type = bin.readASCII( data, offset, 4 );
-			offset += 4; //console.log(type,len);
+			offset += 4;
+			//console.log(type,len);
 
 
 			if ( type == 'IHDR' ) {
 			if ( type == 'IHDR' ) {
 
 
@@ -413,7 +403,6 @@
 			} else if ( type == 'IDAT' ) {
 			} else if ( type == 'IDAT' ) {
 
 
 				for ( var i = 0; i < len; i ++ ) dd[ doff + i ] = data[ offset + i ];
 				for ( var i = 0; i < len; i ++ ) dd[ doff + i ] = data[ offset + i ];
-
 				doff += len;
 				doff += len;
 
 
 			} else if ( type == 'acTL' ) {
 			} else if ( type == 'acTL' ) {
@@ -447,14 +436,13 @@
 					delay: Math.round( del * 1000 ),
 					delay: Math.round( del * 1000 ),
 					dispose: data[ offset + 24 ],
 					dispose: data[ offset + 24 ],
 					blend: data[ offset + 25 ]
 					blend: data[ offset + 25 ]
-				}; //console.log(frm);
-
+				};
+				//console.log(frm);
 				out.frames.push( frm );
 				out.frames.push( frm );
 
 
 			} else if ( type == 'fdAT' ) {
 			} else if ( type == 'fdAT' ) {
 
 
 				for ( var i = 0; i < len - 4; i ++ ) fd[ foff + i ] = data[ offset + i + 4 ];
 				for ( var i = 0; i < len - 4; i ++ ) fd[ foff + i ] = data[ offset + i + 4 ];
-
 				foff += len - 4;
 				foff += len - 4;
 
 
 			} else if ( type == 'pHYs' ) {
 			} else if ( type == 'pHYs' ) {
@@ -464,7 +452,6 @@
 			} else if ( type == 'cHRM' ) {
 			} else if ( type == 'cHRM' ) {
 
 
 				out.tabs[ type ] = [];
 				out.tabs[ type ] = [];
-
 				for ( var i = 0; i < 8; i ++ ) out.tabs[ type ].push( bin.readUint( data, offset + i * 4 ) );
 				for ( var i = 0; i < 8; i ++ ) out.tabs[ type ].push( bin.readUint( data, offset + i * 4 ) );
 
 
 			} else if ( type == 'tEXt' || type == 'zTXt' ) {
 			} else if ( type == 'tEXt' || type == 'zTXt' ) {
@@ -516,12 +503,12 @@
 
 
 				var pl = out.tabs[ 'PLTE' ].length / 3;
 				var pl = out.tabs[ 'PLTE' ].length / 3;
 				out.tabs[ type ] = [];
 				out.tabs[ type ] = [];
-
 				for ( var i = 0; i < pl; i ++ ) out.tabs[ type ].push( rUs( data, offset + i * 2 ) );
 				for ( var i = 0; i < pl; i ++ ) out.tabs[ type ].push( rUs( data, offset + i * 2 ) );
 
 
 			} else if ( type == 'tRNS' ) {
 			} else if ( type == 'tRNS' ) {
 
 
-				if ( out.ctype == 3 ) out.tabs[ type ] = bin.readBytes( data, offset, len ); else if ( out.ctype == 0 ) out.tabs[ type ] = rUs( data, offset ); else if ( out.ctype == 2 ) out.tabs[ type ] = [ rUs( data, offset ), rUs( data, offset + 2 ), rUs( data, offset + 4 ) ]; //else console.log("tRNS for unsupported color type",out.ctype, len);
+				if ( out.ctype == 3 ) out.tabs[ type ] = bin.readBytes( data, offset, len ); else if ( out.ctype == 0 ) out.tabs[ type ] = rUs( data, offset ); else if ( out.ctype == 2 ) out.tabs[ type ] = [ rUs( data, offset ), rUs( data, offset + 2 ), rUs( data, offset + 4 ) ];
+				//else console.log("tRNS for unsupported color type",out.ctype, len);
 
 
 			} else if ( type == 'gAMA' ) out.tabs[ type ] = bin.readUint( data, offset ) / 100000; else if ( type == 'sRGB' ) out.tabs[ type ] = data[ offset ]; else if ( type == 'bKGD' ) {
 			} else if ( type == 'gAMA' ) out.tabs[ type ] = bin.readUint( data, offset ) / 100000; else if ( type == 'sRGB' ) out.tabs[ type ] = data[ offset ]; else if ( type == 'bKGD' ) {
 
 
@@ -531,9 +518,9 @@
 
 
 				break;
 				break;
 
 
-			} //else {  console.log("unknown chunk type", type, len);  out.tabs[type]=data.slice(offset,offset+len);  }
-
+			}
 
 
+			//else {  console.log("unknown chunk type", type, len);  out.tabs[type]=data.slice(offset,offset+len);  }
 			offset += len;
 			offset += len;
 			bin.readUint( data, offset );
 			bin.readUint( data, offset );
 			offset += 4;
 			offset += 4;
@@ -560,7 +547,6 @@
 		var bpp = UPNG.decode._getBPP( out ),
 		var bpp = UPNG.decode._getBPP( out ),
 			bpl = Math.ceil( w * bpp / 8 ),
 			bpl = Math.ceil( w * bpp / 8 ),
 			buff = new Uint8Array( ( bpl + 1 + out.interlace ) * h );
 			buff = new Uint8Array( ( bpl + 1 + out.interlace ) * h );
-
 		if ( out.tabs[ 'CgBI' ] ) dd = UPNG.inflateRaw( dd, buff ); else dd = UPNG.decode._inflate( dd, buff );
 		if ( out.tabs[ 'CgBI' ] ) dd = UPNG.inflateRaw( dd, buff ); else dd = UPNG.decode._inflate( dd, buff );
 		if ( out.interlace == 0 ) dd = UPNG.decode._filterZero( dd, out, 0, w, h ); else if ( out.interlace == 1 ) dd = UPNG.decode._readInterlace( dd, out );
 		if ( out.interlace == 0 ) dd = UPNG.decode._filterZero( dd, out, 0, w, h ); else if ( out.interlace == 1 ) dd = UPNG.decode._readInterlace( dd, out );
 		return dd;
 		return dd;
@@ -578,7 +564,6 @@
 
 
 		var H = {};
 		var H = {};
 		H.H = {};
 		H.H = {};
-
 		H.H.N = function ( N, W ) {
 		H.H.N = function ( N, W ) {
 
 
 			var R = Uint8Array,
 			var R = Uint8Array,
@@ -604,13 +589,11 @@
 				b = V.m,
 				b = V.m,
 				Z = W == null;
 				Z = W == null;
 			if ( Z ) W = new R( N.length >>> 2 << 5 );
 			if ( Z ) W = new R( N.length >>> 2 << 5 );
-
 			while ( i == 0 ) {
 			while ( i == 0 ) {
 
 
 				i = n( N, d, 1 );
 				i = n( N, d, 1 );
 				m = n( N, d + 1, 2 );
 				m = n( N, d + 1, 2 );
 				d += 3;
 				d += 3;
-
 				if ( m == 0 ) {
 				if ( m == 0 ) {
 
 
 					if ( ( d & 7 ) != 0 ) d += 8 - ( d & 7 );
 					if ( ( d & 7 ) != 0 ) d += 8 - ( d & 7 );
@@ -625,7 +608,6 @@
 				}
 				}
 
 
 				if ( Z ) W = H.H.W( W, w + ( 1 << 17 ) );
 				if ( Z ) W = H.H.W( W, w + ( 1 << 17 ) );
-
 				if ( m == 1 ) {
 				if ( m == 1 ) {
 
 
 					v = b.J;
 					v = b.J;
@@ -642,7 +624,6 @@
 					Q = A( N, d + 10, 4 ) + 4;
 					Q = A( N, d + 10, 4 ) + 4;
 					d += 14;
 					d += 14;
 					var j = 1;
 					var j = 1;
-
 					for ( var c = 0; c < 38; c += 2 ) {
 					for ( var c = 0; c < 38; c += 2 ) {
 
 
 						b.Q[ c ] = 0;
 						b.Q[ c ] = 0;
@@ -680,7 +661,6 @@
 					var T = v[ e( N, d ) & X ];
 					var T = v[ e( N, d ) & X ];
 					d += T & 15;
 					d += T & 15;
 					var p = T >>> 4;
 					var p = T >>> 4;
-
 					if ( p >>> 8 == 0 ) {
 					if ( p >>> 8 == 0 ) {
 
 
 						W[ w ++ ] = p;
 						W[ w ++ ] = p;
@@ -692,7 +672,6 @@
 					} else {
 					} else {
 
 
 						var z = w + p - 254;
 						var z = w + p - 254;
-
 						if ( p > 264 ) {
 						if ( p > 264 ) {
 
 
 							var _ = b.q[ p - 257 ];
 							var _ = b.q[ p - 257 ];
@@ -707,7 +686,6 @@
 							Y = b.c[ s ],
 							Y = b.c[ s ],
 							a = ( Y >>> 4 ) + n( N, d, Y & 15 );
 							a = ( Y >>> 4 ) + n( N, d, Y & 15 );
 						d += Y & 15;
 						d += Y & 15;
-
 						while ( w < z ) {
 						while ( w < z ) {
 
 
 							W[ w ] = W[ w ++ - a ];
 							W[ w ] = W[ w ++ - a ];
@@ -744,13 +722,11 @@
 			var l = H.H.e,
 			var l = H.H.e,
 				M = H.H.Z,
 				M = H.H.Z,
 				I = 0;
 				I = 0;
-
 			while ( I < R ) {
 			while ( I < R ) {
 
 
 				var e = N[ M( V, n ) & W ];
 				var e = N[ M( V, n ) & W ];
 				n += e & 15;
 				n += e & 15;
 				var b = e >>> 4;
 				var b = e >>> 4;
-
 				if ( b <= 15 ) {
 				if ( b <= 15 ) {
 
 
 					A[ I ] = b;
 					A[ I ] = b;
@@ -760,7 +736,6 @@
 
 
 					var Z = 0,
 					var Z = 0,
 						m = 0;
 						m = 0;
-
 					if ( b == 16 ) {
 					if ( b == 16 ) {
 
 
 						m = 3 + l( V, n, 2 );
 						m = 3 + l( V, n, 2 );
@@ -780,7 +755,6 @@
 					}
 					}
 
 
 					var J = I + m;
 					var J = I + m;
-
 					while ( I < J ) {
 					while ( I < J ) {
 
 
 						A[ I ] = Z;
 						A[ I ] = Z;
@@ -801,7 +775,6 @@
 			var n = 0,
 			var n = 0,
 				A = 0,
 				A = 0,
 				l = V.length >>> 1;
 				l = V.length >>> 1;
-
 			while ( A < R ) {
 			while ( A < R ) {
 
 
 				var M = N[ A + W ];
 				var M = N[ A + W ];
@@ -834,15 +807,11 @@
 				M,
 				M,
 				I,
 				I,
 				e = R.j;
 				e = R.j;
-
 			for ( var M = 0; M <= W; M ++ ) e[ M ] = 0;
 			for ( var M = 0; M <= W; M ++ ) e[ M ] = 0;
-
 			for ( M = 1; M < V; M += 2 ) e[ N[ M ] ] ++;
 			for ( M = 1; M < V; M += 2 ) e[ N[ M ] ] ++;
-
 			var b = R.K;
 			var b = R.K;
 			n = 0;
 			n = 0;
 			e[ 0 ] = 0;
 			e[ 0 ] = 0;
-
 			for ( A = 1; A <= W; A ++ ) {
 			for ( A = 1; A <= W; A ++ ) {
 
 
 				n = n + e[ A - 1 ] << 1;
 				n = n + e[ A - 1 ] << 1;
@@ -853,7 +822,6 @@
 			for ( l = 0; l < V; l += 2 ) {
 			for ( l = 0; l < V; l += 2 ) {
 
 
 				I = N[ l + 1 ];
 				I = N[ l + 1 ];
-
 				if ( I != 0 ) {
 				if ( I != 0 ) {
 
 
 					N[ l ] = b[ I ];
 					N[ l ] = b[ I ];
@@ -870,7 +838,6 @@
 			var V = N.length,
 			var V = N.length,
 				n = H.H.m,
 				n = H.H.m,
 				A = n.r;
 				A = n.r;
-
 			for ( var l = 0; l < V; l += 2 ) if ( N[ l + 1 ] != 0 ) {
 			for ( var l = 0; l < V; l += 2 ) if ( N[ l + 1 ] != 0 ) {
 
 
 				var M = l >> 1,
 				var M = l >> 1,
@@ -879,7 +846,6 @@
 					b = W - I,
 					b = W - I,
 					Z = N[ l ] << b,
 					Z = N[ l ] << b,
 					m = Z + ( 1 << b );
 					m = Z + ( 1 << b );
-
 				while ( Z != m ) {
 				while ( Z != m ) {
 
 
 					var J = A[ Z ] >>> 15 - W;
 					var J = A[ Z ] >>> 15 - W;
@@ -896,7 +862,6 @@
 
 
 			var R = H.H.m.r,
 			var R = H.H.m.r,
 				V = 15 - W;
 				V = 15 - W;
-
 			for ( var n = 0; n < N.length; n += 2 ) {
 			for ( var n = 0; n < N.length; n += 2 ) {
 
 
 				var A = N[ n ] << W - N[ n + 1 ];
 				var A = N[ n ] << W - N[ n + 1 ];
@@ -984,12 +949,10 @@
 			};
 			};
 
 
 		}();
 		}();
-
 		( function () {
 		( function () {
 
 
 			var N = H.H.m,
 			var N = H.H.m,
 				W = 1 << 15;
 				W = 1 << 15;
-
 			for ( var R = 0; R < W; R ++ ) {
 			for ( var R = 0; R < W; R ++ ) {
 
 
 				var V = R;
 				var V = R;
@@ -1035,16 +998,13 @@
 		return H.H.N;
 		return H.H.N;
 
 
 	}();
 	}();
-
 	UPNG.decode._readInterlace = function ( data, out ) {
 	UPNG.decode._readInterlace = function ( data, out ) {
 
 
 		var w = out.width,
 		var w = out.width,
 			h = out.height;
 			h = out.height;
-
 		var bpp = UPNG.decode._getBPP( out ),
 		var bpp = UPNG.decode._getBPP( out ),
 			cbpp = bpp >> 3,
 			cbpp = bpp >> 3,
 			bpl = Math.ceil( w * bpp / 8 );
 			bpl = Math.ceil( w * bpp / 8 );
-
 		var img = new Uint8Array( h * bpl );
 		var img = new Uint8Array( h * bpl );
 		var di = 0;
 		var di = 0;
 		var starting_row = [ 0, 0, 4, 0, 2, 0, 1 ];
 		var starting_row = [ 0, 0, 4, 0, 2, 0, 1 ];
@@ -1052,7 +1012,6 @@
 		var row_increment = [ 8, 8, 8, 4, 4, 2, 2 ];
 		var row_increment = [ 8, 8, 8, 4, 4, 2, 2 ];
 		var col_increment = [ 8, 8, 4, 4, 2, 2, 1 ];
 		var col_increment = [ 8, 8, 4, 4, 2, 2, 1 ];
 		var pass = 0;
 		var pass = 0;
-
 		while ( pass < 7 ) {
 		while ( pass < 7 ) {
 
 
 			var ri = row_increment[ pass ],
 			var ri = row_increment[ pass ],
@@ -1060,7 +1019,6 @@
 			var sw = 0,
 			var sw = 0,
 				sh = 0;
 				sh = 0;
 			var cr = starting_row[ pass ];
 			var cr = starting_row[ pass ];
-
 			while ( cr < h ) {
 			while ( cr < h ) {
 
 
 				cr += ri;
 				cr += ri;
@@ -1069,7 +1027,6 @@
 			}
 			}
 
 
 			var cc = starting_col[ pass ];
 			var cc = starting_col[ pass ];
-
 			while ( cc < w ) {
 			while ( cc < w ) {
 
 
 				cc += ci;
 				cc += ci;
@@ -1078,18 +1035,14 @@
 			}
 			}
 
 
 			var bpll = Math.ceil( sw * bpp / 8 );
 			var bpll = Math.ceil( sw * bpp / 8 );
-
 			UPNG.decode._filterZero( data, out, di, sw, sh );
 			UPNG.decode._filterZero( data, out, di, sw, sh );
-
 			var y = 0,
 			var y = 0,
 				row = starting_row[ pass ];
 				row = starting_row[ pass ];
 			var val;
 			var val;
-
 			while ( row < h ) {
 			while ( row < h ) {
 
 
 				var col = starting_col[ pass ];
 				var col = starting_col[ pass ];
 				var cdi = di + y * bpll << 3;
 				var cdi = di + y * bpll << 3;
-
 				while ( col < w ) {
 				while ( col < w ) {
 
 
 					if ( bpp == 1 ) {
 					if ( bpp == 1 ) {
@@ -1119,7 +1072,6 @@
 					if ( bpp >= 8 ) {
 					if ( bpp >= 8 ) {
 
 
 						var ii = row * bpl + col * cbpp;
 						var ii = row * bpl + col * cbpp;
-
 						for ( var j = 0; j < cbpp; j ++ ) img[ ii + j ] = data[ ( cdi >> 3 ) + j ];
 						for ( var j = 0; j < cbpp; j ++ ) img[ ii + j ] = data[ ( cdi >> 3 ) + j ];
 
 
 					}
 					}
@@ -1155,7 +1107,6 @@
 		var bpp = UPNG.decode._getBPP( out ),
 		var bpp = UPNG.decode._getBPP( out ),
 			bpl = Math.ceil( w * bpp / 8 ),
 			bpl = Math.ceil( w * bpp / 8 ),
 			paeth = UPNG.decode._paeth;
 			paeth = UPNG.decode._paeth;
-
 		bpp = Math.ceil( bpp / 8 );
 		bpp = Math.ceil( bpp / 8 );
 		var i,
 		var i,
 			di,
 			di,
@@ -1163,7 +1114,6 @@
 			x = 0;
 			x = 0;
 		if ( type > 1 ) data[ off ] = [ 0, 0, 1 ][ type - 2 ];
 		if ( type > 1 ) data[ off ] = [ 0, 0, 1 ][ type - 2 ];
 		if ( type == 3 ) for ( x = bpp; x < bpl; x ++ ) data[ x + 1 ] = data[ x + 1 ] + ( data[ x + 1 - bpp ] >>> 1 ) & 255;
 		if ( type == 3 ) for ( x = bpp; x < bpl; x ++ ) data[ x + 1 ] = data[ x + 1 ] + ( data[ x + 1 - bpp ] >>> 1 ) & 255;
-
 		for ( var y = 0; y < h; y ++ ) {
 		for ( var y = 0; y < h; y ++ ) {
 
 
 			i = off + y * bpl;
 			i = off + y * bpl;
@@ -1173,7 +1123,6 @@
 			if ( type == 0 ) for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ]; else if ( type == 1 ) {
 			if ( type == 0 ) for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ]; else if ( type == 1 ) {
 
 
 				for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ];
 				for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ];
-
 				for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + data[ i + x - bpp ];
 				for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + data[ i + x - bpp ];
 
 
 			} else if ( type == 2 ) {
 			} else if ( type == 2 ) {
@@ -1183,13 +1132,11 @@
 			} else if ( type == 3 ) {
 			} else if ( type == 3 ) {
 
 
 				for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ] + ( data[ i + x - bpl ] >>> 1 );
 				for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ] + ( data[ i + x - bpl ] >>> 1 );
-
 				for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + ( data[ i + x - bpl ] + data[ i + x - bpp ] >>> 1 );
 				for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + ( data[ i + x - bpl ] + data[ i + x - bpp ] >>> 1 );
 
 
 			} else {
 			} else {
 
 
 				for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ] + paeth( 0, data[ i + x - bpl ], 0 );
 				for ( ; x < bpp; x ++ ) data[ i + x ] = data[ di + x ] + paeth( 0, data[ i + x - bpl ], 0 );
-
 				for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + paeth( data[ i + x - bpp ], data[ i + x - bpl ], data[ i + x - bpp - bpl ] );
 				for ( ; x < bpl; x ++ ) data[ i + x ] = data[ di + x ] + paeth( data[ i + x - bpp ], data[ i + x - bpl ], data[ i + x - bpp - bpl ] );
 
 
 			}
 			}
@@ -1235,7 +1182,6 @@
 		nextZero: function ( data, p ) {
 		nextZero: function ( data, p ) {
 
 
 			while ( data[ p ] != 0 ) p ++;
 			while ( data[ p ] != 0 ) p ++;
-
 			return p;
 			return p;
 
 
 		},
 		},
@@ -1266,9 +1212,7 @@
 		readASCII: function ( buff, p, l ) {
 		readASCII: function ( buff, p, l ) {
 
 
 			var s = '';
 			var s = '';
-
 			for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] );
 			for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] );
-
 			return s;
 			return s;
 
 
 		},
 		},
@@ -1280,9 +1224,7 @@
 		readBytes: function ( buff, p, l ) {
 		readBytes: function ( buff, p, l ) {
 
 
 			var arr = [];
 			var arr = [];
-
 			for ( var i = 0; i < l; i ++ ) arr.push( buff[ p + i ] );
 			for ( var i = 0; i < l; i ++ ) arr.push( buff[ p + i ] );
-
 			return arr;
 			return arr;
 
 
 		},
 		},
@@ -1295,9 +1237,7 @@
 
 
 			var s = '',
 			var s = '',
 				ns;
 				ns;
-
 			for ( var i = 0; i < l; i ++ ) s += '%' + UPNG._bin.pad( buff[ p + i ].toString( 16 ) );
 			for ( var i = 0; i < l; i ++ ) s += '%' + UPNG._bin.pad( buff[ p + i ].toString( 16 ) );
-
 			try {
 			try {
 
 
 				ns = decodeURIComponent( s );
 				ns = decodeURIComponent( s );
@@ -1312,14 +1252,12 @@
 
 
 		}
 		}
 	};
 	};
-
 	UPNG._copyTile = function ( sb, sw, sh, tb, tw, th, xoff, yoff, mode ) {
 	UPNG._copyTile = function ( sb, sw, sh, tb, tw, th, xoff, yoff, mode ) {
 
 
 		var w = Math.min( sw, tw ),
 		var w = Math.min( sw, tw ),
 			h = Math.min( sh, th );
 			h = Math.min( sh, th );
 		var si = 0,
 		var si = 0,
 			ti = 0;
 			ti = 0;
-
 		for ( var y = 0; y < h; y ++ ) for ( var x = 0; x < w; x ++ ) {
 		for ( var y = 0; y < h; y ++ ) for ( var x = 0; x < w; x ++ ) {
 
 
 			if ( xoff >= 0 && yoff >= 0 ) {
 			if ( xoff >= 0 && yoff >= 0 ) {
@@ -1362,6 +1300,7 @@
 			} else if ( mode == 2 ) {
 			} else if ( mode == 2 ) {
 
 
 				// copy only differences, otherwise zero
 				// copy only differences, otherwise zero
+
 				var fa = sb[ si + 3 ],
 				var fa = sb[ si + 3 ],
 					fr = sb[ si ],
 					fr = sb[ si ],
 					fg = sb[ si + 1 ],
 					fg = sb[ si + 1 ],
@@ -1370,7 +1309,6 @@
 					br = tb[ ti ],
 					br = tb[ ti ],
 					bg = tb[ ti + 1 ],
 					bg = tb[ ti + 1 ],
 					bb = tb[ ti + 2 ];
 					bb = tb[ ti + 2 ];
-
 				if ( fa == ba && fr == br && fg == bg && fb == bb ) {
 				if ( fa == ba && fr == br && fg == bg && fb == bb ) {
 
 
 					tb[ ti ] = 0;
 					tb[ ti ] = 0;
@@ -1390,6 +1328,7 @@
 			} else if ( mode == 3 ) {
 			} else if ( mode == 3 ) {
 
 
 				// check if can be blended
 				// check if can be blended
+
 				var fa = sb[ si + 3 ],
 				var fa = sb[ si + 3 ],
 					fr = sb[ si ],
 					fr = sb[ si ],
 					fg = sb[ si + 1 ],
 					fg = sb[ si + 1 ],
@@ -1398,8 +1337,8 @@
 					br = tb[ ti ],
 					br = tb[ ti ],
 					bg = tb[ ti + 1 ],
 					bg = tb[ ti + 1 ],
 					bb = tb[ ti + 2 ];
 					bb = tb[ ti + 2 ];
-				if ( fa == ba && fr == br && fg == bg && fb == bb ) continue; //if(fa!=255 && ba!=0) return false;
-
+				if ( fa == ba && fr == br && fg == bg && fb == bb ) continue;
+				//if(fa!=255 && ba!=0) return false;
 				if ( fa < 220 && ba > 20 ) return false;
 				if ( fa < 220 && ba > 20 ) return false;
 
 
 			}
 			}

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