فهرست منبع

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

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

@@ -1,26 +1,17 @@
 ( function () {
 
 	const _q = new THREE.Quaternion();
-
 	const _targetPos = new THREE.Vector3();
-
 	const _targetVec = new THREE.Vector3();
-
 	const _effectorPos = new THREE.Vector3();
-
 	const _effectorVec = new THREE.Vector3();
-
 	const _linkPos = new THREE.Vector3();
-
 	const _invLinkQ = new THREE.Quaternion();
-
 	const _linkScale = new THREE.Vector3();
-
 	const _axis = new THREE.Vector3();
-
 	const _vector = new THREE.Vector3();
-
 	const _matrix = new THREE.Matrix4();
+
 	/**
  * CCD Algorithm
  *  - https://sites.google.com/site/auraliusproject/ccd-algorithm
@@ -41,7 +32,6 @@
  * } ];
  */
 
-
 	class CCDIKSolver {
 
 		/**
@@ -52,21 +42,18 @@
 
 			this.mesh = mesh;
 			this.iks = iks;
-
 			this._valid();
 
 		}
+
 		/**
    * Update all IK bones.
    *
    * @return {CCDIKSolver}
    */
-
-
 		update() {
 
 			const iks = this.iks;
-
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 				this.updateOne( iks[ i ] );
@@ -76,64 +63,55 @@
 			return this;
 
 		}
+
 		/**
    * Update one IK bone
    *
    * @param {Object} ik parameter
    * @return {CCDIKSolver}
    */
-
-
 		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 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 );
-
 			const links = ik.links;
 			const iteration = ik.iteration !== undefined ? ik.iteration : 1;
-
 			for ( let i = 0; i < iteration; i ++ ) {
 
 				let rotated = false;
-
 				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;
 					const limitation = links[ j ].limitation;
 					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 );
-
 					_invLinkQ.invert();
+					_effectorPos.setFromMatrixPosition( effector.matrixWorld );
 
-					_effectorPos.setFromMatrixPosition( effector.matrixWorld ); // work in link world
-
-
+					// work in link world
 					_effectorVec.subVectors( _effectorPos, _linkPos );
-
 					_effectorVec.applyQuaternion( _invLinkQ );
-
 					_effectorVec.normalize();
-
 					_targetVec.subVectors( _targetPos, _linkPos );
-
 					_targetVec.applyQuaternion( _invLinkQ );
-
 					_targetVec.normalize();
-
 					let angle = _targetVec.dot( _effectorVec );
-
 					if ( 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 ( ik.minAngle !== undefined && angle < ik.minAngle ) {
 
 						angle = ik.minAngle;
@@ -161,13 +139,11 @@
 					}
 
 					_axis.crossVectors( _effectorVec, _targetVec );
-
 					_axis.normalize();
-
 					_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 ) {
 
 						let c = link.quaternion.w;
@@ -201,25 +177,24 @@
 			return this;
 
 		}
+
 		/**
    * Creates Helper
    *
    * @return {CCDIKHelper}
    */
-
-
 		createHelper() {
 
 			return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks );
 
-		} // private methods
+		}
 
+		// private methods
 
 		_valid() {
 
 			const iks = this.iks;
 			const bones = this.mesh.skeleton.bones;
-
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 				const ik = iks[ i ];
@@ -227,11 +202,9 @@
 				const links = ik.links;
 				let link0, link1;
 				link0 = effector;
-
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 
 					link1 = bones[ links[ j ].index ];
-
 					if ( link0.parent !== link1 ) {
 
 						console.warn( 'THREE.CCDIKSolver: bone ' + link0.name + ' is not the child of bone ' + link1.name );
@@ -247,7 +220,6 @@
 		}
 
 	}
-
 	function getPosition( bone, matrixWorldInv ) {
 
 		return _vector.setFromMatrixPosition( bone.matrixWorld ).applyMatrix4( matrixWorldInv );
@@ -262,14 +234,13 @@
 		array[ index * 3 + 2 ] = v.z;
 
 	}
+
 	/**
  * Visualize IK bones
  *
  * @param {SkinnedMesh} mesh
  * @param {Array<Object>} iks
  */
-
-
 	class CCDIKHelper extends THREE.Object3D {
 
 		constructor( mesh, iks = [], sphereSize = 0.25 ) {
@@ -304,27 +275,22 @@
 				depthWrite: false,
 				transparent: true
 			} );
-
 			this._init();
 
 		}
+
 		/**
    * Updates IK bones visualization.
    */
-
-
 		updateMatrixWorld( force ) {
 
 			const mesh = this.root;
-
 			if ( this.visible ) {
 
 				let offset = 0;
 				const iks = this.iks;
 				const bones = mesh.skeleton.bones;
-
 				_matrix.copy( mesh.matrixWorld ).invert();
-
 				for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 					const ik = iks[ i ];
@@ -334,7 +300,6 @@
 					const effectorMesh = this.children[ offset ++ ];
 					targetMesh.position.copy( getPosition( targetBone, _matrix ) );
 					effectorMesh.position.copy( getPosition( effectorBone, _matrix ) );
-
 					for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 
 						const link = ik.links[ j ];
@@ -348,7 +313,6 @@
 					const array = line.geometry.attributes.position.array;
 					setPositionOfBoneToAttributeArray( array, 0, targetBone, _matrix );
 					setPositionOfBoneToAttributeArray( array, 1, effectorBone, _matrix );
-
 					for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 
 						const link = ik.links[ j ];
@@ -367,11 +331,10 @@
 			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.
    */
-
-
 		dispose() {
 
 			this.sphereGeometry.dispose();
@@ -380,7 +343,6 @@
 			this.linkSphereMaterial.dispose();
 			this.lineMaterial.dispose();
 			const children = this.children;
-
 			for ( let i = 0; i < children.length; i ++ ) {
 
 				const child = children[ i ];
@@ -388,14 +350,14 @@
 
 			}
 
-		} // private method
+		}
 
+		// private method
 
 		_init() {
 
 			const scope = this;
 			const iks = this.iks;
-
 			function createLineGeometry( ik ) {
 
 				const geometry = new THREE.BufferGeometry();
@@ -434,7 +396,6 @@
 				const ik = iks[ i ];
 				this.add( createTargetMesh() );
 				this.add( createEffectorMesh() );
-
 				for ( let j = 0, jl = ik.links.length; j < jl; j ++ ) {
 
 					this.add( createLinkMesh() );

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

@@ -12,7 +12,6 @@
  * TODO
  *  - more precise grant skinning support.
  */
-
 	class MMDAnimationHelper {
 
 		/**
@@ -43,16 +42,14 @@
 				physics: true,
 				cameraAnimation: true
 			};
+			this.onBeforePhysics = function /* mesh */ () {};
 
-			this.onBeforePhysics = function
-			/* mesh */
-			() {}; // experimental
-
-
+			// experimental
 			this.sharedPhysics = false;
 			this.masterPhysics = null;
 
 		}
+
 		/**
    * Adds an Three.js Object to helper and setups animation.
    * The anmation durations of added objects are synched
@@ -69,8 +66,6 @@
    * @param {Number} params.delayTime - Only for THREE.Audio. Default is 0.0.
    * @return {MMDAnimationHelper}
    */
-
-
 		add( object, params = {} ) {
 
 			if ( object.isSkinnedMesh ) {
@@ -95,14 +90,13 @@
 			return this;
 
 		}
+
 		/**
    * Removes an Three.js Object from helper.
    *
    * @param {THREE.SkinnedMesh|THREE.Camera|THREE.Audio} object
    * @return {MMDAnimationHelper}
    */
-
-
 		remove( object ) {
 
 			if ( object.isSkinnedMesh ) {
@@ -127,18 +121,16 @@
 			return this;
 
 		}
+
 		/**
    * Updates the animation.
    *
    * @param {Number} delta
    * @return {MMDAnimationHelper}
    */
-
-
 		update( delta ) {
 
 			if ( this.audioManager !== null ) this.audioManager.control( delta );
-
 			for ( let i = 0; i < this.meshes.length; i ++ ) {
 
 				this._animateMesh( this.meshes[ i ], delta );
@@ -150,6 +142,7 @@
 			return this;
 
 		}
+
 		/**
    * Changes the pose of SkinnedMesh as VPD specifies.
    *
@@ -161,15 +154,12 @@
    * @param {boolean} params.grant - Default is true.
    * @return {MMDAnimationHelper}
    */
-
-
 		pose( mesh, vpd, params = {} ) {
 
 			if ( params.resetPose !== false ) mesh.pose();
 			const bones = mesh.skeleton.bones;
 			const boneParams = vpd.bones;
 			const boneNameDictionary = {};
-
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
 				boneNameDictionary[ bones[ i ].name ] = i;
@@ -178,7 +168,6 @@
 
 			const vector = new THREE.Vector3();
 			const quaternion = new THREE.Quaternion();
-
 			for ( let i = 0, il = boneParams.length; i < il; 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' ) {
 
 				const sortedBonesData = this._sortBoneDataArray( mesh.geometry.userData.MMD.bones.slice() );
-
 				const ikSolver = params.ik !== false ? this._createCCDIKSolver( mesh ) : null;
 				const grantSolver = params.grant !== false ? this.createGrantSolver( mesh ) : null;
-
 				this._animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver );
 
 			} else {
@@ -220,6 +208,7 @@
 			return this;
 
 		}
+
 		/**
    * Enabes/Disables an animation feature.
    *
@@ -227,8 +216,6 @@
    * @param {boolean} enabled
    * @return {MMDAnimationHelper}
    */
-
-
 		enable( key, enabled ) {
 
 			if ( this.enabled[ key ] === undefined ) {
@@ -238,7 +225,6 @@
 			}
 
 			this.enabled[ key ] = enabled;
-
 			if ( key === 'physics' ) {
 
 				for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
@@ -252,20 +238,20 @@
 			return this;
 
 		}
+
 		/**
    * Creates an GrantSolver instance.
    *
    * @param {THREE.SkinnedMesh} mesh
    * @return {GrantSolver}
    */
-
-
 		createGrantSolver( mesh ) {
 
 			return new GrantSolver( mesh, mesh.geometry.userData.MMD.grants );
 
-		} // private methods
+		}
 
+		// private methods
 
 		_addMesh( mesh, params ) {
 
@@ -279,9 +265,7 @@
 			this.objects.set( mesh, {
 				looped: false
 			} );
-
 			this._setupMeshAnimation( mesh, params.animation );
-
 			if ( params.physics !== false ) {
 
 				this._setupMeshPhysics( mesh, params );
@@ -291,7 +275,6 @@
 			return this;
 
 		}
-
 		_setupCamera( camera, params ) {
 
 			if ( this.camera === camera ) {
@@ -304,7 +287,6 @@
 			this.camera = camera;
 			camera.add( this.cameraTarget );
 			this.objects.set( camera, {} );
-
 			if ( params.animation !== undefined ) {
 
 				this._setupCameraAnimation( camera, params.animation );
@@ -314,7 +296,6 @@
 			return this;
 
 		}
-
 		_setupAudio( audio, params ) {
 
 			if ( this.audio === audio ) {
@@ -332,12 +313,10 @@
 			return this;
 
 		}
-
 		_removeMesh( mesh ) {
 
 			let found = false;
 			let writeIndex = 0;
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 				if ( this.meshes[ i ] === mesh ) {
@@ -362,7 +341,6 @@
 			return this;
 
 		}
-
 		_clearCamera( camera ) {
 
 			if ( camera !== this.camera ) {
@@ -377,7 +355,6 @@
 			return this;
 
 		}
-
 		_clearAudio( audio ) {
 
 			if ( audio !== this.audio ) {
@@ -392,23 +369,20 @@
 			return this;
 
 		}
-
 		_setupMeshAnimation( mesh, animation ) {
 
 			const objects = this.objects.get( mesh );
-
 			if ( animation !== undefined ) {
 
 				const animations = Array.isArray( animation ) ? animation : [ animation ];
 				objects.mixer = new THREE.AnimationMixer( mesh );
-
 				for ( let i = 0, il = animations.length; i < il; i ++ ) {
 
 					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 ) {
 
 					const tracks = event.action._clip.tracks;
@@ -424,13 +398,11 @@
 			return this;
 
 		}
-
 		_setupCameraAnimation( camera, animation ) {
 
 			const animations = Array.isArray( animation ) ? animation : [ animation ];
 			const objects = this.objects.get( camera );
 			objects.mixer = new THREE.AnimationMixer( camera );
-
 			for ( let i = 0, il = animations.length; i < il; i ++ ) {
 
 				objects.mixer.clipAction( animations[ i ] ).play();
@@ -438,35 +410,31 @@
 			}
 
 		}
-
 		_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 ) {
 
 				const masterPhysics = this._getMasterPhysics();
-
 				if ( masterPhysics !== null ) world = masterPhysics.world; // eslint-disable-line no-undef
 
 			}
 
 			objects.physics = this._createMMDPhysics( mesh, params );
-
 			if ( objects.mixer && params.animationWarmup !== false ) {
 
 				this._animateMesh( mesh, 0 );
-
 				objects.physics.reset();
 
 			}
 
 			objects.physics.warmup( params.warmup !== undefined ? params.warmup : 60 );
-
 			this._optimizeIK( mesh, true );
 
 		}
-
 		_animateMesh( mesh, delta ) {
 
 			const objects = this.objects.get( mesh );
@@ -475,23 +443,20 @@
 			const grantSolver = objects.grantSolver;
 			const physics = objects.physics;
 			const looped = objects.looped;
-
 			if ( mixer && this.enabled.animation ) {
 
 				// alternate solution to save/restore bones but less performant?
 				//mesh.pose();
 				//this._updatePropertyMixersBuffer( mesh );
-				this._restoreBones( mesh );
 
+				this._restoreBones( mesh );
 				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 ( ! 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 );
 
 				} 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 this order.
-
-
 		_sortBoneDataArray( boneDataArray ) {
 
 			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
 		// possible but doesn't perfectly simulate.
 		// This method is more costly than the regular one so
 		// you are recommended to set constructor parameter "pmxAnimation: true"
 		// only if your PMX model animation doesn't work well.
 		// If you need better method you would be required to write your own.
-
-
 		_animatePMXMesh( mesh, sortedBonesData, ikSolver, grantSolver ) {
 
 			_quaternionIndex = 0;
-
 			_grantResultMap.clear();
-
 			for ( let i = 0, il = sortedBonesData.length; i < il; i ++ ) {
 
 				updateOne( mesh, sortedBonesData[ i ].index, ikSolver, grantSolver );
@@ -573,11 +536,9 @@
 			return this;
 
 		}
-
 		_animateCamera( camera, delta ) {
 
 			const mixer = this.objects.get( camera ).mixer;
-
 			if ( mixer && this.enabled.cameraAnimation ) {
 
 				mixer.update( delta );
@@ -589,21 +550,17 @@
 			}
 
 		}
-
 		_optimizeIK( mesh, physicsEnabled ) {
 
 			const iks = mesh.geometry.userData.MMD.iks;
 			const bones = mesh.geometry.userData.MMD.bones;
-
 			for ( let i = 0, il = iks.length; i < il; i ++ ) {
 
 				const ik = iks[ i ];
 				const links = ik.links;
-
 				for ( let j = 0, jl = links.length; j < jl; j ++ ) {
 
 					const link = links[ j ];
-
 					if ( physicsEnabled === true ) {
 
 						// disable IK of the bone the corresponding rigidBody type of which is 1 or 2
@@ -621,7 +578,6 @@
 			}
 
 		}
-
 		_createCCDIKSolver( mesh ) {
 
 			if ( THREE.CCDIKSolver === undefined ) {
@@ -633,7 +589,6 @@
 			return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks );
 
 		}
-
 		_createMMDPhysics( mesh, params ) {
 
 			if ( THREE.MMDPhysics === undefined ) {
@@ -645,29 +600,28 @@
 			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.
    * TODO: Not to access private properties ( ._actions and ._clip )
    */
-
-
 		_syncDuration() {
 
 			let max = 0.0;
 			const objects = this.objects;
 			const meshes = this.meshes;
 			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 ++ ) {
 
 				const mixer = this.objects.get( meshes[ i ] ).mixer;
 				if ( mixer === undefined ) continue;
-
 				for ( let j = 0; j < mixer._actions.length; j ++ ) {
 
 					const clip = mixer._actions[ j ]._clip;
-
 					if ( ! objects.has( clip ) ) {
 
 						objects.set( clip, {
@@ -685,13 +639,11 @@
 			if ( camera !== null ) {
 
 				const mixer = this.objects.get( camera ).mixer;
-
 				if ( mixer !== undefined ) {
 
 					for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) {
 
 						const clip = mixer._actions[ i ]._clip;
-
 						if ( ! objects.has( 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 ++ ) {
 
 				const mixer = this.objects.get( this.meshes[ i ] ).mixer;
 				if ( mixer === undefined ) continue;
-
 				for ( let j = 0, jl = mixer._actions.length; j < jl; j ++ ) {
 
 					mixer._actions[ j ]._clip.duration = max;
@@ -732,7 +685,6 @@
 			if ( camera !== null ) {
 
 				const mixer = this.objects.get( camera ).mixer;
-
 				if ( mixer !== undefined ) {
 
 					for ( let i = 0, il = mixer._actions.length; i < il; i ++ ) {
@@ -751,15 +703,15 @@
 
 			}
 
-		} // workaround
+		}
 
+		// workaround
 
 		_updatePropertyMixersBuffer( mesh ) {
 
 			const mixer = this.objects.get( mesh ).mixer;
 			const propertyMixers = mixer._bindings;
 			const accuIndex = mixer._accuIndex;
-
 			for ( let i = 0, il = propertyMixers.length; i < il; i ++ ) {
 
 				const propertyMixer = propertyMixers[ i ];
@@ -771,6 +723,7 @@
 			}
 
 		}
+
 		/*
    * 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.
    */
-
-
 		_saveBones( mesh ) {
 
 			const objects = this.objects.get( mesh );
 			const bones = mesh.skeleton.bones;
 			let backupBones = objects.backupBones;
-
 			if ( backupBones === undefined ) {
 
 				backupBones = new Float32Array( bones.length * 7 );
@@ -804,14 +754,12 @@
 			}
 
 		}
-
 		_restoreBones( mesh ) {
 
 			const objects = this.objects.get( mesh );
 			const backupBones = objects.backupBones;
 			if ( backupBones === undefined ) return;
 			const bones = mesh.skeleton.bones;
-
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
 				const bone = bones[ i ];
@@ -820,17 +768,16 @@
 
 			}
 
-		} // experimental
+		}
 
+		// experimental
 
 		_getMasterPhysics() {
 
 			if ( this.masterPhysics !== null ) return this.masterPhysics;
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 				const physics = this.meshes[ i ].physics;
-
 				if ( physics !== undefined && physics !== null ) {
 
 					this.masterPhysics = physics;
@@ -843,19 +790,14 @@
 			return null;
 
 		}
-
 		_updateSharedPhysics( delta ) {
 
 			if ( this.meshes.length === 0 || ! this.enabled.physics || ! this.sharedPhysics ) return;
-
 			const physics = this._getMasterPhysics();
-
 			if ( physics === null ) return;
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 				const p = this.meshes[ i ].physics;
-
 				if ( p !== null && p !== undefined ) {
 
 					p.updateRigidBodies();
@@ -865,11 +807,9 @@
 			}
 
 			physics.stepSimulation( delta );
-
 			for ( let i = 0, il = this.meshes.length; i < il; i ++ ) {
 
 				const p = this.meshes[ i ].physics;
-
 				if ( p !== null && p !== undefined ) {
 
 					p.updateBones();
@@ -880,12 +820,11 @@
 
 		}
 
-	} // Keep working quaternions for less GC
-
+	}
 
+	// Keep working quaternions for less GC
 	const _quaternions = [];
 	let _quaternionIndex = 0;
-
 	function getQuaternion() {
 
 		if ( _quaternionIndex >= _quaternions.length ) {
@@ -896,33 +835,33 @@
 
 		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();
-
 	function updateOne( mesh, boneIndex, ikSolver, grantSolver ) {
 
 		const bones = mesh.skeleton.bones;
 		const bonesData = mesh.geometry.userData.MMD.bones;
 		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;
-		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
 		// result without applyting IK or grant is gotten
 		// 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 ) {
 
 			const parentIndex = boneData.grant.parentIndex;
 			const ratio = boneData.grant.ratio;
-
 			if ( ! _grantResultMap.has( parentIndex ) ) {
 
 				updateOne( mesh, parentIndex, ikSolver, grantSolver );
@@ -938,16 +877,15 @@
 			// @TODO: Updating world matrices every time solving an IK bone is
 			// costly. Optimize if possible.
 			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;
-
 			for ( let i = 0, il = links.length; i < il; i ++ ) {
 
 				const link = links[ i ];
 				if ( link.enabled === false ) continue;
 				const linkIndex = link.index;
-
 				if ( _grantResultMap.has( linkIndex ) ) {
 
 					_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 );
 
-	} //
+	}
 
+	//
 
 	class AudioManager {
 
@@ -981,12 +920,11 @@
 			this.duration = this.audioDuration + this.delayTime;
 
 		}
+
 		/**
    * @param {Number} delta
    * @return {AudioManager}
    */
-
-
 		control( delta ) {
 
 			this.elapsed += delta;
@@ -995,26 +933,26 @@
 			if ( this._shouldStartAudio() ) this.audio.play();
 			return this;
 
-		} // private methods
+		}
 
+		// private methods
 
 		_shouldStartAudio() {
 
 			if ( this.audio.isPlaying ) return false;
-
 			while ( 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;
 			return true;
 
 		}
-
 		_shouldStopAudio() {
 
 			return this.audio.isPlaying && this.currentTime >= this.duration;
@@ -1022,8 +960,8 @@
 		}
 
 	}
-
 	const _q = new THREE.Quaternion();
+
 	/**
  * 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.)
@@ -1032,8 +970,6 @@
  * @param {THREE.SkinnedMesh} mesh
  * @param {Array<Object>} grants
  */
-
-
 	class GrantSolver {
 
 		constructor( mesh, grants = [] ) {
@@ -1042,16 +978,14 @@
 			this.grants = grants;
 
 		}
+
 		/**
    * Solve all the grant bones
    * @return {GrantSolver}
    */
-
-
 		update() {
 
 			const grants = this.grants;
-
 			for ( let i = 0, il = grants.length; i < il; i ++ ) {
 
 				this.updateOne( grants[ i ] );
@@ -1061,25 +995,23 @@
 			return this;
 
 		}
+
 		/**
    * Solve a grant bone
    * @param {Object} grant - grant parameter
    * @return {GrantSolver}
    */
-
-
 		updateOne( grant ) {
 
 			const bones = this.mesh.skeleton.bones;
 			const bone = bones[ grant.index ];
 			const parentBone = bones[ grant.parentIndex ];
-
 			if ( grant.isLocal ) {
 
 				// TODO: implement
-				if ( grant.affectPosition ) {} // TODO: implement
-
+				if ( grant.affectPosition ) {}
 
+				// TODO: implement
 				if ( grant.affectRotation ) {}
 
 			} else {
@@ -1098,13 +1030,10 @@
 			return this;
 
 		}
-
 		addGrantRotation( bone, q, ratio ) {
 
 			_q.set( 0, 0, 0, 1 );
-
 			_q.slerp( q, ratio );
-
 			bone.quaternion.multiply( _q );
 			return this;
 

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

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

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

@@ -20,29 +20,31 @@
 				fragmentShader: depthShader.fragmentShader
 			} );
 			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.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
 		// 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 ) {
 
 			this.filmGauge = filmGauge;
 			this.setFocalLength( focalLength );
 			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 );
 
 		}
-
 		linearize( depth ) {
 
 			const zfar = this.far;
@@ -50,40 +52,42 @@
 			return - zfar * znear / ( depth * ( zfar - znear ) - zfar );
 
 		}
-
 		smoothstep( near, far, depth ) {
 
 			const x = this.saturate( ( depth - near ) / ( far - near ) );
 			return x * x * ( 3 - 2 * x );
 
 		}
-
 		saturate( 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 ) {
 
-			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;
 			this.sdistance = this.smoothstep( this.near, this.far, this.focus );
 			this.ldistance = this.linearize( 1 - this.sdistance );
 			this.postprocessing.bokeh_uniforms[ 'focalDepth' ].value = this.ldistance;
 
 		}
-
 		initPostProcessing() {
 
 			if ( this.postprocessing.enabled ) {
@@ -101,7 +105,9 @@
 				this.postprocessing.bokeh_uniforms[ 'shaderFocus' ].value = 0;
 				this.postprocessing.bokeh_uniforms[ 'fstop' ].value = 2.8;
 				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[ 'zfar' ].value = this.near;
@@ -124,23 +130,28 @@
 			}
 
 		}
-
 		renderCinematic( scene, renderer ) {
 
 			if ( this.postprocessing.enabled ) {
 
 				const currentRenderTarget = renderer.getRenderTarget();
-				renderer.clear(); // Render scene into texture
+				renderer.clear();
+
+				// Render scene into texture
 
 				scene.overrideMaterial = null;
 				renderer.setRenderTarget( this.postprocessing.rtTextureColor );
 				renderer.clear();
-				renderer.render( scene, this ); // Render depth into texture
+				renderer.render( scene, this );
+
+				// Render depth into texture
 
 				scene.overrideMaterial = this.materialDepth;
 				renderer.setRenderTarget( this.postprocessing.rtTextureDepth );
 				renderer.clear();
-				renderer.render( scene, this ); // Render bokeh composite
+				renderer.render( scene, this );
+
+				// Render bokeh composite
 
 				renderer.setRenderTarget( null );
 				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 () {
 
 	const _plane = new THREE.Plane();
-
 	const _raycaster = new THREE.Raycaster();
-
 	const _pointer = new THREE.Vector2();
-
 	const _offset = new THREE.Vector3();
-
 	const _intersection = new THREE.Vector3();
-
 	const _worldPosition = new THREE.Vector3();
-
 	const _inverseMatrix = new THREE.Matrix4();
-
 	class DragControls extends THREE.EventDispatcher {
 
 		constructor( _objects, _camera, _domElement ) {
@@ -23,18 +16,16 @@
 
 			let _selected = null,
 				_hovered = null;
-			const _intersections = []; //
+			const _intersections = [];
 
-			const scope = this;
+			//
 
+			const scope = this;
 			function activate() {
 
 				_domElement.addEventListener( 'pointermove', onPointerMove );
-
 				_domElement.addEventListener( 'pointerdown', onPointerDown );
-
 				_domElement.addEventListener( 'pointerup', onPointerCancel );
-
 				_domElement.addEventListener( 'pointerleave', onPointerCancel );
 
 			}
@@ -42,13 +33,9 @@
 			function deactivate() {
 
 				_domElement.removeEventListener( 'pointermove', onPointerMove );
-
 				_domElement.removeEventListener( 'pointerdown', onPointerDown );
-
 				_domElement.removeEventListener( 'pointerup', onPointerCancel );
-
 				_domElement.removeEventListener( 'pointerleave', onPointerCancel );
-
 				_domElement.style.cursor = '';
 
 			}
@@ -75,9 +62,7 @@
 
 				if ( scope.enabled === false ) return;
 				updatePointer( event );
-
 				_raycaster.setFromCamera( _pointer, _camera );
-
 				if ( _selected ) {
 
 					if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
@@ -92,23 +77,19 @@
 					} );
 					return;
 
-				} // hover support
+				}
 
+				// hover support
 
 				if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
 
 					_intersections.length = 0;
-
 					_raycaster.setFromCamera( _pointer, _camera );
-
 					_raycaster.intersectObjects( _objects, true, _intersections );
-
 					if ( _intersections.length > 0 ) {
 
 						const object = _intersections[ 0 ].object;
-
 						_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
-
 						if ( _hovered !== object && _hovered !== null ) {
 
 							scope.dispatchEvent( {
@@ -155,21 +136,15 @@
 				if ( scope.enabled === false ) return;
 				updatePointer( event );
 				_intersections.length = 0;
-
 				_raycaster.setFromCamera( _pointer, _camera );
-
 				_raycaster.intersectObjects( _objects, true, _intersections );
-
 				if ( _intersections.length > 0 ) {
 
 					_selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object;
-
 					_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
-
 					if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
 						_inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
-
 						_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 
 					}
@@ -187,7 +162,6 @@
 			function onPointerCancel() {
 
 				if ( scope.enabled === false ) return;
-
 				if ( _selected ) {
 
 					scope.dispatchEvent( {
@@ -205,13 +179,14 @@
 			function updatePointer( event ) {
 
 				const rect = _domElement.getBoundingClientRect();
-
 				_pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
 				_pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
 
 			}
 
-			activate(); // API
+			activate();
+
+			// API
 
 			this.enabled = true;
 			this.transformGroup = false;

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

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

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

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

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

@@ -1,5 +1,6 @@
 ( function () {
 
+	// This set of controls performs orbiting, dollying (zooming), and panning.
 	// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
 	//
 	//    Orbit - left mouse / touch: one-finger move
@@ -15,7 +16,6 @@
 	const _endEvent = {
 		type: 'end'
 	};
-
 	class OrbitControls extends THREE.EventDispatcher {
 
 		constructor( object, domElement ) {
@@ -24,76 +24,86 @@
 			this.object = object;
 			this.domElement = domElement;
 			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.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.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.maxPolarAngle = Math.PI; // radians
+
 			// 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 )
-
 			this.minAzimuthAngle = - Infinity; // radians
-
 			this.maxAzimuthAngle = Infinity; // radians
+
 			// Set to true to enable damping (inertia)
 			// If damping is enabled, you must call controls.update() in your animation loop
-
 			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.zoomSpeed = 1.0; // Set to false to disable rotating
+			this.zoomSpeed = 1.0;
 
+			// Set to false to disable rotating
 			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.panSpeed = 1.0;
 			this.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up
-
 			this.keyPanSpeed = 7.0; // pixels moved per arrow key push
+
 			// Set to true to automatically rotate around the target
 			// If auto-rotate is enabled, you must call controls.update() in your animation loop
-
 			this.autoRotate = false;
 			this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60
-			// The four arrow keys
 
+			// The four arrow keys
 			this.keys = {
 				LEFT: 'ArrowLeft',
 				UP: 'ArrowUp',
 				RIGHT: 'ArrowRight',
 				BOTTOM: 'ArrowDown'
-			}; // Mouse buttons
+			};
 
+			// Mouse buttons
 			this.mouseButtons = {
 				LEFT: THREE.MOUSE.ROTATE,
 				MIDDLE: THREE.MOUSE.DOLLY,
 				RIGHT: THREE.MOUSE.PAN
-			}; // Touch fingers
+			};
 
+			// Touch fingers
 			this.touches = {
 				ONE: THREE.TOUCH.ROTATE,
 				TWO: THREE.TOUCH.DOLLY_PAN
-			}; // for reset
+			};
 
+			// for reset
 			this.target0 = this.target.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
 			//
 
@@ -140,13 +150,14 @@
 				scope.update();
 				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 () {
 
-				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 quatInverse = quat.clone().invert();
 				const lastPosition = new THREE.Vector3();
@@ -155,12 +166,13 @@
 				return function update() {
 
 					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 );
-
 					if ( scope.autoRotate && state === STATE.NONE ) {
 
 						rotateLeft( getAutoRotationAngle() );
@@ -177,17 +189,16 @@
 						spherical.theta += sphericalDelta.theta;
 						spherical.phi += sphericalDelta.phi;
 
-					} // restrict theta to be between desired limits
+					}
 
+					// restrict theta to be between desired limits
 
 					let min = scope.minAzimuthAngle;
 					let max = scope.maxAzimuthAngle;
-
 					if ( isFinite( min ) && isFinite( max ) ) {
 
 						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 ( min <= max ) {
 
 							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.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 ) {
 
@@ -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 );
 					position.copy( scope.target ).add( offset );
 					scope.object.lookAt( scope.target );
-
 					if ( scope.enableDamping === true ) {
 
 						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
 					// using small-angle approximation cos(x/2) = 1 - x^2 / 8
 
@@ -255,7 +271,6 @@
 				};
 
 			}();
-
 			this.dispose = function () {
 
 				scope.domElement.removeEventListener( 'contextmenu', onContextMenu );
@@ -264,18 +279,20 @@
 				scope.domElement.removeEventListener( 'wheel', onMouseWheel );
 				scope.domElement.removeEventListener( 'pointermove', onPointerMove );
 				scope.domElement.removeEventListener( 'pointerup', onPointerUp );
-
 				if ( scope._domElementKeyEvents !== null ) {
 
 					scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
 
-				} //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
+				}
+
+				//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
+
+			};
 
-			}; //
+			//
 			// internals
 			//
 
-
 			const scope = this;
 			const STATE = {
 				NONE: - 1,
@@ -288,8 +305,9 @@
 				TOUCH_DOLLY_ROTATE: 6
 			};
 			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 sphericalDelta = new THREE.Spherical();
 			let scale = 1;
@@ -306,7 +324,6 @@
 			const dollyDelta = new THREE.Vector2();
 			const pointers = [];
 			const pointerPositions = {};
-
 			function getAutoRotationAngle() {
 
 				return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
@@ -337,14 +354,12 @@
 				return function panLeft( distance, objectMatrix ) {
 
 					v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
-
 					v.multiplyScalar( - distance );
 					panOffset.add( v );
 
 				};
 
 			}();
-
 			const panUp = function () {
 
 				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 offset = new THREE.Vector3();
 				return function pan( deltaX, deltaY ) {
 
 					const element = scope.domElement;
-
 					if ( scope.object.isPerspectiveCamera ) {
 
 						// perspective
 						const position = scope.object.position;
 						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 );
 						panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
 
@@ -405,7 +421,6 @@
 				};
 
 			}();
-
 			function dollyOut( dollyScale ) {
 
 				if ( scope.object.isPerspectiveCamera ) {
@@ -446,11 +461,12 @@
 
 				}
 
-			} //
+			}
+
+			//
 			// event callbacks - update the object state
 			//
 
-
 			function handleMouseDownRotate( event ) {
 
 				rotateStart.set( event.clientX, event.clientY );
@@ -486,7 +502,6 @@
 
 				dollyEnd.set( event.clientX, event.clientY );
 				dollyDelta.subVectors( dollyEnd, dollyStart );
-
 				if ( dollyDelta.y > 0 ) {
 
 					dollyOut( getZoomScale() );
@@ -531,24 +546,20 @@
 			function handleKeyDown( event ) {
 
 				let needsUpdate = false;
-
 				switch ( event.code ) {
 
 					case scope.keys.UP:
 						pan( 0, scope.keyPanSpeed );
 						needsUpdate = true;
 						break;
-
 					case scope.keys.BOTTOM:
 						pan( 0, - scope.keyPanSpeed );
 						needsUpdate = true;
 						break;
-
 					case scope.keys.LEFT:
 						pan( scope.keyPanSpeed, 0 );
 						needsUpdate = true;
 						break;
-
 					case scope.keys.RIGHT:
 						pan( - scope.keyPanSpeed, 0 );
 						needsUpdate = true;
@@ -691,26 +702,26 @@
 				if ( scope.enableZoom ) handleTouchMoveDolly( event );
 				if ( scope.enableRotate ) handleTouchMoveRotate( event );
 
-			} //
+			}
+
+			//
 			// event handlers - FSM: listen for events and reset state
 			//
 
-
 			function onPointerDown( event ) {
 
 				if ( scope.enabled === false ) return;
-
 				if ( pointers.length === 0 ) {
 
 					scope.domElement.setPointerCapture( event.pointerId );
 					scope.domElement.addEventListener( 'pointermove', onPointerMove );
 					scope.domElement.addEventListener( 'pointerup', onPointerUp );
 
-				} //
+				}
 
+				//
 
 				addPointer( event );
-
 				if ( event.pointerType === 'touch' ) {
 
 					onTouchStart( event );
@@ -726,7 +737,6 @@
 			function onPointerMove( event ) {
 
 				if ( scope.enabled === false ) return;
-
 				if ( event.pointerType === 'touch' ) {
 
 					onTouchMove( event );
@@ -742,7 +752,6 @@
 			function onPointerUp( event ) {
 
 				removePointer( event );
-
 				if ( pointers.length === 0 ) {
 
 					scope.domElement.releasePointerCapture( event.pointerId );
@@ -765,21 +774,17 @@
 			function onMouseDown( event ) {
 
 				let mouseAction;
-
 				switch ( event.button ) {
 
 					case 0:
 						mouseAction = scope.mouseButtons.LEFT;
 						break;
-
 					case 1:
 						mouseAction = scope.mouseButtons.MIDDLE;
 						break;
-
 					case 2:
 						mouseAction = scope.mouseButtons.RIGHT;
 						break;
-
 					default:
 						mouseAction = - 1;
 
@@ -792,7 +797,6 @@
 						handleMouseDownDolly( event );
 						state = STATE.DOLLY;
 						break;
-
 					case THREE.MOUSE.ROTATE:
 						if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
 
@@ -809,7 +813,6 @@
 						}
 
 						break;
-
 					case THREE.MOUSE.PAN:
 						if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
 
@@ -826,7 +829,6 @@
 						}
 
 						break;
-
 					default:
 						state = STATE.NONE;
 
@@ -848,12 +850,10 @@
 						if ( scope.enableRotate === false ) return;
 						handleMouseMoveRotate( event );
 						break;
-
 					case STATE.DOLLY:
 						if ( scope.enableZoom === false ) return;
 						handleMouseMoveDolly( event );
 						break;
-
 					case STATE.PAN:
 						if ( scope.enablePan === false ) return;
 						handleMouseMovePan( event );
@@ -883,7 +883,6 @@
 			function onTouchStart( event ) {
 
 				trackPointer( event );
-
 				switch ( pointers.length ) {
 
 					case 1:
@@ -894,20 +893,17 @@
 								handleTouchStartRotate();
 								state = STATE.TOUCH_ROTATE;
 								break;
-
 							case THREE.TOUCH.PAN:
 								if ( scope.enablePan === false ) return;
 								handleTouchStartPan();
 								state = STATE.TOUCH_PAN;
 								break;
-
 							default:
 								state = STATE.NONE;
 
 						}
 
 						break;
-
 					case 2:
 						switch ( scope.touches.TWO ) {
 
@@ -916,20 +912,17 @@
 								handleTouchStartDollyPan();
 								state = STATE.TOUCH_DOLLY_PAN;
 								break;
-
 							case THREE.TOUCH.DOLLY_ROTATE:
 								if ( scope.enableZoom === false && scope.enableRotate === false ) return;
 								handleTouchStartDollyRotate();
 								state = STATE.TOUCH_DOLLY_ROTATE;
 								break;
-
 							default:
 								state = STATE.NONE;
 
 						}
 
 						break;
-
 					default:
 						state = STATE.NONE;
 
@@ -946,7 +939,6 @@
 			function onTouchMove( event ) {
 
 				trackPointer( event );
-
 				switch ( state ) {
 
 					case STATE.TOUCH_ROTATE:
@@ -954,25 +946,21 @@
 						handleTouchMoveRotate( event );
 						scope.update();
 						break;
-
 					case STATE.TOUCH_PAN:
 						if ( scope.enablePan === false ) return;
 						handleTouchMovePan( event );
 						scope.update();
 						break;
-
 					case STATE.TOUCH_DOLLY_PAN:
 						if ( scope.enableZoom === false && scope.enablePan === false ) return;
 						handleTouchMoveDollyPan( event );
 						scope.update();
 						break;
-
 					case STATE.TOUCH_DOLLY_ROTATE:
 						if ( scope.enableZoom === false && scope.enableRotate === false ) return;
 						handleTouchMoveDollyRotate( event );
 						scope.update();
 						break;
-
 					default:
 						state = STATE.NONE;
 
@@ -996,7 +984,6 @@
 			function removePointer( event ) {
 
 				delete pointerPositions[ event.pointerId ];
-
 				for ( let i = 0; i < pointers.length; i ++ ) {
 
 					if ( pointers[ i ].pointerId == event.pointerId ) {
@@ -1013,7 +1000,6 @@
 			function trackPointer( event ) {
 
 				let position = pointerPositions[ event.pointerId ];
-
 				if ( position === undefined ) {
 
 					position = new THREE.Vector2();
@@ -1030,21 +1016,26 @@
 				const pointer = event.pointerId === pointers[ 0 ].pointerId ? pointers[ 1 ] : pointers[ 0 ];
 				return pointerPositions[ pointer.pointerId ];
 
-			} //
+			}
 
+			//
 
 			scope.domElement.addEventListener( 'contextmenu', onContextMenu );
 			scope.domElement.addEventListener( 'pointerdown', onPointerDown );
 			scope.domElement.addEventListener( 'pointercancel', onPointerCancel );
 			scope.domElement.addEventListener( 'wheel', onMouseWheel, {
 				passive: false
-			} ); // force an update at start
+			} );
+
+			// force an update at start
 
 			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).
 	// 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
 	//    Pan - left mouse, or arrow keys / touch: one-finger move
 
-
 	class MapControls extends OrbitControls {
 
 		constructor( object, domElement ) {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -11,24 +11,15 @@
 
 	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();
 			this.degree = degree;
 			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.endKnot = endKnot || this.knots.length - 1;
-
 			for ( let i = 0; i < controlPoints.length; ++ i ) {
 
 				// ensure THREE.Vector4 for control points
@@ -38,15 +29,13 @@
 			}
 
 		}
-
 		getPoint( t, optionalTarget = new THREE.Vector3() ) {
 
 			const point = optionalTarget;
 			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 );
-
 			if ( hpoint.w !== 1.0 ) {
 
 				// 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 );
 
 		}
-
 		getTangent( t, optionalTarget = new THREE.Vector3() ) {
 
 			const tangent = optionalTarget;

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

@@ -8,11 +8,7 @@
 
 	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.degree2 = degree2;
@@ -20,12 +16,12 @@
 			this.knots2 = knots2;
 			this.controlPoints = [];
 			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 ) {
 
 				this.controlPoints[ i ] = [];
-
 				for ( let j = 0; j < len2; ++ j ) {
 
 					const point = controlPoints[ i ][ j ];
@@ -36,11 +32,9 @@
 			}
 
 		}
-
 		getPoint( t1, t2, target ) {
 
 			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
 
 			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
 */
-
 	function findSpan( p, u, U ) {
 
 		const n = U.length - p - 1;
-
 		if ( u >= U[ n ] ) {
 
 			return n - 1;
@@ -39,7 +37,6 @@ returns the span
 		let low = p;
 		let high = n;
 		let mid = Math.floor( ( low + high ) / 2 );
-
 		while ( u < U[ mid ] || u >= U[ mid + 1 ] ) {
 
 			if ( u < U[ mid ] ) {
@@ -59,6 +56,7 @@ returns the span
 		return mid;
 
 	}
+
 	/*
 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.
 */
-
-
 	function calcBasisFunctions( span, u, p, U ) {
 
 		const N = [];
 		const left = [];
 		const right = [];
 		N[ 0 ] = 1.0;
-
 		for ( let j = 1; j <= p; ++ j ) {
 
 			left[ j ] = u - U[ span + 1 - j ];
 			right[ j ] = U[ span + j ] - u;
 			let saved = 0.0;
-
 			for ( let r = 0; r < j; ++ r ) {
 
 				const rv = right[ r + 1 ];
@@ -101,6 +95,7 @@ returns array[p+1] with basis functions values.
 		return N;
 
 	}
+
 	/*
 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
 */
-
-
 	function calcBSplinePoint( p, U, P, u ) {
 
 		const span = findSpan( p, u, U );
 		const N = calcBasisFunctions( span, u, p, U );
 		const C = new THREE.Vector4( 0, 0, 0, 0 );
-
 		for ( let j = 0; j <= p; ++ j ) {
 
 			const point = P[ span - p + j ];
@@ -134,6 +126,7 @@ returns point for given u
 		return C;
 
 	}
+
 	/*
 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
 */
-
-
 	function calcBasisFunctionDerivatives( span, u, p, n, U ) {
 
 		const zeroArr = [];
-
 		for ( let i = 0; i <= p; ++ i ) zeroArr[ i ] = 0.0;
-
 		const ders = [];
-
 		for ( let i = 0; i <= n; ++ i ) ders[ i ] = zeroArr.slice( 0 );
-
 		const ndu = [];
-
 		for ( let i = 0; i <= p; ++ i ) ndu[ i ] = zeroArr.slice( 0 );
-
 		ndu[ 0 ][ 0 ] = 1.0;
 		const left = zeroArr.slice( 0 );
 		const right = zeroArr.slice( 0 );
-
 		for ( let j = 1; j <= p; ++ j ) {
 
 			left[ j ] = u - U[ span + 1 - j ];
 			right[ j ] = U[ span + j ] - u;
 			let saved = 0.0;
-
 			for ( let r = 0; r < j; ++ r ) {
 
 				const rv = right[ r + 1 ];
@@ -197,7 +180,6 @@ returns array[n+1][p+1] with basis functions derivatives
 			let s1 = 0;
 			let s2 = 1;
 			const a = [];
-
 			for ( let i = 0; i <= p; ++ i ) {
 
 				a[ i ] = zeroArr.slice( 0 );
@@ -205,13 +187,11 @@ returns array[n+1][p+1] with basis functions derivatives
 			}
 
 			a[ 0 ][ 0 ] = 1.0;
-
 			for ( let k = 1; k <= n; ++ k ) {
 
 				let d = 0.0;
 				const rk = r - k;
 				const pk = p - k;
-
 				if ( r >= k ) {
 
 					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 j2 = r - 1 <= pk ? k - 1 : p - r;
-
 				for ( let j = j1; j <= j2; ++ 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;
-
 		for ( let k = 1; k <= n; ++ k ) {
 
 			for ( let j = 0; j <= p; ++ j ) {
@@ -262,6 +240,7 @@ returns array[n+1][p+1] with basis functions derivatives
 		return ders;
 
 	}
+
 	/*
 	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
 	*/
-
-
 	function calcBSplineDerivatives( p, U, P, u, nd ) {
 
 		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 nders = calcBasisFunctionDerivatives( span, u, p, du, U );
 		const Pw = [];
-
 		for ( let i = 0; i < P.length; ++ i ) {
 
 			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 ) {
 
 			const point = Pw[ span - p ].clone().multiplyScalar( nders[ k ][ 0 ] );
-
 			for ( let j = 1; j <= p; ++ 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;
 
 	}
+
 	/*
 Calculate "K over I"
 
 returns k!/(i!(k-i)!)
 */
-
-
 	function calcKoverI( k, i ) {
 
 		let nom = 1;
-
 		for ( let j = 2; j <= k; ++ j ) {
 
 			nom *= j;
@@ -335,7 +308,6 @@ returns k!/(i!(k-i)!)
 		}
 
 		let denom = 1;
-
 		for ( let j = 2; j <= i; ++ j ) {
 
 			denom *= j;
@@ -351,6 +323,7 @@ returns k!/(i!(k-i)!)
 		return nom / denom;
 
 	}
+
 	/*
 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.
 */
-
-
 	function calcRationalCurveDerivatives( Pders ) {
 
 		const nd = Pders.length;
 		const Aders = [];
 		const wders = [];
-
 		for ( let i = 0; i < nd; ++ i ) {
 
 			const point = Pders[ i ];
@@ -375,11 +345,9 @@ returns array with derivatives for rational curve.
 		}
 
 		const CK = [];
-
 		for ( let k = 0; k < nd; ++ k ) {
 
 			const v = Aders[ k ].clone();
-
 			for ( let i = 1; i <= k; ++ 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;
 
 	}
+
 	/*
 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.
 */
-
-
 	function calcNURBSDerivatives( p, U, P, u, nd ) {
 
 		const Pders = calcBSplineDerivatives( p, U, P, u, nd );
 		return calcRationalCurveDerivatives( Pders );
 
 	}
+
 	/*
 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)
 */
-
-
 	function calcSurfacePoint( p, q, U, V, P, u, v, target ) {
 
 		const uspan = findSpan( p, u, U );
@@ -431,11 +397,9 @@ returns point for given (u, v)
 		const Nu = calcBasisFunctions( uspan, u, p, U );
 		const Nv = calcBasisFunctions( vspan, v, q, V );
 		const temp = [];
-
 		for ( let l = 0; l <= q; ++ l ) {
 
 			temp[ l ] = new THREE.Vector4( 0, 0, 0, 0 );
-
 			for ( let k = 0; k <= p; ++ k ) {
 
 				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 );
-
 		for ( let l = 0; l <= q; ++ 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 ) {
 
 			// 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.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 _scene = new THREE.Scene();
-
 			const _stereo = new THREE.StereoCamera();
-
 			const _params = {
 				minFilter: THREE.LinearFilter,
 				magFilter: THREE.NearestFilter,
 				format: THREE.RGBAFormat
 			};
-
 			const _renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
-
 			const _renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
-
 			const _material = new THREE.ShaderMaterial( {
 				uniforms: {
 					'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' ),
-				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' )
 			} );
-
 			const _mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), _material );
-
 			_scene.add( _mesh );
-
 			this.setSize = function ( width, height ) {
 
 				renderer.setSize( width, height );
 				const pixelRatio = renderer.getPixelRatio();
-
 				_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
-
 				_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
 
 			};
@@ -64,9 +55,7 @@
 				const currentRenderTarget = renderer.getRenderTarget();
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
 				_stereo.update( camera );
-
 				renderer.setRenderTarget( _renderTargetL );
 				renderer.clear();
 				renderer.render( scene, _stereo.cameraL );
@@ -82,11 +71,8 @@
 			this.dispose = function () {
 
 				_renderTargetL.dispose();
-
 				_renderTargetR.dispose();
-
 				_mesh.geometry.dispose();
-
 				_mesh.material.dispose();
 
 			};

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

@@ -5,6 +5,7 @@
  *
  * 16 April 2012 - @blurspline
  */
+
 	class AsciiEffect {
 
 		constructor( renderer, charSet = ' .:-=+*#%@', options = {} ) {
@@ -12,18 +13,15 @@
 			// ' .,:;=|iI+hHOE#`$';
 			// darker bolder character set from https://github.com/saw/Canvas-ASCII-Art/
 			// ' .\'`^",:;Il!i~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$'.split('');
+
 			// 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 bColor = options[ 'color' ] || false; // nice but slows down rendering!
-
 			const bAlpha = options[ 'alpha' ] || false; // Transparency
-
 			const bBlock = options[ 'block' ] || false; // blocked characters. like good O dos
-
 			const bInvert = options[ 'invert' ] || false; // black is white, white is black
-
 			const strResolution = options[ 'strResolution' ] || 'low';
 			let width, height;
 			const domElement = document.createElement( 'div' );
@@ -32,7 +30,6 @@
 			domElement.appendChild( oAscii );
 			let iWidth, iHeight;
 			let oImg;
-
 			this.setSize = function ( w, h ) {
 
 				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() {
 
 				iWidth = Math.round( width * fResolution );
 				iHeight = Math.round( height * fResolution );
 				oCanvas.width = iWidth;
-				oCanvas.height = iHeight; // oCanvas.style.display = "none";
+				oCanvas.height = iHeight;
+				// oCanvas.style.display = "none";
 				// oCanvas.style.width = iWidth;
 				// oCanvas.style.height = iHeight;
 
 				oImg = renderer.domElement;
-
 				if ( oImg.style.backgroundColor ) {
 
 					oAscii.rows[ 0 ].cells[ 0 ].style.backgroundColor = oImg.style.backgroundColor;
@@ -92,7 +91,6 @@
 			const strFont = 'courier new, monospace';
 			const oCanvasImg = renderer.domElement;
 			const oCanvas = document.createElement( 'canvas' );
-
 			if ( ! oCanvas.getContext ) {
 
 				return;
@@ -100,7 +98,6 @@
 			}
 
 			const oCtx = oCanvas.getContext( '2d' );
-
 			if ( ! oCtx.getImageData ) {
 
 				return;
@@ -108,13 +105,16 @@
 			}
 
 			let aCharList = bColor ? aDefaultColorCharList : aDefaultCharList;
-			if ( charSet ) aCharList = charSet; // Setup dom
+			if ( charSet ) aCharList = charSet;
+
+			// Setup dom
 
 			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' ) {
 
 				switch ( iScale ) {
@@ -122,16 +122,13 @@
 					case 1:
 						fLetterSpacing = - 1;
 						break;
-
 					case 2:
 					case 3:
 						fLetterSpacing = - 2.1;
 						break;
-
 					case 4:
 						fLetterSpacing = - 3.1;
 						break;
-
 					case 5:
 						fLetterSpacing = - 4.15;
 						break;
@@ -147,15 +144,12 @@
 					case 1:
 						fLetterSpacing = 0;
 						break;
-
 					case 2:
 						fLetterSpacing = - 1;
 						break;
-
 					case 3:
 						fLetterSpacing = - 1.04;
 						break;
-
 					case 4:
 					case 5:
 						fLetterSpacing = - 2.1;
@@ -173,7 +167,6 @@
 					case 2:
 						fLetterSpacing = 0;
 						break;
-
 					case 3:
 					case 4:
 					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 ) {
 
 				oCtx.clearRect( 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 ) {
 
@@ -205,7 +203,8 @@
 						const iAlpha = oImgData[ iOffset + 3 ];
 						let iCharIdx;
 						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 ) {
 
@@ -216,19 +215,18 @@
 						}
 
 						iCharIdx = Math.floor( ( 1 - fBrightness ) * ( aCharList.length - 1 ) );
-
 						if ( bInvert ) {
 
 							iCharIdx = aCharList.length - iCharIdx - 1;
 
-						} // good for debugging
+						}
+
+						// good for debugging
 						//fBrightness = Math.floor(fBrightness * 10);
 						//strThisChar = fBrightness;
 
-
 						let strThisChar = aCharList[ iCharIdx ];
 						if ( strThisChar === undefined || strThisChar == ' ' ) strThisChar = '&nbsp;';
-
 						if ( bColor ) {
 
 							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;
 
 			}

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

@@ -64,21 +64,26 @@
 			const defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
 			const defaultColor = new THREE.Color().fromArray( parameters.defaultColor !== undefined ? parameters.defaultColor : [ 0, 0, 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
 			// save at the outline material creation and release
 			// if it's unused removeThresholdCount frames
 			// unless keepAlive is true.
-
 			const cache = {};
-			const removeThresholdCount = 60; // outlineMaterial.uuid -> object.material or
+			const removeThresholdCount = 60;
+
+			// outlineMaterial.uuid -> object.material or
 			// outlineMaterial.uuid -> object.material[ n ]
 			// save before render and release after render.
+			const originalMaterials = {};
 
-			const originalMaterials = {}; // object.uuid -> originalOnBeforeRender
+			// object.uuid -> originalOnBeforeRender
 			// save before render and release after render.
+			const originalOnBeforeRenders = {};
 
-			const originalOnBeforeRenders = {}; //this.cache = cache;  // for debug
+			//this.cache = cache;  // for debug
 
 			const uniformsOutline = {
 				outlineThickness: {
@@ -91,12 +96,15 @@
 					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' );
 			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() {
 
 				return new THREE.ShaderMaterial( {
@@ -112,7 +120,6 @@
 			function getOutlineMaterialFromCache( originalMaterial ) {
 
 				let data = cache[ originalMaterial.uuid ];
-
 				if ( data === undefined ) {
 
 					data = {
@@ -143,7 +150,6 @@
 
 				const geometry = object.geometry;
 				let hasNormals = false;
-
 				if ( object.geometry !== undefined ) {
 
 					if ( geometry.isBufferGeometry ) {
@@ -165,7 +171,6 @@
 			function setOutlineMaterial( object ) {
 
 				if ( isCompatible( object ) === false ) return;
-
 				if ( Array.isArray( object.material ) ) {
 
 					for ( let i = 0, il = object.material.length; i < il; i ++ ) {
@@ -188,7 +193,6 @@
 			function restoreOriginalMaterial( object ) {
 
 				if ( isCompatible( object ) === false ) return;
-
 				if ( Array.isArray( object.material ) ) {
 
 					for ( let i = 0, il = object.material.length; i < il; i ++ ) {
@@ -209,8 +213,9 @@
 
 			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;
 				updateUniforms( material, originalMaterial );
 
@@ -220,7 +225,6 @@
 
 				const outlineParameters = originalMaterial.userData.outlineParameters;
 				material.uniforms.outlineAlpha.value = originalMaterial.opacity;
-
 				if ( outlineParameters !== undefined ) {
 
 					if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
@@ -247,7 +251,6 @@
 				material.toneMapped = originalMaterial.toneMapped;
 				material.premultipliedAlpha = originalMaterial.premultipliedAlpha;
 				material.displacementMap = originalMaterial.displacementMap;
-
 				if ( outlineParameters !== undefined ) {
 
 					if ( originalMaterial.visible === false ) {
@@ -271,7 +274,6 @@
 				}
 
 				if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
-
 				if ( originalMaterial.clippingPlanes ) {
 
 					material.clipping = true;
@@ -287,36 +289,32 @@
 
 			function cleanupCache() {
 
-				let keys; // clear originialMaterials
+				let keys;
 
+				// clear originialMaterials
 				keys = Object.keys( originalMaterials );
-
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 					originalMaterials[ keys[ i ] ] = undefined;
 
-				} // clear originalOnBeforeRenders
-
+				}
 
+				// clear originalOnBeforeRenders
 				keys = Object.keys( originalOnBeforeRenders );
-
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 					originalOnBeforeRenders[ keys[ i ] ] = undefined;
 
-				} // remove unused outlineMaterial from cache
-
+				}
 
+				// remove unused outlineMaterial from cache
 				keys = Object.keys( cache );
-
 				for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 					const key = keys[ i ];
-
 					if ( cache[ key ].used === false ) {
 
 						cache[ key ].count ++;
-
 						if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) {
 
 							delete cache[ key ];
@@ -371,6 +369,7 @@
 				renderer.shadowMap.enabled = currentShadowMapEnabled;
 
 			};
+
 			/*
      * See #9918
      *
@@ -385,12 +384,9 @@
      *
      * }
      */
-
-
 			this.autoClear = renderer.autoClear;
 			this.domElement = renderer.domElement;
 			this.shadowMap = renderer.shadowMap;
-
 			this.clear = function ( color, depth, stencil ) {
 
 				renderer.clear( color, depth, stencil );

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

@@ -5,21 +5,15 @@
 		constructor( renderer ) {
 
 			const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-
 			const _scene = new THREE.Scene();
-
 			const _stereo = new THREE.StereoCamera();
-
 			const _params = {
 				minFilter: THREE.LinearFilter,
 				magFilter: THREE.NearestFilter,
 				format: THREE.RGBAFormat
 			};
-
 			const _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
-
 			const _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
-
 			const _material = new THREE.ShaderMaterial( {
 				uniforms: {
 					'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' ),
 				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 );
-
 			_scene.add( mesh );
-
 			this.setSize = function ( width, height ) {
 
 				renderer.setSize( width, height );
 				const pixelRatio = renderer.getPixelRatio();
-
 				_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
-
 				_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
 
 			};
@@ -52,9 +41,7 @@
 
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
 				_stereo.update( camera );
-
 				renderer.setRenderTarget( _renderTargetL );
 				renderer.clear();
 				renderer.render( scene, _stereo.cameraL );

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

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

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

@@ -5,10 +5,8 @@
 		constructor( renderer ) {
 
 			const _stereo = new THREE.StereoCamera();
-
 			_stereo.aspect = 0.5;
 			const size = new THREE.Vector2();
-
 			this.setEyeSeparation = function ( eyeSep ) {
 
 				_stereo.eyeSep = eyeSep;
@@ -25,9 +23,7 @@
 
 				if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
 				if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
-
 				_stereo.update( camera );
-
 				renderer.getSize( size );
 				if ( renderer.autoClear ) renderer.clear();
 				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
  */
-
 	class RoomEnvironment extends THREE.Scene {
 
 		constructor() {
@@ -51,40 +50,45 @@
 			box6.position.set( - 2.193, - 0.369, - 5.547 );
 			box6.rotation.set( 0, 0.516, 0 );
 			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 ) );
 			light1.position.set( - 16.116, 14.37, 8.208 );
 			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 ) );
 			light2.position.set( - 16.109, 18.021, - 8.207 );
 			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 ) );
 			light3.position.set( 14.904, 12.198, - 1.832 );
 			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 ) );
 			light4.position.set( - 0.462, 8.89, 14.520 );
 			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 ) );
 			light5.position.set( 3.235, 11.486, - 12.541 );
 			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 ) );
 			light6.position.set( 0.0, 20.0, 0.0 );
 			light6.scale.set( 1.0, 0.1, 1.0 );
 			this.add( light6 );
 
 		}
-
 		dispose() {
 
 			const resources = new Set();
@@ -98,7 +102,6 @@
 				}
 
 			} );
-
 			for ( const resource of resources ) {
 
 				resource.dispose();
@@ -108,7 +111,6 @@
 		}
 
 	}
-
 	function createAreaLightMaterial( intensity ) {
 
 		const material = new THREE.MeshBasicMaterial();

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

@@ -24,7 +24,6 @@
 				unitName: null,
 				unitMeter: null
 			}, options );
-
 			if ( options.upAxis.match( /^[XYZ]_UP$/ ) === null ) {
 
 				console.error( 'ColladaExporter: Invalid upAxis: valid values are X_UP, Y_UP or Z_UP.' );
@@ -53,23 +52,20 @@
 			}
 
 			const version = options.version;
-
 			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.` );
 				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 ) {
 
 				const IS_END_TAG = /^<\//;
 				const IS_SELF_CLOSING = /(\?>$)|(\/>$)/;
 				const HAS_TEXT = /<[^>]+>[^<]*<\/[^<]+>/;
-
 				const pad = ( ch, num ) => num > 0 ? ch + pad( ch, num - 1 ) : '';
-
 				let tagnum = 0;
 				return urdf.match( /(<[^>]+>[^<]+<\/[^<]+>)|(<[^>]+>)/g ).map( tag => {
 
@@ -80,7 +76,6 @@
 					}
 
 					const res = `${pad( '  ', tagnum )}${tag}`;
-
 					if ( ! HAS_TEXT.test( tag ) && ! IS_SELF_CLOSING.test( tag ) && ! IS_END_TAG.test( tag ) ) {
 
 						tagnum ++;
@@ -91,14 +86,13 @@
 
 				} ).join( '\n' );
 
-			} // Convert an image into a png format for saving
-
+			}
 
+			// Convert an image into a png format for saving
 			function base64ToBuffer( str ) {
 
 				const b = atob( str );
 				const buf = new Uint8Array( b.length );
-
 				for ( let i = 0, l = buf.length; i < l; i ++ ) {
 
 					buf[ i ] = b.charCodeAt( i );
@@ -110,25 +104,25 @@
 			}
 
 			let canvas, ctx;
-
 			function imageToData( image, ext ) {
 
 				canvas = canvas || document.createElement( 'canvas' );
 				ctx = ctx || canvas.getContext( '2d' );
 				canvas.width = image.width;
 				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 );
 
-			} // 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 tempColor = new THREE.Color();
-
 			function attrBufferToArray( attr, isColor = false ) {
 
 				if ( isColor ) {
@@ -136,7 +130,6 @@
 					// convert the colors to srgb before export
 					// colors are always written as floats
 					const arr = new Float32Array( attr.count * 3 );
-
 					for ( let i = 0, l = attr.count; i < l; i ++ ) {
 
 						tempColor.fromBufferAttribute( attr, i ).convertLinearToSRGB();
@@ -153,7 +146,6 @@
 					// use the typed array constructor to save on memory
 					const arr = new attr.array.constructor( attr.count * attr.itemSize );
 					const size = attr.itemSize;
-
 					for ( let i = 0, l = attr.count; i < l; i ++ ) {
 
 						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 ) {
 
 				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 ) {
 
 				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>';
 				return res;
 
-			} // Returns the string for a node's transform information
-
+			}
 
+			// Returns the string for a node's transform information
 			let transMat;
-
 			function getTransform( o ) {
 
 				// ensure the object's matrix is up to date
@@ -204,14 +195,13 @@
 				transMat.transpose();
 				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 ) {
 
 				let info = geometryInfo.get( bufferGeometry );
-
 				if ( ! info ) {
 
 					const meshid = `Mesh${libraryGeometries.length + 1}`;
@@ -222,46 +212,48 @@
 						materialIndex: 0
 					} ];
 					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 vertName = `${meshid}-vertices`;
 					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
 					// models with attributes that share an offset.
 					// MeshLab Bug#424: https://sourceforge.net/p/meshlab/bugs/424/
-					// serialize normals
 
+					// serialize normals
 					let triangleInputs = `<input semantic="VERTEX" source="#${vertName}" offset="0" />`;
-
 					if ( 'normal' in bufferGeometry.attributes ) {
 
 						const normName = `${meshid}-normal`;
 						gnode += getAttribute( bufferGeometry.attributes.normal, normName, [ 'X', 'Y', 'Z' ], 'float' );
 						triangleInputs += `<input semantic="NORMAL" source="#${normName}" offset="0" />`;
 
-					} // serialize uvs
-
+					}
 
+					// serialize uvs
 					if ( 'uv' in bufferGeometry.attributes ) {
 
 						const uvName = `${meshid}-texcoord`;
 						gnode += getAttribute( bufferGeometry.attributes.uv, uvName, [ 'S', 'T' ], 'float' );
 						triangleInputs += `<input semantic="TEXCOORD" source="#${uvName}" offset="0" set="0" />`;
 
-					} // serialize lightmap uvs
-
+					}
 
+					// serialize lightmap uvs
 					if ( 'uv2' in bufferGeometry.attributes ) {
 
 						const uvName = `${meshid}-texcoord2`;
 						gnode += getAttribute( bufferGeometry.attributes.uv2, uvName, [ 'S', 'T' ], 'float' );
 						triangleInputs += `<input semantic="TEXCOORD" source="#${uvName}" offset="0" set="1" />`;
 
-					} // serialize colors
-
+					}
 
+					// serialize colors
 					if ( 'color' in bufferGeometry.attributes ) {
 
 						// colors are always written as floats
@@ -272,7 +264,6 @@
 					}
 
 					let indexArray = null;
-
 					if ( bufferGeometry.index ) {
 
 						indexArray = attrBufferToArray( bufferGeometry.index );
@@ -280,7 +271,6 @@
 					} else {
 
 						indexArray = new Array( indexCount );
-
 						for ( let i = 0, l = indexArray.length; i < l; i ++ ) indexArray[ i ] = i;
 
 					}
@@ -309,21 +299,19 @@
 
 				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 ) {
 
 				let texid = imageMap.get( tex );
-
 				if ( texid == null ) {
 
 					texid = `image-${libraryImages.length + 1}`;
 					const ext = 'png';
 					const name = tex.name || texid;
 					let imageNode = `<image id="${texid}" name="${name}">`;
-
 					if ( version === '1.5.0' ) {
 
 						imageNode += `<init_from><ref>${options.textureDirectory}${name}.${ext}</ref></init_from>`;
@@ -350,19 +338,17 @@
 
 				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 ) {
 
 				let matid = materialMap.get( m );
-
 				if ( matid == null ) {
 
 					matid = `Mat${libraryEffects.length + 1}`;
 					let type = 'phong';
-
 					if ( m.isMeshLambertMaterial === true ) {
 
 						type = 'lambert';
@@ -370,7 +356,6 @@
 					} else if ( m.isMeshBasicMaterial === true ) {
 
 						type = 'constant';
-
 						if ( m.map !== null ) {
 
 							// The Collada spec does not support diffuse texture maps with the
@@ -389,16 +374,15 @@
 					const reflectivity = m.reflectivity || 0;
 					emissive.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
 					// channel to specify the transparency
-
 					let transparencyNode = '';
-
 					if ( m.transparent === true ) {
 
 						transparencyNode += '<transparent>' + ( m.map ? '<texture texture="diffuse-sampler"></texture>' : '<float>1</float>' ) + '</transparent>';
-
 						if ( m.opacity < 1 ) {
 
 							transparencyNode += `<transparency><float>${m.opacity}</float></transparency>`;
@@ -419,30 +403,30 @@
 
 				return matid;
 
-			} // Recursively process the object into a scene
-
+			}
 
+			// Recursively process the object into a scene
 			function processObject( o ) {
 
 				let node = `<node name="${o.name}">`;
 				node += getTransform( o );
-
 				if ( o.isMesh === true && o.geometry !== null ) {
 
 					// function returns the id associated with the mesh and a "BufferGeometry" version
 					// of the geometry in case it's not a geometry.
 					const geomInfo = processGeometry( o.geometry );
 					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 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
 					// the materials.
-
 					const mat = o.material || new THREE.MeshBasicMaterial();
 					const materials = Array.isArray( mat ) ? mat : [ mat ];
-
 					if ( geometry.groups.length > materials.length ) {
 
 						matidsArray = new Array( geometry.groups.length );
@@ -486,7 +470,6 @@
 				data: format( dae ),
 				textures
 			};
-
 			if ( typeof onDone === 'function' ) {
 
 				requestAnimationFrame( () => onDone( res ) );

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

@@ -15,6 +15,7 @@
  */
 
 	/* global DracoEncoderModule */
+
 	class DRACOExporter {
 
 		parse( object, options = {
@@ -38,7 +39,6 @@
 			const encoder = new dracoEncoder.Encoder();
 			let builder;
 			let dracoObject;
-
 			if ( object.isMesh === true ) {
 
 				builder = new dracoEncoder.MeshBuilder();
@@ -46,7 +46,6 @@
 				const vertices = geometry.getAttribute( 'position' );
 				builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
 				const faces = geometry.getIndex();
-
 				if ( faces !== null ) {
 
 					builder.AddFacesToMesh( dracoObject, faces.count / 3, faces.array );
@@ -54,7 +53,6 @@
 				} else {
 
 					const faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );
-
 					for ( let i = 0; i < faces.length; i ++ ) {
 
 						faces[ i ] = i;
@@ -68,7 +66,6 @@
 				if ( options.exportNormals === true ) {
 
 					const normals = geometry.getAttribute( 'normal' );
-
 					if ( normals !== undefined ) {
 
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );
@@ -80,7 +77,6 @@
 				if ( options.exportUvs === true ) {
 
 					const uvs = geometry.getAttribute( 'uv' );
-
 					if ( uvs !== undefined ) {
 
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array );
@@ -92,7 +88,6 @@
 				if ( options.exportColor === true ) {
 
 					const colors = geometry.getAttribute( 'color' );
-
 					if ( colors !== undefined ) {
 
 						builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );
@@ -107,11 +102,9 @@
 				dracoObject = new dracoEncoder.PointCloud();
 				const vertices = geometry.getAttribute( 'position' );
 				builder.AddFloatAttribute( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );
-
 				if ( options.exportColor === true ) {
 
 					const colors = geometry.getAttribute( 'color' );
-
 					if ( colors !== undefined ) {
 
 						builder.AddFloatAttribute( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );
@@ -124,23 +117,28 @@
 
 				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 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 ) {
 
 				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 ) {
 
 				for ( let i = 0; i < 5; i ++ ) {
@@ -156,7 +154,6 @@
 			}
 
 			let length;
-
 			if ( object.isMesh === true ) {
 
 				length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData );
@@ -168,16 +165,14 @@
 			}
 
 			dracoEncoder.destroy( dracoObject );
-
 			if ( length === 0 ) {
 
 				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 ) );
-
 			for ( let i = 0; i < length; i ++ ) {
 
 				outputData[ i ] = encodedData.GetValue( i );
@@ -191,14 +186,19 @@
 
 		}
 
-	} // Encoder methods
+	}
 
+	// Encoder methods
 
 	DRACOExporter.MESH_EDGEBREAKER_ENCODING = 1;
-	DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0; // Geometry type
+	DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0;
+
+	// Geometry type
 
 	DRACOExporter.POINT_CLOUD = 0;
-	DRACOExporter.TRIANGULAR_MESH = 1; // Attribute type
+	DRACOExporter.TRIANGULAR_MESH = 1;
+
+	// Attribute type
 
 	DRACOExporter.INVALID = - 1;
 	DRACOExporter.POSITION = 0;

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

@@ -10,7 +10,6 @@
 	const NO_COMPRESSION = 0;
 	const ZIPS_COMPRESSION = 2;
 	const ZIP_COMPRESSION = 3;
-
 	class EXRExporter {
 
 		parse( renderer, renderTarget, options ) {
@@ -25,7 +24,6 @@
 		}
 
 	}
-
 	function supported( renderer, renderTarget ) {
 
 		if ( ! renderer || ! renderer.isWebGLRenderer ) {
@@ -97,7 +95,6 @@
 	function getPixelData( renderer, rtt, info ) {
 
 		let dataBuffer;
-
 		if ( info.type === THREE.FloatType ) {
 
 			dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels );
@@ -131,7 +128,6 @@
 			setValue = info.dataType == 1 ? setFloat16 : setFloat32,
 			outBuffer = new Uint8Array( info.width * info.height * info.numOutputChannels * info.dataSize ),
 			dv = new DataView( outBuffer.buffer );
-
 		for ( let y = 0; y < h; ++ y ) {
 
 			for ( let x = 0; x < w; ++ x ) {
@@ -170,13 +166,11 @@
 				totalSize: 0
 			},
 			size = info.width * info.numOutputChannels * info.blockLines * info.dataSize;
-
 		switch ( info.compression ) {
 
 			case 0:
 				compress = compressNONE;
 				break;
-
 			case 2:
 			case 3:
 				compress = compressZIP;
@@ -218,11 +212,11 @@
 		//
 		// Reorder the pixel data.
 		//
+
 		let t1 = 0,
 			t2 = Math.floor( ( data.length + 1 ) / 2 ),
 			s = 0;
 		const stop = data.length - 1;
-
 		while ( true ) {
 
 			if ( s > stop ) break;
@@ -230,13 +224,13 @@
 			if ( s > stop ) break;
 			tmpBuffer[ t2 ++ ] = data[ s ++ ];
 
-		} //
+		}
+
+		//
 		// Predictor.
 		//
 
-
 		let p = tmpBuffer[ 0 ];
-
 		for ( let t = 1; t < tmpBuffer.length; t ++ ) {
 
 			const d = tmpBuffer[ t ] - p + ( 128 + 256 );
@@ -264,8 +258,8 @@
 		};
 		const dv = new DataView( outBuffer.buffer );
 		setUint32( dv, 20000630, offset ); // magic
-
 		setUint32( dv, 2, offset ); // mask
+
 		// = HEADER =
 
 		setString( dv, 'compression', offset );
@@ -326,12 +320,14 @@
 		offset.value += 4;
 		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 ) {
 
 			setUint64( dv, sum, offset );
@@ -352,7 +348,6 @@
 			outBuffer = new Uint8Array( HeaderSize + TableSize + chunks.totalSize + info.numBlocks * 8 ),
 			dv = new DataView( outBuffer.buffer );
 		fillHeader( outBuffer, chunks, info );
-
 		for ( let i = 0; i < chunks.data.length; ++ i ) {
 
 			const data = chunks.data[ i ].dataChunk;
@@ -375,13 +370,16 @@
 		dec.b = b;
 		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.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.a = a;
-	// }
 
+	// }
 
 	function setUint8( dv, value, offset ) {
 
@@ -421,7 +419,6 @@
 	function setString( dv, string, offset ) {
 
 		const tmp = textEncoder.encode( string + '\0' );
-
 		for ( let i = 0; i < tmp.length; ++ i ) {
 
 			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;
 				let a = num.toString();
-
 				if ( a.indexOf( '.' ) === - 1 ) {
 
 					a += '.';
@@ -60,7 +59,6 @@
 			function toStringsFromArray( array ) {
 
 				const a = [];
-
 				for ( let i = 0, il = array.length; i < il; i ++ ) {
 
 					a.push( toStringsFromNumber( array[ i ] ) );
@@ -84,16 +82,15 @@
 			array.push( ( skin.name !== '' ? skin.name.replace( /\s/g, '_' ) : 'skin' ) + '.osm;' );
 			array.push( bones.length + ';' );
 			array.push( '' );
-
 			for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
 				const bone = bones[ i ];
 				const bone2 = bones2[ i ];
+
 				/*
        * use the bone matrix saved before solving IK.
        * see CCDIKSolver for the detail.
        */
-
 				if ( useOriginalBones === true && bone.userData.ik !== undefined && bone.userData.ik.originalMatrix !== undefined ) {
 
 					matrix.fromArray( bone.userData.ik.originalMatrix );
@@ -107,8 +104,9 @@
 				position.setFromMatrixPosition( matrix );
 				quaternion.setFromRotationMatrix( matrix );
 				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 ];
 				qArray[ 0 ] = - qArray[ 0 ];
 				qArray[ 1 ] = - qArray[ 1 ];
@@ -126,21 +124,18 @@
 
 		}
 
-	} // Unicode to Shift_JIS table
-
+	}
 
+	// Unicode to Shift_JIS table
 	let u2sTable;
-
 	function unicodeToShiftjis( str ) {
 
 		if ( u2sTable === undefined ) {
 
 			const encoder = new MMDParser.CharsetEncoder(); // eslint-disable-line no-undef
-
 			const table = encoder.s2uTable;
 			u2sTable = {};
 			const keys = Object.keys( table );
-
 			for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
 				let key = keys[ i ];
@@ -153,12 +148,10 @@
 		}
 
 		const array = [];
-
 		for ( let i = 0, il = str.length; i < il; i ++ ) {
 
 			const code = str.charCodeAt( i );
 			const value = u2sTable[ code ];
-
 			if ( value === undefined ) {
 
 				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 uv = new THREE.Vector2();
 			const face = [];
-
 			function parseMesh( mesh ) {
 
 				let nbVertex = 0;
 				let nbNormals = 0;
 				let nbVertexUvs = 0;
 				const geometry = mesh.geometry;
-				const normalMatrixWorld = new THREE.Matrix3(); // shortcuts
+				const normalMatrixWorld = new THREE.Matrix3();
 
+				// shortcuts
 				const vertices = geometry.getAttribute( 'position' );
 				const normals = geometry.getAttribute( 'normal' );
 				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 ) {
 
 					output += 'usemtl ' + mesh.material.name + '\n';
 
-				} // vertices
+				}
 
+				// vertices
 
 				if ( vertices !== undefined ) {
 
 					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';
 
 					}
 
-				} // uvs
+				}
 
+				// uvs
 
 				if ( uvs !== undefined ) {
 
 					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';
 
 					}
 
-				} // normals
+				}
 
+				// normals
 
 				if ( normals !== undefined ) {
 
 					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
 					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';
 
 					}
 
-				} // faces
+				}
 
+				// faces
 
 				if ( indices !== null ) {
 
@@ -90,9 +100,9 @@
 							const j = indices.getX( i + m ) + 1;
 							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';
 
 					}
@@ -106,16 +116,16 @@
 							const j = i + m + 1;
 							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';
 
 					}
 
-				} // update index
-
+				}
 
+				// update index
 				indexVertex += nbVertex;
 				indexVertexUvs += nbVertexUvs;
 				indexNormals += nbNormals;
@@ -126,20 +136,23 @@
 
 				let nbVertex = 0;
 				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';
-
 				if ( vertices !== undefined ) {
 
 					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';
 
 					}
@@ -149,7 +162,6 @@
 				if ( type === 'Line' ) {
 
 					output += 'l ';
-
 					for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
 
 						output += indexVertex + j + ' ';
@@ -168,9 +180,9 @@
 
 					}
 
-				} // update index
-
+				}
 
+				// update index
 				indexVertex += nbVertex;
 
 			}
@@ -182,7 +194,6 @@
 				const vertices = geometry.getAttribute( 'position' );
 				const colors = geometry.getAttribute( 'color' );
 				output += 'o ' + points.name + '\n';
-
 				if ( vertices !== undefined ) {
 
 					for ( let i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) {
@@ -190,7 +201,6 @@
 						vertex.fromBufferAttribute( vertices, i );
 						vertex.applyMatrix4( points.matrixWorld );
 						output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z;
-
 						if ( colors !== undefined ) {
 
 							color.fromBufferAttribute( colors, i ).convertLinearToSRGB();
@@ -203,7 +213,6 @@
 					}
 
 					output += 'p ';
-
 					for ( let j = 1, l = vertices.count; j <= l; j ++ ) {
 
 						output += indexVertex + j + ' ';
@@ -212,9 +221,9 @@
 
 					output += '\n';
 
-				} // update index
-
+				}
 
+				// update index
 				indexVertex += nbVertex;
 
 			}

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

@@ -26,7 +26,6 @@
 
 						const mesh = child;
 						const geometry = mesh.geometry;
-
 						if ( geometry.hasAttribute( 'position' ) === true ) {
 
 							cb( mesh, geometry );
@@ -37,9 +36,9 @@
 
 				} );
 
-			} // Default options
-
+			}
 
+			// Default options
 			const defaultOptions = {
 				binary: false,
 				excludeAttributes: [],
@@ -51,9 +50,10 @@
 			let includeIndices = true;
 			let includeNormals = 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 faceCount = 0;
 			object.traverse( function ( child ) {
@@ -67,7 +67,6 @@
 					const uvs = geometry.getAttribute( 'uv' );
 					const colors = geometry.getAttribute( 'color' );
 					const indices = geometry.getIndex();
-
 					if ( vertices === undefined ) {
 
 						return;
@@ -96,7 +95,6 @@
 			includeNormals = includeNormals && excludeAttributes.indexOf( 'normal' ) === - 1;
 			includeColors = includeColors && excludeAttributes.indexOf( 'color' ) === - 1;
 			includeUVs = includeUVs && excludeAttributes.indexOf( 'uv' ) === - 1;
-
 			if ( includeIndices && faceCount !== Math.floor( faceCount ) ) {
 
 				// point cloud meshes will not have an index array and may not have a
@@ -108,9 +106,9 @@
 			}
 
 			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';
-
 			if ( includeNormals === true ) {
 
 				// 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 normalMatrixWorld = new THREE.Matrix3();
 			let result = null;
-
 			if ( options.binary === true ) {
 
 				// 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 color channels with 1 byte
 				// 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
-
 				const faceListLength = includeIndices ? faceCount * ( indexByteCount * 3 + 1 ) : 0;
 				const output = new DataView( new ArrayBuffer( headerBin.length + vertexListLength + faceListLength ) );
 				new Uint8Array( output.buffer ).set( headerBin, 0 );
@@ -170,19 +170,20 @@
 					const colors = geometry.getAttribute( 'color' );
 					const indices = geometry.getIndex();
 					normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
-
 					for ( let i = 0, l = vertices.count; i < l; i ++ ) {
 
 						vertex.fromBufferAttribute( vertices, i );
-						vertex.applyMatrix4( mesh.matrixWorld ); // Position information
+						vertex.applyMatrix4( mesh.matrixWorld );
 
+						// Position information
 						output.setFloat32( vOffset, vertex.x, options.littleEndian );
 						vOffset += 4;
 						output.setFloat32( vOffset, vertex.y, options.littleEndian );
 						vOffset += 4;
 						output.setFloat32( vOffset, vertex.z, options.littleEndian );
-						vOffset += 4; // Normal information
+						vOffset += 4;
 
+						// Normal information
 						if ( includeNormals === true ) {
 
 							if ( normals != null ) {
@@ -207,9 +208,9 @@
 
 							}
 
-						} // UV information
-
+						}
 
+						// UV information
 						if ( includeUVs === true ) {
 
 							if ( uvs != null ) {
@@ -228,9 +229,9 @@
 
 							}
 
-						} // THREE.Color information
-
+						}
 
+						// THREE.Color information
 						if ( includeColors === true ) {
 
 							if ( colors != null ) {
@@ -261,6 +262,7 @@
 					if ( includeIndices === true ) {
 
 						// Create the face list
+
 						if ( indices !== null ) {
 
 							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;
 
 				} );
@@ -316,15 +318,18 @@
 					const uvs = geometry.getAttribute( 'uv' );
 					const colors = geometry.getAttribute( 'color' );
 					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 ++ ) {
 
 						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 ( normals != null ) {
@@ -339,9 +344,9 @@
 
 							}
 
-						} // UV information
-
+						}
 
+						// UV information
 						if ( includeUVs === true ) {
 
 							if ( uvs != null ) {
@@ -354,9 +359,9 @@
 
 							}
 
-						} // THREE.Color information
-
+						}
 
+						// THREE.Color information
 						if ( includeColors === true ) {
 
 							if ( colors != null ) {
@@ -374,9 +379,9 @@
 
 						vertexList += line + '\n';
 
-					} // Create the face list
-
+					}
 
+					// Create the face list
 					if ( includeIndices === true ) {
 
 						if ( indices !== null ) {

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

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

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

@@ -5,8 +5,9 @@
 		async parse( scene ) {
 
 			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;
 			let output = buildHeader();
 			const materials = {};
@@ -17,11 +18,9 @@
 
 					const geometry = object.geometry;
 					const material = object.material;
-
 					if ( material.isMeshStandardMaterial ) {
 
 						const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usd';
-
 						if ( ! ( geometryFileName in files ) ) {
 
 							const meshObject = buildMeshObject( geometry );
@@ -49,7 +48,6 @@
 			output += buildMaterials( materials, textures );
 			files[ modelFileName ] = fflate.strToU8( output );
 			output = null;
-
 			for ( const id in textures ) {
 
 				const texture = textures[ id ];
@@ -59,19 +57,18 @@
 				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() );
 
-			} // 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;
-
 			for ( const filename in files ) {
 
 				const file = files[ filename ];
 				const headerSize = 34 + filename.length;
 				offset += headerSize;
 				const offsetMod64 = offset & 63;
-
 				if ( offsetMod64 !== 4 ) {
 
 					const padLength = 64 - offsetMod64;
@@ -95,7 +92,6 @@
 		}
 
 	}
-
 	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 ) {
@@ -106,7 +102,6 @@
 			canvas.height = image.height * Math.min( 1, scale );
 			const context = canvas.getContext( '2d' );
 			context.drawImage( image, 0, 0, canvas.width, canvas.height );
-
 			if ( color !== undefined ) {
 
 				const hex = parseInt( color, 16 );
@@ -115,7 +110,6 @@
 				const b = ( hex & 255 ) / 255;
 				const imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
 				const data = imagedata.data;
-
 				for ( let i = 0; i < data.length; i += 4 ) {
 
 					data[ i + 0 ] = data[ i + 0 ] * r;
@@ -132,11 +126,11 @@
 
 		}
 
-	} //
+	}
 
+	//
 
 	const PRECISION = 7;
-
 	function buildHeader() {
 
 		return `#usda 1.0
@@ -158,14 +152,14 @@
 		output += dataToInsert;
 		return fflate.strToU8( output );
 
-	} // Xform
+	}
 
+	// Xform
 
 	function buildXform( object, geometry, material ) {
 
 		const name = 'Object_' + object.id;
 		const transform = buildMatrix( object.matrixWorld );
-
 		if ( object.matrixWorld.determinant() < 0 ) {
 
 			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 ]})`;
 
-	} // Mesh
+	}
 
+	// Mesh
 
 	function buildMeshObject( geometry ) {
 
@@ -246,7 +241,6 @@ def "Geometry"
 
 		const index = geometry.index;
 		const array = [];
-
 		if ( index !== null ) {
 
 			for ( let i = 0; i < index.count; i ++ ) {
@@ -258,7 +252,6 @@ def "Geometry"
 		} else {
 
 			const length = geometry.attributes.position.count;
-
 			for ( let i = 0; i < length; i ++ ) {
 
 				array.push( i );
@@ -281,7 +274,6 @@ def "Geometry"
 		}
 
 		const array = [];
-
 		for ( let i = 0; i < attribute.count; i ++ ) {
 
 			const x = attribute.getX( i );
@@ -305,7 +297,6 @@ def "Geometry"
 		}
 
 		const array = [];
-
 		for ( let i = 0; i < attribute.count; i ++ ) {
 
 			const x = attribute.getX( i );
@@ -316,13 +307,13 @@ def "Geometry"
 
 		return array.join( ', ' );
 
-	} // Materials
+	}
 
+	// Materials
 
 	function buildMaterials( materials, textures ) {
 
 		const array = [];
-
 		for ( const uuid in materials ) {
 
 			const material = materials[ uuid ];
@@ -342,10 +333,10 @@ ${array.join( '' )}
 	function buildMaterial( material, textures ) {
 
 		// https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
+
 		const pad = '            ';
 		const inputs = [];
 		const samplers = [];
-
 		function buildTexture( texture, mapType, color ) {
 
 			const id = texture.id + ( color ? '_' + color.getHexString() : '' );
@@ -390,7 +381,6 @@ ${array.join( '' )}
 		if ( material.map !== null ) {
 
 			inputs.push( `${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:rgb>` );
-
 			if ( material.transparent ) {
 
 				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 y = - heightHalf;
 			let z = - depthHalf;
-
 			for ( let i = 0; i <= widthSegments; i ++ ) {
 
 				vertices.push( x, - heightHalf, - depthHalf, x, heightHalf, - depthHalf );

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

@@ -4,25 +4,29 @@
 
 		constructor( points = [] ) {
 
-			super(); // buffers
+			super();
+
+			// buffers
 
 			const vertices = [];
 			const normals = [];
-
 			if ( THREE.ConvexHull === undefined ) {
 
 				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 ++ ) {
 
 				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 {
 
@@ -33,8 +37,9 @@
 
 				} while ( edge !== face.edge );
 
-			} // build geometry
+			}
 
+			// build geometry
 
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 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 ) {
 
-			super(); // buffers
+			super();
+
+			// buffers
 
 			const vertices = [];
 			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();
 			projectorMatrix.makeRotationFromEuler( orientation );
 			projectorMatrix.setPosition( position );
 			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( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
 			this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
-
 			function generate() {
 
 				let decalVertices = [];
 				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 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
 				//
 				// this data structure will be later used to perform the clipping
@@ -55,8 +68,8 @@
 				if ( geometry.index !== null ) {
 
 					// indexed THREE.BufferGeometry
-					const index = geometry.index;
 
+					const index = geometry.index;
 					for ( let i = 0; i < index.count; i ++ ) {
 
 						vertex.fromBufferAttribute( positionAttribute, index.getX( i ) );
@@ -68,6 +81,7 @@
 				} else {
 
 					// non-indexed THREE.BufferGeometry
+
 					for ( let i = 0; i < positionAttribute.count; 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( 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 ) ); // 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 ++ ) {
 
-					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 );
 					normals.push( decalVertex.normal.x, decalVertex.normal.y, decalVertex.normal.z );
@@ -104,6 +127,7 @@
 			function pushDecalVertex( decalVertices, vertex, normal ) {
 
 				// transform the vertex to world space, then to projector space
+
 				vertex.applyMatrix4( mesh.matrixWorld );
 				vertex.applyMatrix4( projectorMatrixInverse );
 				normal.transformDirection( mesh.matrixWorld );
@@ -114,7 +138,9 @@
 			function clipGeometry( inVertices, plane ) {
 
 				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
 
 				for ( let i = 0; i < inVertices.length; i += 3 ) {
@@ -129,16 +155,18 @@
 					const d3 = inVertices[ i + 2 ].position.dot( plane ) - s;
 					const v1Out = d1 > 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 ) {
 
 						case 0:
 						{
 
 							// the entire face lies inside of the plane, no clipping needed
+
 							outVertices.push( inVertices[ i ] );
 							outVertices.push( inVertices[ i + 1 ] );
 							outVertices.push( inVertices[ i + 2 ] );
@@ -150,6 +178,7 @@
 						{
 
 							// one vertex lies outside of the plane, perform clipping
+
 							if ( v1Out ) {
 
 								nV1 = inVertices[ i + 1 ];
@@ -198,6 +227,7 @@
 						{
 
 							// two vertices lies outside of the plane, perform clipping
+
 							if ( ! v1Out ) {
 
 								nV1 = inVertices[ i ].clone();
@@ -239,6 +269,7 @@
 						{
 
 							// the entire face lies outside of the plane, so let's discard the corresponding vertices
+
 							break;
 
 						}
@@ -256,7 +287,9 @@
 				const d0 = v0.position.dot( p ) - s;
 				const d1 = v1.position.dot( p ) - s;
 				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 );
 
 				return v;
@@ -265,8 +298,9 @@
 
 		}
 
-	} // helper
+	}
 
+	// helper
 
 	class DecalVertex {
 
@@ -276,7 +310,6 @@
 			this.normal = normal;
 
 		}
-
 		clone() {
 
 			return new this.constructor( this.position.clone(), this.normal.clone() );

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

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

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

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

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

@@ -4,7 +4,6 @@
  * Parametric Surfaces Geometry
  * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html
  */
-
 	class ParametricGeometry extends THREE.BufferGeometry {
 
 		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,
 				slices: slices,
 				stacks: stacks
-			}; // buffers
+			};
+
+			// buffers
 
 			const indices = [];
 			const vertices = [];
@@ -26,20 +27,25 @@
 			const p0 = new THREE.Vector3(),
 				p1 = 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 ++ ) {
 
 				const v = i / stacks;
-
 				for ( let j = 0; j <= slices; j ++ ) {
 
-					const u = j / slices; // vertex
+					const u = j / slices;
+
+					// vertex
 
 					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
 
 					if ( u - EPS >= 0 ) {
@@ -64,18 +70,22 @@
 						func( u, v + EPS, p1 );
 						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();
-					normals.push( normal.x, normal.y, normal.z ); // uv
+					normals.push( normal.x, normal.y, normal.z );
+
+					// uv
 
 					uvs.push( u, v );
 
 				}
 
-			} // generate indices
+			}
 
+			// generate indices
 
 			for ( let i = 0; i < stacks; i ++ ) {
 
@@ -84,15 +94,18 @@
 					const a = i * sliceCount + j;
 					const b = i * 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( b, c, d );
 
 				}
 
-			} // build geometry
+			}
 
+			// build geometry
 
 			this.setIndex( indices );
 			this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );

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

@@ -1,25 +1,24 @@
 ( function () {
 
 	const _tempNormal = new THREE.Vector3();
-
 	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 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[ 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;
-
 		if ( Math.sign( _tempNormal[ uvAxis ] ) === 1 ) {
 
 			return arcAngleRatio * arcUvRatio;
@@ -39,17 +38,21 @@
 		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
-			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 );
-			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;
 			const geometry2 = this.toNonIndexed();
 			this.index = null;
 			this.attributes.position = geometry2.attributes.position;
 			this.attributes.normal = geometry2.attributes.normal;
-			this.attributes.uv = geometry2.attributes.uv; //
+			this.attributes.uv = geometry2.attributes.uv;
+
+			//
 
 			const position = new THREE.Vector3();
 			const normal = new THREE.Vector3();
@@ -60,7 +63,6 @@
 			const faceTris = positions.length / 6;
 			const faceDirVector = new THREE.Vector3();
 			const halfSegmentSize = 0.5 / segments;
-
 			for ( let i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
 
 				position.fromArray( positions, i );
@@ -76,51 +78,51 @@
 				normals[ i + 1 ] = normal.y;
 				normals[ i + 2 ] = normal.z;
 				const side = Math.floor( i / faceTris );
-
 				switch ( side ) {
 
 					case 0:
 						// right
+
 						// generate UVs along Z then Y
 						faceDirVector.set( 1, 0, 0 );
 						uvs[ j + 0 ] = getUv( faceDirVector, normal, 'z', 'y', radius, depth );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
 						break;
-
 					case 1:
 						// left
+
 						// generate UVs along Z then Y
 						faceDirVector.set( - 1, 0, 0 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'y', radius, depth );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
 						break;
-
 					case 2:
 						// top
+
 						// generate UVs along X then Z
 						faceDirVector.set( 0, 1, 0 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
 						uvs[ j + 1 ] = getUv( faceDirVector, normal, 'z', 'x', radius, depth );
 						break;
-
 					case 3:
 						// bottom
+
 						// generate UVs along X then Z
 						faceDirVector.set( 0, - 1, 0 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'x', radius, depth );
 						break;
-
 					case 4:
 						// front
+
 						// generate UVs along X then Y
 						faceDirVector.set( 0, 0, 1 );
 						uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'y', radius, width );
 						uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height );
 						break;
-
 					case 5:
 						// back
+
 						// generate UVs along X then Y
 						faceDirVector.set( 0, 0, - 1 );
 						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
  * }
  */
-
 	class TextGeometry extends THREE.ExtrudeGeometry {
 
 		constructor( text, parameters = {} ) {
 
 			const font = parameters.font;
-
 			if ( font === undefined ) {
 
 				super(); // generate default extrude geometry
 
 			} 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.bevelSize === undefined ) parameters.bevelSize = 8;

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

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

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

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

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

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

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

@@ -18,8 +18,9 @@
 			super( geometry, material );
 			this.light = light;
 			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 geometry2 = new THREE.BufferGeometry();
@@ -31,11 +32,9 @@
 			} ) ) );
 
 		}
-
 		updateMatrixWorld() {
 
 			this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 );
-
 			if ( this.color !== undefined ) {
 
 				this.material.color.set( this.color );
@@ -43,21 +42,21 @@
 
 			} 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 max = Math.max( c.r, c.g, c.b );
 				if ( max > 1 ) c.multiplyScalar( 1 / max );
 				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.children[ 0 ].matrixWorld.copy( this.matrixWorld );
 
 		}
-
 		dispose() {
 
 			this.geometry.dispose();

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

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

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

@@ -1,9 +1,7 @@
 ( function () {
 
 	const _v1 = new THREE.Vector3();
-
 	const _v2 = new THREE.Vector3();
-
 	class VertexTangentsHelper extends THREE.LineSegments {
 
 		constructor( object, size = 1, color = 0x00ffff ) {
@@ -18,32 +16,34 @@
 			} ) );
 			this.object = object;
 			this.size = size;
-			this.type = 'VertexTangentsHelper'; //
+			this.type = 'VertexTangentsHelper';
+
+			//
 
 			this.matrixAutoUpdate = false;
 			this.update();
 
 		}
-
 		update() {
 
 			this.object.updateMatrixWorld( true );
 			const matrixWorld = this.object.matrixWorld;
-			const position = this.geometry.attributes.position; //
+			const position = this.geometry.attributes.position;
+
+			//
 
 			const objGeometry = this.object.geometry;
 			const objPos = objGeometry.attributes.position;
 			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 ++ ) {
 
 				_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
-
 				_v2.fromBufferAttribute( objTan, j );
-
 				_v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( _v1 );
-
 				position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
 				idx = idx + 1;
 				position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
@@ -54,7 +54,6 @@
 			position.needsUpdate = true;
 
 		}
-
 		dispose() {
 
 			this.geometry.dispose();

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

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

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

@@ -12,7 +12,6 @@
 				transparent: true
 			} );
 			super( geometry, material );
-
 			function onEvent( event ) {
 
 				material.map.dispatchDOMEvent( event );
@@ -23,7 +22,6 @@
 			this.addEventListener( 'mousemove', onEvent );
 			this.addEventListener( 'mouseup', onEvent );
 			this.addEventListener( 'click', onEvent );
-
 			this.dispose = function () {
 
 				geometry.dispose();
@@ -40,7 +38,6 @@
 		}
 
 	}
-
 	class HTMLTexture extends THREE.CanvasTexture {
 
 		constructor( dom ) {
@@ -50,8 +47,9 @@
 			this.anisotropy = 16;
 			this.encoding = THREE.sRGBEncoding;
 			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( () => {
 
 				if ( ! this.scheduleUpdate ) {
@@ -72,7 +70,6 @@
 			this.observer = observer;
 
 		}
-
 		dispatchDOMEvent( event ) {
 
 			if ( event.data ) {
@@ -82,7 +79,6 @@
 			}
 
 		}
-
 		update() {
 
 			this.image = html2canvas( this.dom );
@@ -90,7 +86,6 @@
 			this.scheduleUpdate = null;
 
 		}
-
 		dispose() {
 
 			if ( this.observer ) {
@@ -104,21 +99,19 @@
 
 		}
 
-	} //
+	}
 
+	//
 
 	const canvases = new WeakMap();
-
 	function html2canvas( element ) {
 
 		const range = document.createRange();
 		const color = new THREE.Color();
-
 		function Clipper( context ) {
 
 			const clips = [];
 			let isClipping = false;
-
 			function doClip() {
 
 				if ( isClipping ) {
@@ -133,7 +126,6 @@
 					minY = - Infinity;
 				let maxX = Infinity,
 					maxY = Infinity;
-
 				for ( let i = 0; i < clips.length; i ++ ) {
 
 					const clip = clips[ i ];
@@ -207,7 +199,6 @@
 			const borderWidth = style[ which + 'Width' ];
 			const borderStyle = style[ which + 'Style' ];
 			const borderColor = style[ which + 'Color' ];
-
 			if ( borderWidth !== '0px' && borderStyle !== 'none' && borderColor !== 'transparent' && borderColor !== 'rgba(0, 0, 0, 0)' ) {
 
 				context.strokeStyle = borderColor;
@@ -227,10 +218,10 @@
 				y = 0,
 				width = 0,
 				height = 0;
-
 			if ( element.nodeType === Node.TEXT_NODE ) {
 
 				// text
+
 				range.selectNode( element );
 				const rect = range.getBoundingClientRect();
 				x = rect.left - offset.left - 0.5;
@@ -261,23 +252,24 @@
 				y = rect.top - offset.top - 0.5;
 				width = rect.width;
 				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 ) );
 				const backgroundColor = style.backgroundColor;
-
 				if ( backgroundColor !== 'transparent' && backgroundColor !== 'rgba(0, 0, 0, 0)' ) {
 
 					context.fillStyle = backgroundColor;
 					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' ];
 				let match = true;
 				let prevBorder = null;
-
 				for ( const border of borders ) {
 
 					if ( prevBorder !== null ) {
@@ -294,8 +286,8 @@
 				if ( match === true ) {
 
 					// 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)' ) {
 
 						context.strokeStyle = style.borderTopColor;
@@ -307,6 +299,7 @@
 				} else {
 
 					// Otherwise draw individual borders
+
 					drawBorder( style, 'borderTop', x, y, width, 0 );
 					drawBorder( style, 'borderLeft', x, y, 0, height );
 					drawBorder( style, 'borderBottom', x, y + height, width, 0 );
@@ -321,7 +314,6 @@
 					color.set( accentColor );
 					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';
-
 					if ( element.type === 'radio' ) {
 
 						buildRectPath( x, y, width, height, height );
@@ -330,7 +322,6 @@
 						context.lineWidth = 1;
 						context.fill();
 						context.stroke();
-
 						if ( element.checked ) {
 
 							buildRectPath( x + 2, y + 2, width - 4, height - 4, height );
@@ -352,7 +343,6 @@
 						context.lineWidth = 1;
 						context.stroke();
 						context.fill();
-
 						if ( element.checked ) {
 
 							const currentTextAlign = context.textAlign;
@@ -405,13 +395,13 @@
 				}
 
 			}
+
 			/*
     // debug
     context.strokeStyle = '#' + Math.random().toString( 16 ).slice( - 3 );
     context.strokeRect( x - 0.5, y - 0.5, width + 1, height + 1 );
     */
 
-
 			const isClipping = style.overflow === 'auto' || style.overflow === 'hidden';
 			if ( isClipping ) clipper.add( {
 				x: x,
@@ -419,7 +409,6 @@
 				width: width,
 				height: height
 			} );
-
 			for ( let i = 0; i < element.childNodes.length; i ++ ) {
 
 				drawElement( element.childNodes[ i ], style );
@@ -432,7 +421,6 @@
 
 		const offset = element.getBoundingClientRect();
 		let canvas = canvases.get( element );
-
 		if ( canvas === undefined ) {
 
 			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;
 
@@ -464,17 +455,14 @@
 		const rect = element.getBoundingClientRect();
 		x = x * rect.width + rect.left;
 		y = y * rect.height + rect.top;
-
 		function traverse( element ) {
 
 			if ( element.nodeType !== Node.TEXT_NODE && element.nodeType !== Node.COMMENT_NODE ) {
 
 				const rect = element.getBoundingClientRect();
-
 				if ( x > rect.left && x < rect.right && y > rect.top && y < rect.bottom ) {
 
 					element.dispatchEvent( new MouseEvent( event, mouseEventInit ) );
-
 					if ( element instanceof HTMLInputElement && element.type === 'range' && ( event === 'mousedown' || event === 'click' ) ) {
 
 						const [ min, max ] = [ 'min', 'max' ].map( property => parseFloat( element[ property ] ) );

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

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

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

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

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

@@ -12,14 +12,12 @@
 			this.pointTopLeft = new THREE.Vector2();
 			this.pointBottomRight = new THREE.Vector2();
 			this.isDown = false;
-
 			this.onPointerDown = function ( event ) {
 
 				this.isDown = true;
 				this.onSelectStart( event );
 
 			}.bind( this );
-
 			this.onPointerMove = function ( event ) {
 
 				if ( this.isDown ) {
@@ -29,20 +27,17 @@
 				}
 
 			}.bind( this );
-
 			this.onPointerUp = function () {
 
 				this.isDown = false;
 				this.onSelectOver();
 
 			}.bind( this );
-
 			this.renderer.domElement.addEventListener( 'pointerdown', this.onPointerDown );
 			this.renderer.domElement.addEventListener( 'pointermove', this.onPointerMove );
 			this.renderer.domElement.addEventListener( 'pointerup', this.onPointerUp );
 
 		}
-
 		dispose() {
 
 			this.renderer.domElement.removeEventListener( 'pointerdown', this.onPointerDown );
@@ -50,7 +45,6 @@
 			this.renderer.domElement.removeEventListener( 'pointerup', this.onPointerUp );
 
 		}
-
 		onSelectStart( event ) {
 
 			this.element.style.display = 'none';
@@ -63,7 +57,6 @@
 			this.startPoint.y = event.clientY;
 
 		}
-
 		onSelectMove( event ) {
 
 			this.element.style.display = 'block';
@@ -77,7 +70,6 @@
 			this.element.style.height = this.pointBottomRight.y - this.pointTopLeft.y + 'px';
 
 		}
-
 		onSelectOver() {
 
 			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 sh = new THREE.SphericalHarmonics3();
 			const shCoefficients = sh.coefficients;
-
 			for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
 
 				const image = cubeTexture.image[ faceIndex ];
@@ -28,56 +27,57 @@
 				const imageWidth = imageData.width; // assumed to be square
 
 				const pixelSize = 2 / imageWidth;
-
 				for ( let i = 0, il = data.length; i < il; i += 4 ) {
 
 					// RGBA assumed
+
 					// 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 col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize;
 					const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize;
-
 					switch ( faceIndex ) {
 
 						case 0:
 							coord.set( - 1, row, - col );
 							break;
-
 						case 1:
 							coord.set( 1, row, col );
 							break;
-
 						case 2:
 							coord.set( - col, 1, - row );
 							break;
-
 						case 3:
 							coord.set( - col, - 1, row );
 							break;
-
 						case 4:
 							coord.set( - col, row, 1 );
 							break;
-
 						case 5:
 							coord.set( col, row, - 1 );
 							break;
 
-					} // weight assigned to this pixel
+					}
 
+					// weight assigned to this pixel
 
 					const lengthSq = coord.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 ++ ) {
 
 						shCoefficients[ j ].x += shBasis[ j ] * color.r * weight;
@@ -88,11 +88,10 @@
 
 				}
 
-			} // normalize
-
+			}
 
+			// normalize
 			const norm = 4 * Math.PI / totalWeight;
-
 			for ( let j = 0; j < 9; j ++ ) {
 
 				shCoefficients[ j ].x *= norm;
@@ -104,7 +103,6 @@
 			return new THREE.LightProbe( sh );
 
 		}
-
 		static fromCubeRenderTarget( renderer, cubeRenderTarget ) {
 
 			// 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 sh = new THREE.SphericalHarmonics3();
 			const shCoefficients = sh.coefficients;
-
 			for ( let faceIndex = 0; faceIndex < 6; faceIndex ++ ) {
 
 				const imageWidth = cubeRenderTarget.width; // assumed to be square
-
 				const data = new Uint8Array( imageWidth * imageWidth * 4 );
 				renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex );
 				const pixelSize = 2 / imageWidth;
-
 				for ( let i = 0, il = data.length; i < il; i += 4 ) {
 
 					// RGBA assumed
+
 					// 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 col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize;
 					const row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize;
-
 					switch ( faceIndex ) {
 
 						case 0:
 							coord.set( 1, row, - col );
 							break;
-
 						case 1:
 							coord.set( - 1, row, col );
 							break;
-
 						case 2:
 							coord.set( col, 1, - row );
 							break;
-
 						case 3:
 							coord.set( col, - 1, row );
 							break;
-
 						case 4:
 							coord.set( col, row, 1 );
 							break;
-
 						case 5:
 							coord.set( - col, row, - 1 );
 							break;
 
-					} // weight assigned to this pixel
+					}
 
+					// weight assigned to this pixel
 
 					const lengthSq = coord.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 ++ ) {
 
 						shCoefficients[ j ].x += shBasis[ j ] * color.r * weight;
@@ -183,11 +180,10 @@
 
 				}
 
-			} // normalize
-
+			}
 
+			// normalize
 			const norm = 4 * Math.PI / totalWeight;
-
 			for ( let j = 0; j < 9; j ++ ) {
 
 				shCoefficients[ j ].x *= norm;
@@ -201,7 +197,6 @@
 		}
 
 	}
-
 	function convertColorToLinear( color, encoding ) {
 
 		switch ( encoding ) {
@@ -209,10 +204,8 @@
 			case THREE.sRGBEncoding:
 				color.convertSRGBToLinear();
 				break;
-
 			case THREE.LinearEncoding:
 				break;
-
 			default:
 				console.warn( 'WARNING: LightProbeGenerator convertColorToLinear() encountered an unsupported encoding.' );
 				break;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2 - 0
examples/js/lights/RectAreaLightUniformsLib.js


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

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

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

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

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

@@ -1,49 +1,32 @@
 ( function () {
 
 	const _start = new THREE.Vector3();
-
 	const _end = new THREE.Vector3();
-
 	const _start4 = new THREE.Vector4();
-
 	const _end4 = new THREE.Vector4();
-
 	const _ssOrigin = new THREE.Vector4();
-
 	const _ssOrigin3 = new THREE.Vector3();
-
 	const _mvMatrix = new THREE.Matrix4();
-
 	const _line = new THREE.Line3();
-
 	const _closestPoint = new THREE.Vector3();
-
 	const _box = new THREE.Box3();
-
 	const _sphere = new THREE.Sphere();
-
 	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
-
-
 	function getWorldSpaceHalfWidth( camera, distance, resolution ) {
 
 		// 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
 		// width does not need to be halved.
 		_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
-
 		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
-
 		_clipToWorldVector.x = _lineWidth / resolution.width;
 		_clipToWorldVector.y = _lineWidth / resolution.height;
-
 		_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
-
 		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
-
 		return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );
 
 	}
@@ -53,16 +36,11 @@
 		for ( let i = 0, l = _instanceStart.count; i < l; i ++ ) {
 
 			_line.start.fromBufferAttribute( _instanceStart, i );
-
 			_line.end.fromBufferAttribute( _instanceEnd, i );
-
 			const pointOnLine = new THREE.Vector3();
 			const point = new THREE.Vector3();
-
 			_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
-
 			const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;
-
 			if ( isInside ) {
 
 				intersects.push( {
@@ -91,119 +69,98 @@
 		const geometry = lineSegments.geometry;
 		const instanceStart = geometry.attributes.instanceStart;
 		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
 		// sitting at the camera origin which will cause "w" to be 0 when
 		// 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.applyMatrix4( camera.matrixWorldInverse );
-
 		_ssOrigin.applyMatrix4( projectionMatrix );
+		_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
 
-		_ssOrigin.multiplyScalar( 1 / _ssOrigin.w ); // screen space
-
-
+		// screen space
 		_ssOrigin.x *= resolution.x / 2;
 		_ssOrigin.y *= resolution.y / 2;
 		_ssOrigin.z = 0;
-
 		_ssOrigin3.copy( _ssOrigin );
-
 		_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
-
 		for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
 
 			_start4.fromBufferAttribute( instanceStart, i );
-
 			_end4.fromBufferAttribute( instanceEnd, i );
-
 			_start4.w = 1;
-			_end4.w = 1; // camera space
+			_end4.w = 1;
 
+			// camera space
 			_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;
-
 			if ( isBehindCameraNear ) {
 
 				continue;
 
-			} // trim the segment if it extends behind camera near
-
+			}
 
+			// trim the segment if it extends behind camera near
 			if ( _start4.z > near ) {
 
 				const deltaDist = _start4.z - _end4.z;
 				const t = ( _start4.z - near ) / deltaDist;
-
 				_start4.lerp( _end4, t );
 
 			} else if ( _end4.z > near ) {
 
 				const deltaDist = _end4.z - _start4.z;
 				const t = ( _end4.z - near ) / deltaDist;
-
 				_end4.lerp( _start4, t );
 
-			} // clip space
-
+			}
 
+			// clip space
 			_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 );
+			_end4.multiplyScalar( 1 / _end4.w );
 
-			_end4.multiplyScalar( 1 / _end4.w ); // screen space
-
-
+			// screen space
 			_start4.x *= resolution.x / 2;
 			_start4.y *= resolution.y / 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.z = 0;
-
 			_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 );
+			_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 isInClipSpace = zPos >= - 1 && zPos <= 1;
-
 			const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;
-
 			if ( isInClipSpace && isInside ) {
 
 				_line.start.fromBufferAttribute( instanceStart, i );
-
 				_line.end.fromBufferAttribute( instanceEnd, i );
-
 				_line.start.applyMatrix4( matrixWorld );
-
 				_line.end.applyMatrix4( matrixWorld );
-
 				const pointOnLine = new THREE.Vector3();
 				const point = new THREE.Vector3();
-
 				_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
-
 				intersects.push( {
 					point: point,
 					pointOnLine: pointOnLine,
@@ -231,8 +188,9 @@
 			this.isLineSegments2 = true;
 			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() {
 
@@ -240,13 +198,10 @@
 			const instanceStart = geometry.attributes.instanceStart;
 			const instanceEnd = geometry.attributes.instanceEnd;
 			const lineDistances = new Float32Array( 2 * instanceStart.count );
-
 			for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 
 				_start.fromBufferAttribute( instanceStart, i );
-
 				_end.fromBufferAttribute( instanceEnd, i );
-
 				lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
 				lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 
@@ -255,18 +210,15 @@
 			const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
 			geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
-
 			geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
 			return this;
 
 		}
-
 		raycast( raycaster, intersects ) {
 
 			const worldUnits = this.material.worldUnits;
 			const camera = raycaster.camera;
-
 			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.' );
@@ -280,19 +232,19 @@
 			const material = this.material;
 			_lineWidth = material.linewidth + threshold;
 			_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 ) {
 
 				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;
-
 			if ( worldUnits ) {
 
 				sphereMargin = _lineWidth * 0.5;
@@ -305,25 +257,23 @@
 			}
 
 			_sphere.radius += sphereMargin;
-
 			if ( _ray.intersectsSphere( _sphere ) === false ) {
 
 				return;
 
-			} // check if we intersect the box bounds
-
+			}
 
+			// check if we intersect the box bounds
 			if ( geometry.boundingBox === null ) {
 
 				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;
-
 			if ( worldUnits ) {
 
 				boxMargin = _lineWidth * 0.5;
@@ -336,7 +286,6 @@
 			}
 
 			_box.expandByScalar( boxMargin );
-
 			if ( _ray.intersectsBox( _box ) === false ) {
 
 				return;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 81 - 141
examples/js/loaders/ColladaLoader.js


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

@@ -7,7 +7,6 @@
 			super( manager );
 
 		}
-
 		parse( buffer, loadMipmaps ) {
 
 			const dds = {
@@ -16,19 +15,25 @@
 				height: 0,
 				format: null,
 				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
+
 			// All values and structures referenced from:
 			// 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_WIDTH = 0x4;
 			// const DDSD_PITCH = 0x8;
 			// 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 DDSCAPS_COMPLEX = 0x8;
 			// const DDSCAPS_MIPMAP = 0x400000;
 			// const DDSCAPS_TEXTURE = 0x1000;
@@ -39,7 +44,9 @@
 			const DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
 			const DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
 			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_ALPHA = 0x2;
 			// const DDPF_FOURCC = 0x4;
@@ -66,7 +73,6 @@
 				const byteArray = new Uint8Array( dataLength );
 				let dst = 0;
 				let src = 0;
-
 				for ( let y = 0; y < height; y ++ ) {
 
 					for ( let x = 0; x < width; x ++ ) {
@@ -81,13 +87,10 @@
 						src ++;
 						byteArray[ dst ] = r;
 						dst ++; //r
-
 						byteArray[ dst ] = g;
 						dst ++; //g
-
 						byteArray[ dst ] = b;
 						dst ++; //b
-
 						byteArray[ dst ] = a;
 						dst ++; //a
 
@@ -104,6 +107,7 @@
 			const FOURCC_DXT5 = fourCCToInt32( 'DXT5' );
 			const FOURCC_ETC1 = fourCCToInt32( 'ETC1' );
 			const headerLengthInt = 31; // The header length in 32 bit ints
+
 			// Offsets into the header array
 
 			const off_magic = 0;
@@ -111,21 +115,24 @@
 			const off_flags = 2;
 			const off_height = 3;
 			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_RGBBitCount = 22;
 			const off_RBitMask = 23;
 			const off_GBitMask = 24;
 			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;
+
 			// Parse header
 
 			const header = new Int32Array( buffer, 0, headerLengthInt );
-
 			if ( header[ off_magic ] !== DDS_MAGIC ) {
 
 				console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' );
@@ -136,29 +143,24 @@
 			let blockBytes;
 			const fourCC = header[ off_pfFourCC ];
 			let isRGBAUncompressed = false;
-
 			switch ( fourCC ) {
 
 				case FOURCC_DXT1:
 					blockBytes = 8;
 					dds.format = THREE.RGB_S3TC_DXT1_Format;
 					break;
-
 				case FOURCC_DXT3:
 					blockBytes = 16;
 					dds.format = THREE.RGBA_S3TC_DXT3_Format;
 					break;
-
 				case FOURCC_DXT5:
 					blockBytes = 16;
 					dds.format = THREE.RGBA_S3TC_DXT5_Format;
 					break;
-
 				case FOURCC_ETC1:
 					blockBytes = 8;
 					dds.format = THREE.RGB_ETC1_Format;
 					break;
-
 				default:
 					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;
-
 			if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
 
 				dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
@@ -185,7 +186,6 @@
 
 			const caps2 = header[ off_caps2 ];
 			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 ) ) ) {
 
 				console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
@@ -195,19 +195,18 @@
 
 			dds.width = header[ off_width ];
 			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 ++ ) {
 
 				let width = dds.width;
 				let height = dds.height;
-
 				for ( let i = 0; i < dds.mipmapCount; i ++ ) {
 
 					let byteArray, dataLength;
-
 					if ( isRGBAUncompressed ) {
 
 						byteArray = loadARGBMip( buffer, dataOffset, width, height );

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

@@ -1,7 +1,6 @@
 ( function () {
 
 	const _taskCache = new WeakMap();
-
 	class DRACOLoader extends THREE.Loader {
 
 		constructor( manager ) {
@@ -29,28 +28,24 @@
 			};
 
 		}
-
 		setDecoderPath( path ) {
 
 			this.decoderPath = path;
 			return this;
 
 		}
-
 		setDecoderConfig( config ) {
 
 			this.decoderConfig = config;
 			return this;
 
 		}
-
 		setWorkerLimit( workerLimit ) {
 
 			this.workerLimit = workerLimit;
 			return this;
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const loader = new THREE.FileLoader( this.manager );
@@ -65,7 +60,6 @@
 			}, onProgress, onError );
 
 		}
-
 		decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) {
 
 			const taskConfig = {
@@ -76,16 +70,15 @@
 			return this.decodeGeometry( buffer, taskConfig ).then( callback );
 
 		}
-
 		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 ) ) {
 
 				const cachedTask = _taskCache.get( buffer );
-
 				if ( cachedTask.key === taskKey ) {
 
 					return cachedTask.promise;
@@ -100,14 +93,16 @@
 
 				}
 
-			} //
+			}
 
+			//
 
 			let worker;
 			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 => {
 
 				worker = _worker;
@@ -122,37 +117,39 @@
 						id: taskID,
 						taskConfig,
 						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( () => {
 
 				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, {
 				key: taskKey,
 				promise: geometryPending
 			} );
-
 			return geometryPending;
 
 		}
-
 		_createGeometry( geometryData ) {
 
 			const geometry = new THREE.BufferGeometry();
-
 			if ( geometryData.index ) {
 
 				geometry.setIndex( new THREE.BufferAttribute( geometryData.index.array, 1 ) );
@@ -172,7 +169,6 @@
 			return geometry;
 
 		}
-
 		_loadLibrary( url, responseType ) {
 
 			const loader = new THREE.FileLoader( this.manager );
@@ -186,21 +182,17 @@
 			} );
 
 		}
-
 		preload() {
 
 			this._initDecoder();
-
 			return this;
 
 		}
-
 		_initDecoder() {
 
 			if ( this.decoderPending ) return this.decoderPending;
 			const useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';
 			const librariesPending = [];
-
 			if ( useJS ) {
 
 				librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) );
@@ -215,7 +207,6 @@
 			this.decoderPending = Promise.all( librariesPending ).then( libraries => {
 
 				const jsContent = libraries[ 0 ];
-
 				if ( ! useJS ) {
 
 					this.decoderConfig.wasmBinary = libraries[ 1 ];
@@ -230,7 +221,6 @@
 			return this.decoderPending;
 
 		}
-
 		_getWorker( taskID, taskCost ) {
 
 			return this._initDecoder().then( () => {
@@ -245,23 +235,17 @@
 						type: 'init',
 						decoderConfig: this.decoderConfig
 					} );
-
 					worker.onmessage = function ( e ) {
 
 						const message = e.data;
-
 						switch ( message.type ) {
 
 							case 'decode':
 								worker._callbacks[ message.id ].resolve( message );
-
 								break;
-
 							case 'error':
 								worker._callbacks[ message.id ].reject( message );
-
 								break;
-
 							default:
 								console.error( 'THREE.DRACOLoader: Unexpected message, "' + message.type + '"' );
 
@@ -289,7 +273,6 @@
 			} );
 
 		}
-
 		_releaseTask( worker, taskID ) {
 
 			worker._taskLoad -= worker._taskCosts[ taskID ];
@@ -297,13 +280,11 @@
 			delete worker._taskCosts[ taskID ];
 
 		}
-
 		debug() {
 
 			console.log( 'Task load: ', this.workerPool.map( worker => worker._taskLoad ) );
 
 		}
-
 		dispose() {
 
 			for ( let i = 0; i < this.workerPool.length; ++ i ) {
@@ -318,25 +299,21 @@
 		}
 
 	}
-	/* WEB WORKER */
 
+	/* WEB WORKER */
 
 	function DRACOWorker() {
 
 		let decoderConfig;
 		let decoderPending;
-
 		onmessage = function ( e ) {
 
 			const message = e.data;
-
 			switch ( message.type ) {
 
 				case 'init':
 					decoderConfig = message.decoderConfig;
-					decoderPending = new Promise( function ( resolve
-						/*, reject*/
-					) {
+					decoderPending = new Promise( function ( resolve /*, reject*/ ) {
 
 						decoderConfig.onModuleLoaded = function ( draco ) {
 
@@ -350,8 +327,8 @@
 						DracoDecoderModule( decoderConfig ); // eslint-disable-line no-undef
 
 					} );
-					break;
 
+					break;
 				case 'decode':
 					const buffer = message.buffer;
 					const taskConfig = message.taskConfig;
@@ -361,7 +338,6 @@
 						const decoder = new draco.Decoder();
 						const decoderBuffer = new draco.DecoderBuffer();
 						decoderBuffer.Init( new Int8Array( buffer ), buffer.byteLength );
-
 						try {
 
 							const geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig );
@@ -403,7 +379,6 @@
 			let dracoGeometry;
 			let decodingStatus;
 			const geometryType = decoder.GetEncodedGeometryType( decoderBuffer );
-
 			if ( geometryType === draco.TRIANGULAR_MESH ) {
 
 				dracoGeometry = new draco.Mesh();
@@ -429,17 +404,19 @@
 			const geometry = {
 				index: null,
 				attributes: []
-			}; // Gather all vertex attributes.
+			};
 
+			// Gather all vertex attributes.
 			for ( const attributeName in attributeIDs ) {
 
 				const attributeType = self[ attributeTypes[ attributeName ] ];
 				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,
 				// 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.
-
 				if ( taskConfig.useUniqueIDs ) {
 
 					attributeID = attributeIDs[ attributeName ];
@@ -455,9 +432,9 @@
 
 				geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) );
 
-			} // Add index.
-
+			}
 
+			// Add index.
 			if ( geometryType === draco.TRIANGULAR_MESH ) {
 
 				geometry.index = decodeIndex( draco, decoder, dracoGeometry );
@@ -474,14 +451,10 @@
 			const numFaces = dracoGeometry.num_faces();
 			const numIndices = numFaces * 3;
 			const byteLength = numIndices * 4;
-
 			const ptr = draco._malloc( byteLength );
-
 			decoder.GetTrianglesUInt32Array( dracoGeometry, byteLength, ptr );
 			const index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice();
-
 			draco._free( ptr );
-
 			return {
 				array: index,
 				itemSize: 1
@@ -496,14 +469,10 @@
 			const numValues = numPoints * numComponents;
 			const byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
 			const dataType = getDracoDataType( draco, attributeType );
-
 			const ptr = draco._malloc( byteLength );
-
 			decoder.GetAttributeDataArrayForAllPoints( dracoGeometry, attribute, dataType, byteLength, ptr );
 			const array = new attributeType( draco.HEAPF32.buffer, ptr, numValues ).slice();
-
 			draco._free( ptr );
-
 			return {
 				name: attributeName,
 				array: array,
@@ -518,22 +487,16 @@
 
 				case Float32Array:
 					return draco.DT_FLOAT32;
-
 				case Int8Array:
 					return draco.DT_INT8;
-
 				case Int16Array:
 					return draco.DT_INT16;
-
 				case Int32Array:
 					return draco.DT_INT32;
-
 				case Uint8Array:
 					return draco.DT_UINT8;
-
 				case Uint16Array:
 					return draco.DT_UINT16;
-
 				case Uint32Array:
 					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 );
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const scope = this;
@@ -23,15 +22,15 @@
 			}, onProgress, onError );
 
 		}
-
 		parse( json ) {
 
 			return new Font( json );
 
 		}
 
-	} //
+	}
 
+	//
 
 	class Font {
 
@@ -42,12 +41,10 @@
 			this.data = data;
 
 		}
-
 		generateShapes( text, size = 100 ) {
 
 			const shapes = [];
 			const paths = createPaths( text, size, this.data );
-
 			for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
 
 				shapes.push( ...paths[ p ].toShapes() );
@@ -59,7 +56,6 @@
 		}
 
 	}
-
 	function createPaths( text, size, data ) {
 
 		const chars = Array.from( text );
@@ -68,11 +64,9 @@
 		const paths = [];
 		let offsetX = 0,
 			offsetY = 0;
-
 		for ( let i = 0; i < chars.length; i ++ ) {
 
 			const char = chars[ i ];
-
 			if ( char === '\n' ) {
 
 				offsetX = 0;
@@ -95,7 +89,6 @@
 	function createPath( char, scale, offsetX, offsetY, data ) {
 
 		const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
-
 		if ( ! glyph ) {
 
 			console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
@@ -105,42 +98,40 @@
 
 		const path = new THREE.ShapePath();
 		let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
-
 		if ( glyph.o ) {
 
 			const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
-
 			for ( let i = 0, l = outline.length; i < l; ) {
 
 				const action = outline[ i ++ ];
-
 				switch ( action ) {
 
 					case 'm':
 						// moveTo
+
 						x = outline[ i ++ ] * scale + offsetX;
 						y = outline[ i ++ ] * scale + offsetY;
 						path.moveTo( x, y );
 						break;
-
 					case 'l':
 						// lineTo
+
 						x = outline[ i ++ ] * scale + offsetX;
 						y = outline[ i ++ ] * scale + offsetY;
 						path.lineTo( x, y );
 						break;
-
 					case 'q':
 						// quadraticCurveTo
+
 						cpx = outline[ i ++ ] * scale + offsetX;
 						cpy = outline[ i ++ ] * scale + offsetY;
 						cpx1 = outline[ i ++ ] * scale + offsetX;
 						cpy1 = outline[ i ++ ] * scale + offsetY;
 						path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
 						break;
-
 					case 'b':
 						// bezierCurveTo
+
 						cpx = outline[ i ++ ] * scale + offsetX;
 						cpy = outline[ i ++ ] * scale + offsetY;
 						cpx1 = outline[ i ++ ] * scale + offsetX;

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

@@ -17,7 +17,6 @@
 			this.splitLayer = false;
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const scope = this;
@@ -50,7 +49,6 @@
 			}, onProgress, onError );
 
 		}
-
 		parse( data ) {
 
 			let state = {
@@ -72,7 +70,6 @@
 				color: 0x00FF00
 			} );
 			extrudingMaterial.name = 'extruded';
-
 			function newLayer( line ) {
 
 				currentLayer = {
@@ -82,9 +79,9 @@
 				};
 				layers.push( currentLayer );
 
-			} //Create lie segment between p1 and p2
-
+			}
 
+			//Create lie segment between p1 and p2
 			function addSegment( p1, p2 ) {
 
 				if ( currentLayer === undefined ) {
@@ -120,12 +117,12 @@
 			}
 
 			const lines = data.replace( /;.+/g, '' ).split( '\n' );
-
 			for ( let i = 0; i < lines.length; i ++ ) {
 
 				const tokens = lines[ i ].split( ' ' );
-				const cmd = tokens[ 0 ].toUpperCase(); //Argumments
+				const cmd = tokens[ 0 ].toUpperCase();
 
+				//Argumments
 				const args = {};
 				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' ) {
 
 					const line = {
@@ -148,12 +146,12 @@
 						z: args.z !== undefined ? absolute( state.z, args.z ) : state.z,
 						e: args.e !== undefined ? absolute( state.e, args.e ) : state.e,
 						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 ) {
 
 						state.extruding = delta( state.e, line.e ) > 0;
-
 						if ( currentLayer == undefined || line.z != currentLayer.z ) {
 
 							newLayer( line );
@@ -165,7 +163,9 @@
 					addSegment( 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' );
 				} else if ( cmd === 'G90' ) {
 
@@ -186,7 +186,9 @@
 					line.z = args.z !== undefined ? args.z : line.z;
 					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();
 			object.name = 'gcode';
-
 			if ( this.splitLayer ) {
 
 				for ( let i = 0; i < layers.length; i ++ ) {
@@ -218,13 +219,11 @@
 
 				const vertex = [],
 					pathVertex = [];
-
 				for ( let i = 0; i < layers.length; i ++ ) {
 
 					const layer = layers[ i ];
 					const layerVertex = layer.vertex;
 					const layerPathVertex = layer.pathVertex;
-
 					for ( let j = 0; j < layerVertex.length; 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;
 
 		}
-
 		load( urls, onLoad, onProgress, onError ) {
 
 			const texture = new THREE.CubeTexture();
 			texture.type = this.type;
-
 			switch ( texture.type ) {
 
 				case THREE.FloatType:
@@ -23,7 +21,6 @@
 					texture.magFilter = THREE.LinearFilter;
 					texture.generateMipmaps = false;
 					break;
-
 				case THREE.HalfFloatType:
 					texture.encoding = THREE.LinearEncoding;
 					texture.minFilter = THREE.LinearFilter;
@@ -35,7 +32,6 @@
 
 			const scope = this;
 			let loaded = 0;
-
 			function loadHDRData( i, onLoad, onProgress, onError ) {
 
 				new THREE.FileLoader( scope.manager ).setPath( scope.path ).setResponseType( 'arraybuffer' ).setWithCredentials( scope.withCredentials ).load( urls[ i ], function ( buffer ) {
@@ -43,7 +39,6 @@
 					loaded ++;
 					const texData = scope.hdrLoader.parse( buffer );
 					if ( ! texData ) return;
-
 					if ( texData.data !== undefined ) {
 
 						const dataTexture = new THREE.DataTexture( texData.data, texData.width, texData.height );
@@ -77,7 +72,6 @@
 			return texture;
 
 		}
-
 		setDataType( value ) {
 
 			this.type = value;

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

@@ -7,7 +7,6 @@
 			super( manager );
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const scope = this;
@@ -41,7 +40,6 @@
 			}, onProgress, onError );
 
 		}
-
 		parse( data ) {
 
 			function findFile( url ) {
@@ -62,7 +60,6 @@
 			manager.setURLModifier( function ( url ) {
 
 				const image = findFile( url );
-
 				if ( image ) {
 
 					console.log( 'Loading', url );
@@ -75,7 +72,9 @@
 
 				return url;
 
-			} ); //
+			} );
+
+			//
 
 			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 model = xml.querySelector( 'Placemark Model Link href' );
-
 				if ( model ) {
 
 					const loader = new THREE.ColladaLoader( manager );
@@ -95,11 +93,9 @@
 			} else {
 
 				console.warn( 'KMZLoader: Missing doc.kml file.' );
-
 				for ( const path in zip ) {
 
 					const extension = path.split( '.' ).pop().toLowerCase();
-
 					if ( extension === 'dae' ) {
 
 						const loader = new THREE.ColladaLoader( manager );

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

@@ -14,7 +14,6 @@
 			super( manager );
 
 		}
-
 		parse( buffer, loadMipmaps ) {
 
 			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)
 	// load types
-
 	const COMPRESSED_2D = 0; // uses a gl.compressedTexImage2D()
 	//const COMPRESSED_3D = 1; // uses a gl.compressedTexImage3D()
 	//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} 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'
 			// 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
-
 			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 ) {
 
 				console.error( 'texture missing KTX identifier' );
 				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 headerDataView = new DataView( this.arrayBuffer, 12, 13 * dataSize );
 			const endianness = headerDataView.getUint32( 0, true );
 			const littleEndian = endianness === 0x04030201;
 			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.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.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.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.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.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
-			// 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 ) {
 
 				console.warn( 'only compressed formats currently supported' );
@@ -125,27 +109,25 @@
 				console.warn( 'number of faces expected' + facesExpected + ', but found ' + this.numberOfFaces );
 				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;
 
 		}
-
 		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 width = this.pixelWidth;
 			let height = this.pixelHeight;
 			const mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1;
-
 			for ( let level = 0; level < mipmapCount; level ++ ) {
 
 				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
 
 				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 );
 
 		}
-
 		parse( str ) {
 
 			// remove empty lines and comment lints
 			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 gridStep = gridLines[ 1 ] - gridLines[ 0 ];
 			const size = gridLines.length;
-
 			for ( let i = 1, l = gridLines.length; i < l; i ++ ) {
 
 				if ( gridStep !== gridLines[ i ] - gridLines[ i - 1 ] ) {
@@ -57,7 +56,6 @@
 			const dataArray = new Array( size * size * size * 4 );
 			let index = 0;
 			let maxOutputValue = 0.0;
-
 			for ( let i = 1, l = lines.length; i < l; i ++ ) {
 
 				const line = lines[ i ].trim();
@@ -68,8 +66,9 @@
 				maxOutputValue = Math.max( maxOutputValue, r, g, b );
 				const bLayer = index % 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;
 				dataArray[ 4 * pixelIndex + 0 ] = r;
 				dataArray[ 4 * pixelIndex + 1 ] = g;
@@ -77,22 +76,19 @@
 				dataArray[ 4 * pixelIndex + 3 ] = 1.0;
 				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 maxBitValue = Math.pow( 2.0, bits );
-
 			for ( let i = 0, l = dataArray.length; i < l; i += 4 ) {
 
 				const r = dataArray[ i + 0 ];
 				const g = dataArray[ i + 1 ];
 				const b = dataArray[ i + 2 ];
 				dataArray[ i + 0 ] = 255 * r / maxBitValue; // r
-
 				dataArray[ i + 1 ] = 255 * g / maxBitValue; // g
-
 				dataArray[ i + 2 ] = 255 * b / maxBitValue; // b
 
 			}

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

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

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

@@ -12,9 +12,7 @@
  *  https://static.lightwave3d.com/sdk/2019/html/filefmts/lwo2.html
  *
  **/
-
 	let _lwoTree;
-
 	class LWOLoader extends THREE.Loader {
 
 		constructor( manager, parameters = {} ) {
@@ -23,12 +21,12 @@
 			this.resourcePath = parameters.resourcePath !== undefined ? parameters.resourcePath : '';
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			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 loader = new THREE.FileLoader( this.manager );
 			loader.setPath( scope.path );
@@ -36,6 +34,7 @@
 			loader.load( url, function ( buffer ) {
 
 				// console.time( 'Total parsing: ' );
+
 				try {
 
 					onLoad( scope.parse( buffer, path, modelName ) );
@@ -54,24 +53,27 @@
 
 					scope.manager.itemError( url );
 
-				} // console.timeEnd( 'Total parsing: ' );
+				}
+
+				// console.timeEnd( 'Total parsing: ' );
 
 			}, onProgress, onError );
 
 		}
-
 		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 );
 			return new LWOTreeParser( textureLoader ).parse( modelName );
 
 		}
 
-	} // Parse the lwoTree object
-
+	}
 
+	// Parse the lwoTree object
 	class LWOTreeParser {
 
 		constructor( textureLoader ) {
@@ -79,7 +81,6 @@
 			this.textureLoader = textureLoader;
 
 		}
-
 		parse( modelName ) {
 
 			this.materials = new MaterialParser( this.textureLoader ).parse();
@@ -91,16 +92,15 @@
 			};
 
 		}
-
 		parseLayers() {
 
 			// 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 geometryParser = new GeometryParser();
 			const scope = this;
-
 			_lwoTree.layers.forEach( function ( 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 );
 
 			} );
-
 			this.applyPivots( finalMeshes );
 			return finalMeshes;
 
 		}
-
 		parseMesh( geometry, layer ) {
 
 			let mesh;
@@ -125,9 +123,9 @@
 			mesh.userData.pivot = layer.pivot;
 			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 ) {
 
 			meshes.forEach( function ( mesh ) {
@@ -138,7 +136,6 @@
 					child.position.x += pivot[ 0 ];
 					child.position.y += pivot[ 1 ];
 					child.position.z += pivot[ 2 ];
-
 					if ( child.parent ) {
 
 						const parentPivot = child.parent.userData.pivot;
@@ -153,7 +150,6 @@
 			} );
 
 		}
-
 		getMaterials( namesArray, type ) {
 
 			const materials = [];
@@ -162,8 +158,9 @@
 
 				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' ) {
 
 				materials.forEach( function ( mat, i ) {
@@ -171,7 +168,6 @@
 					const spec = {
 						color: mat.color
 					};
-
 					if ( type === 'points' ) {
 
 						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 );
 			if ( filtered.length === 1 ) return filtered[ 0 ];
 			return materials;
 
 		}
-
 		getMaterialByName( name ) {
 
 			return this.materials.filter( function ( m ) {
@@ -203,13 +198,12 @@
 
 			} )[ 0 ];
 
-		} // If the material has an aoMap, duplicate UVs
-
+		}
 
+		// If the material has an aoMap, duplicate UVs
 		duplicateUVs( geometry, materials ) {
 
 			let duplicateUVs = false;
-
 			if ( ! Array.isArray( materials ) ) {
 
 				if ( materials.aoMap ) duplicateUVs = true;
@@ -230,7 +224,6 @@
 		}
 
 	}
-
 	class MaterialParser {
 
 		constructor( textureLoader ) {
@@ -238,12 +231,10 @@
 			this.textureLoader = textureLoader;
 
 		}
-
 		parse() {
 
 			const materials = [];
 			this.textures = {};
-
 			for ( const name in _lwoTree.materials ) {
 
 				if ( _lwoTree.format === 'LWO3' ) {
@@ -261,7 +252,6 @@
 			return materials;
 
 		}
-
 		parseMaterial( materialData, name, textures ) {
 
 			let params = {
@@ -282,10 +272,7 @@
 			return new materialType( params );
 
 		}
-
-		parseMaterialLwo2( materialData, name
-			/*, textures*/
-		) {
+		parseMaterialLwo2( materialData, name /*, textures*/ ) {
 
 			let params = {
 				name: name,
@@ -296,38 +283,33 @@
 			params = Object.assign( params, attributes );
 			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
 		// NB: this means that THREE.FrontSide and THREE.BackSide have been switched!
-
-
 		getSide( attributes ) {
 
 			if ( ! attributes.side ) return THREE.BackSide;
-
 			switch ( attributes.side ) {
 
 				case 0:
 				case 1:
 					return THREE.BackSide;
-
 				case 2:
 					return THREE.FrontSide;
-
 				case 3:
 					return THREE.DoubleSide;
 
 			}
 
 		}
-
 		getSmooth( attributes ) {
 
 			if ( ! attributes.smooth ) return true;
 			return ! attributes.smooth;
 
 		}
-
 		parseConnections( connections, nodes ) {
 
 			const materialConnections = {
@@ -361,7 +343,6 @@
 			return materialConnections;
 
 		}
-
 		getNodeByRefName( refName, nodes ) {
 
 			for ( const name in nodes ) {
@@ -371,11 +352,9 @@
 			}
 
 		}
-
 		parseTextureNodes( textureNodes ) {
 
 			const maps = {};
-
 			for ( const name in textureNodes ) {
 
 				const node = textureNodes[ name ];
@@ -384,70 +363,60 @@
 				const texture = this.loadTexture( path );
 				if ( node.widthWrappingMode !== undefined ) texture.wrapS = this.getWrappingType( node.widthWrappingMode );
 				if ( node.heightWrappingMode !== undefined ) texture.wrapT = this.getWrappingType( node.heightWrappingMode );
-
 				switch ( name ) {
 
 					case 'Color':
 						maps.map = texture;
 						break;
-
 					case 'Roughness':
 						maps.roughnessMap = texture;
 						maps.roughness = 1;
 						break;
-
 					case 'Specular':
 						maps.specularMap = texture;
 						maps.specular = 0xffffff;
 						break;
-
 					case 'Luminous':
 						maps.emissiveMap = texture;
 						maps.emissive = 0x808080;
 						break;
-
 					case 'Luminous THREE.Color':
 						maps.emissive = 0x808080;
 						break;
-
 					case 'Metallic':
 						maps.metalnessMap = texture;
 						maps.metalness = 1;
 						break;
-
 					case 'Transparency':
 					case 'Alpha':
 						maps.alphaMap = texture;
 						maps.transparent = true;
 						break;
-
 					case 'Normal':
 						maps.normalMap = texture;
 						if ( node.amplitude !== undefined ) maps.normalScale = new THREE.Vector2( node.amplitude, node.amplitude );
 						break;
-
 					case 'Bump':
 						maps.bumpMap = texture;
 						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;
 			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 ) {
 
 			for ( const name in attributes ) {
 
 				const attribute = attributes[ name ];
-
 				if ( attribute.maps ) {
 
 					const mapData = attribute.maps[ 0 ];
@@ -456,47 +425,38 @@
 					const texture = this.loadTexture( path );
 					if ( mapData.wrap !== undefined ) texture.wrapS = this.getWrappingType( mapData.wrap.w );
 					if ( mapData.wrap !== undefined ) texture.wrapT = this.getWrappingType( mapData.wrap.h );
-
 					switch ( name ) {
 
 						case 'Color':
 							maps.map = texture;
 							break;
-
 						case 'Diffuse':
 							maps.aoMap = texture;
 							break;
-
 						case 'Roughness':
 							maps.roughnessMap = texture;
 							maps.roughness = 1;
 							break;
-
 						case 'Specular':
 							maps.specularMap = texture;
 							maps.specular = 0xffffff;
 							break;
-
 						case 'Luminosity':
 							maps.emissiveMap = texture;
 							maps.emissive = 0x808080;
 							break;
-
 						case 'Metallic':
 							maps.metalnessMap = texture;
 							maps.metalness = 1;
 							break;
-
 						case 'Transparency':
 						case 'Alpha':
 							maps.alphaMap = texture;
 							maps.transparent = true;
 							break;
-
 						case 'Normal':
 							maps.normalMap = texture;
 							break;
-
 						case 'Bump':
 							maps.bumpMap = texture;
 							break;
@@ -508,17 +468,16 @@
 			}
 
 		}
-
 		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 ) {
 
 				params.color = new THREE.Color().fromArray( attributes.Color.value );
 
 			} else params.color = new THREE.Color();
-
 			if ( attributes.Transparency && attributes.Transparency.value !== 0 ) {
 
 				params.opacity = 1 - attributes.Transparency.value;
@@ -533,15 +492,11 @@
 			return params;
 
 		}
-
-		parsePhysicalAttributes( params, attributes
-			/*, maps*/
-		) {
+		parsePhysicalAttributes( params, attributes /*, maps*/ ) {
 
 			if ( attributes.Clearcoat && attributes.Clearcoat.value > 0 ) {
 
 				params.clearcoat = attributes.Clearcoat.value;
-
 				if ( attributes[ 'Clearcoat Gloss' ] ) {
 
 					params.clearcoatRoughness = 0.5 * ( 1 - attributes[ 'Clearcoat Gloss' ].value );
@@ -551,13 +506,11 @@
 			}
 
 		}
-
 		parseStandardAttributes( params, attributes, maps ) {
 
 			if ( attributes.Luminous ) {
 
 				params.emissiveIntensity = attributes.Luminous.value;
-
 				if ( attributes[ 'Luminous THREE.Color' ] && ! maps.emissive ) {
 
 					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;
 
 		}
-
 		parsePhongAttributes( params, attributes, maps ) {
 
 			if ( attributes[ 'Refraction Index' ] ) params.refractionRatio = 0.98 / attributes[ 'Refraction Index' ].value;
 			if ( attributes.Diffuse ) params.color.multiplyScalar( attributes.Diffuse.value );
-
 			if ( attributes.Reflection ) {
 
 				params.reflectivity = attributes.Reflection.value;
@@ -590,7 +541,6 @@
 			if ( attributes.Luminosity ) {
 
 				params.emissiveIntensity = attributes.Luminosity.value;
-
 				if ( ! maps.emissiveMap && ! maps.map ) {
 
 					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[ 'Color Highlight' ] ) {
@@ -621,17 +571,16 @@
 			if ( params.specular && attributes.Glossiness ) params.shininess = 7 + Math.pow( 2, attributes.Glossiness.value * 12 + 2 );
 
 		}
-
 		parseEnvMap( connections, maps, attributes ) {
 
 			if ( connections.envMap ) {
 
 				const envMap = this.loadTexture( connections.envMap );
-
 				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 ) {
 
 						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.
 
 				} else envMap.mapping = THREE.EquirectangularReflectionMapping;
-
 				maps.envMap = envMap;
 
 			}
 
-		} // get texture defined at top level by its index
-
+		}
 
+		// get texture defined at top level by its index
 		getTexturePathByIndex( index ) {
 
 			let fileName = '';
 			if ( ! _lwoTree.textures ) return fileName;
-
 			_lwoTree.textures.forEach( function ( texture ) {
 
 				if ( texture.index === index ) fileName = texture.fileName;
 
 			} );
-
 			return fileName;
 
 		}
-
 		loadTexture( path ) {
 
 			if ( ! path ) return null;
@@ -681,9 +626,9 @@
 			} );
 			return texture;
 
-		} // 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge
-
+		}
 
+		// 0 = Reset, 1 = Repeat, 2 = Mirror, 3 = Edge
 		getWrappingType( num ) {
 
 			switch ( num ) {
@@ -691,20 +636,16 @@
 				case 0:
 					console.warn( 'LWOLoader: "Reset" texture wrapping type is not supported in three.js' );
 					return THREE.ClampToEdgeWrapping;
-
 				case 1:
 					return THREE.RepeatWrapping;
-
 				case 2:
 					return THREE.MirroredRepeatWrapping;
-
 				case 3:
 					return THREE.ClampToEdgeWrapping;
 
 			}
 
 		}
-
 		getMaterialType( nodeData ) {
 
 			if ( nodeData.Clearcoat && nodeData.Clearcoat.value > 0 ) return THREE.MeshPhysicalMaterial;
@@ -714,7 +655,6 @@
 		}
 
 	}
-
 	class GeometryParser {
 
 		parse( geoData, layer ) {
@@ -726,17 +666,20 @@
 			this.parseGroups( geometry, geoData );
 			geometry.computeVertexNormals();
 			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.userData = userData;
 
 			return geometry;
 
-		} // split quads into tris
-
+		}
 
+		// split quads into tris
 		splitIndices( indices, polygonDimensions ) {
 
 			const remappedIndices = [];
@@ -768,9 +711,9 @@
 			} );
 			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 ) {
 
 			const tags = _lwoTree.tags;
@@ -780,24 +723,20 @@
 			if ( geoData.type === 'points' ) elemSize = 1;
 			const remappedIndices = this.splitMaterialIndices( geoData.polygonDimensions, geoData.materialIndices );
 			let indexNum = 0; // create new indices in numerical order
-
 			const indexPairs = {}; // original indices mapped to numerical indices
 
 			let prevMaterialIndex;
 			let materialIndex;
 			let prevStart = 0;
 			let currentCount = 0;
-
 			for ( let i = 0; i < remappedIndices.length; i += 2 ) {
 
 				materialIndex = remappedIndices[ i + 1 ];
 				if ( i === 0 ) matNames[ indexNum ] = tags[ materialIndex ];
 				if ( prevMaterialIndex === undefined ) prevMaterialIndex = materialIndex;
-
 				if ( materialIndex !== prevMaterialIndex ) {
 
 					let currentIndex;
-
 					if ( indexPairs[ tags[ prevMaterialIndex ] ] ) {
 
 						currentIndex = indexPairs[ tags[ prevMaterialIndex ] ];
@@ -820,13 +759,12 @@
 
 				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 ) {
 
 				let currentIndex;
-
 				if ( indexPairs[ tags[ materialIndex ] ] ) {
 
 					currentIndex = indexPairs[ tags[ materialIndex ] ];
@@ -841,13 +779,12 @@
 
 				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;
 
 		}
-
 		splitMaterialIndices( polygonDimensions, indices ) {
 
 			const remappedIndices = [];
@@ -875,7 +812,9 @@
 			} );
 			return remappedIndices;
 
-		} // UV maps:
+		}
+
+		// UV maps:
 		// 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
 		// 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
 		// UV maps are defined as partially VMAP and partially VMAD
 		// VMADs are currently not supported
-
-
 		parseUVs( geometry, layer ) {
 
 			// start by creating a UV map set to zero for the whole geometry
@@ -894,7 +831,6 @@
 				return 0;
 
 			} );
-
 			for ( const name in layer.uvs ) {
 
 				const uvs = layer.uvs[ name ].uvs;
@@ -911,11 +847,9 @@
 			geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( remappedUVs, 2 ) );
 
 		}
-
 		parseMorphTargets( geometry, layer ) {
 
 			let num = 0;
-
 			for ( const name in layer.morphTargets ) {
 
 				const remappedPoints = geometry.attributes.position.array.slice();
@@ -950,8 +884,9 @@
 
 		}
 
-	} // ************** UTILITY FUNCTIONS **************
+	}
 
+	// ************** UTILITY FUNCTIONS **************
 
 	function extractParentUrl( url, dir ) {
 

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

@@ -8,7 +8,6 @@
 			this.type = THREE.HalfFloatType;
 
 		}
-
 		parse( buffer ) {
 
 			const ifds = UTIF.decode( buffer );
@@ -24,7 +23,6 @@
 			};
 
 		}
-
 		setDataType( 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 = {};
-
 	UTIF.decode = function ( buff, prm ) {
 
 		if ( prm == null ) prm = {
 			parseMN: true,
 			debug: false
 		}; // read MakerNote, debug
-
 		var data = new Uint8Array( buff ),
 			offset = 0;
-
 		var id = UTIF._binBE.readASCII( data, offset, 2 );
-
 		offset += 2;
 		var bin = id == 'II' ? UTIF._binLE : UTIF._binBE;
 		bin.readUshort( data, offset );
 		offset += 2;
 		var ifdo = bin.readUint( data, offset );
 		var ifds = [];
-
 		while ( true ) {
 
 			var cnt = bin.readUshort( data, ifdo ),
@@ -68,7 +62,6 @@
 			}
 
 			UTIF._readIFD( bin, data, ifdo, ifds, 0, prm );
-
 			ifdo = bin.readUint( data, ifdo + 2 + cnt * 12 );
 			if ( ifdo == 0 ) break;
 
@@ -82,26 +75,19 @@
 
 		if ( img.data ) return;
 		var data = new Uint8Array( buff );
-
 		var id = UTIF._binBE.readASCII( data, 0, 2 );
-
 		if ( img[ 't256' ] == null ) return; // No width => probably not an image
-
 		img.isLE = id == 'II';
 		img.width = img[ 't256' ][ 0 ]; //delete img["t256"];
-
 		img.height = img[ 't257' ][ 0 ]; //delete img["t257"];
 
 		var cmpr = img[ 't259' ] ? img[ 't259' ][ 0 ] : 1; //delete img["t259"];
-
 		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 ( cmpr == 7 && img[ 't258' ] && img[ 't258' ].length > 3 ) img[ 't258' ] = img[ 't258' ].slice( 0, 3 );
 		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 ) {
 
 			bipp = Math.round( img[ 't279' ][ 0 ] * 8 / ( img.width * img[ 't278' ][ 0 ] ) );
@@ -113,11 +99,10 @@
 		if ( soff == null ) soff = img[ 't324' ];
 		var bcnt = img[ 't279' ];
 		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 ) ),
 			bilen = 0;
-
 		if ( img[ 't322' ] != null ) {
 
 			var tw = img[ 't322' ][ 0 ],
@@ -125,16 +110,12 @@
 			var tx = Math.floor( ( img.width + tw - 1 ) / tw );
 			var ty = Math.floor( ( img.height + th - 1 ) / th );
 			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 ++ ) {
 
 				var i = y * tx + x;
-
 				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 );
 
 			}
@@ -145,11 +126,9 @@
 
 			var rps = img[ 't278' ] ? img[ 't278' ][ 0 ] : img.height;
 			rps = Math.min( rps, img.height );
-
 			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 );
-
 				bilen += bipl * rps;
 
 			}
@@ -166,20 +145,23 @@
 
 		//console.log("compression", cmpr);
 		//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 noc = img[ 't277' ] ? img[ 't277' ][ 0 ] : 1,
 			bpp = bps * noc >>> 3,
 			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 ++ ) {
 
 				//console.log("fixing endianity");
 				var roff = toff + y * bpl;
-
 				for ( var x = 1; x < bpl; x += 2 ) {
 
 					var t = tgt[ roff + x ];
@@ -221,29 +203,23 @@
 			qw = w * 4;
 		var io = 0,
 			out = new Uint8Array( qw );
-
 		while ( io < len ) {
 
 			var oo = 0;
-
 			while ( oo < qw ) {
 
 				var c = data[ off + io ];
 				io ++;
-
 				if ( c < 128 ) {
 
 					for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io + j ];
-
 					oo += c;
 					io += c;
 
 				} else {
 
 					c = c - 126;
-
 					for ( var j = 0; j < c; j ++ ) out[ oo + j ] = data[ off + io ];
-
 					oo += c;
 					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
-
 	UTIF._types = function () {
 
 		var main = new Array( 250 );
@@ -339,14 +315,12 @@
 		};
 
 	}();
-
 	UTIF._readIFD = function ( bin, data, offset, ifds, depth, prm ) {
 
 		var cnt = bin.readUshort( data, offset );
 		offset += 2;
 		var ifd = {};
 		if ( prm.debug ) console.log( '   '.repeat( depth ), ifds.length - 1, '>>>----------------' );
-
 		for ( var i = 0; i < cnt; i ++ ) {
 
 			var tag = bin.readUshort( data, offset );
@@ -357,8 +331,8 @@
 			offset += 4;
 			var voff = bin.readUint( data, offset );
 			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 ) {
 
 				arr = new Uint8Array( data.buffer, num < 5 ? offset - 4 : voff, num );
@@ -389,7 +363,6 @@
 			if ( type == 5 || type == 10 ) {
 
 				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 ) ] );
 
 			}
@@ -428,18 +401,14 @@
 
 			if ( prm.debug ) console.log( '   '.repeat( depth ), tag, type, UTIF.tags[ 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 ) {
 
 				var oarr = tag == 50740 ? [ bin.readUint( arr, 0 ) ] : arr;
 				var subfd = [];
-
 				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 == 34665 ) ifd.exifIFD = subfd[ 0 ];
 				if ( tag == 34853 ) ifd.gpsiIFD = subfd[ 0 ]; //console.log("gps", subfd[0]);  }
-
 				if ( tag == 50740 ) ifd.dngPrvt = subfd[ 0 ];
 				if ( tag == 61440 ) ifd.fujiIFD = subfd[ 0 ];
 
@@ -447,14 +416,12 @@
 
 			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 ) {
 
 					var subsub = [];
-
 					UTIF._readIFD( bin, data, voff, subsub, depth + 1, prm );
-
 					ifd.makerNote = subsub[ 0 ];
 
 				}
@@ -476,17 +443,14 @@
 			area = w * h,
 			data = out.data;
 		let img;
-
 		switch ( type ) {
 
 			case THREE.HalfFloatType:
 				img = new Uint16Array( area * 4 );
 				break;
-
 			case THREE.FloatType:
 				img = new Float32Array( area * 4 );
 				break;
-
 			default:
 				console.error( 'THREE.LogLuvLoader: Unsupported texture data type:', type );
 
@@ -495,7 +459,6 @@
 		let intp = out[ 't262' ] ? out[ 't262' ][ 0 ] : 2;
 		const bps = out[ 't258' ] ? Math.min( 32, out[ 't258' ][ 0 ] ) : 1;
 		if ( out[ 't262' ] == null && bps == 1 ) intp = 0;
-
 		if ( intp == 32845 ) {
 
 			for ( let y = 0; y < h; y ++ ) {
@@ -507,20 +470,22 @@
 					let L = data[ si + 1 ] << 8 | data[ si ];
 					L = Math.pow( 2, ( L + 0.5 ) / 256 - 64 );
 					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 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,
 						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 g = - 1.022 * X + 1.978 * Y + 0.044 * Z;
 					const b = 0.061 * X - 0.224 * Y + 1.163 * Z;
-
 					if ( type === THREE.HalfFloatType ) {
 
 						img[ qi ] = THREE.DataUtils.toHalfFloat( Math.min( r, 65504 ) );
@@ -555,7 +520,6 @@
 		nextZero: function ( data, o ) {
 
 			while ( data[ o ] != 0 ) o ++;
-
 			return o;
 
 		},
@@ -595,27 +559,21 @@
 		readASCII: function ( buff, p, l ) {
 
 			var s = '';
-
 			for ( var i = 0; i < l; i ++ ) s += String.fromCharCode( buff[ p + i ] );
-
 			return s;
 
 		},
 		readFloat: function ( buff, p ) {
 
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + 3 - i ];
-
 			return UTIF._binBE.fl32[ 0 ];
 
 		},
 		readDouble: function ( buff, p ) {
 
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + 7 - i ];
-
 			return UTIF._binBE.fl64[ 0 ];
 
 		},
@@ -651,7 +609,6 @@
 		writeDouble: function ( buff, p, n ) {
 
 			UTIF._binBE.fl64[ 0 ] = n;
-
 			for ( var i = 0; i < 8; i ++ ) buff[ p + i ] = UTIF._binBE.ui8[ 7 - i ];
 
 		}
@@ -701,18 +658,14 @@
 		readFloat: function ( buff, p ) {
 
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 4; i ++ ) a[ i ] = buff[ p + i ];
-
 			return UTIF._binBE.fl32[ 0 ];
 
 		},
 		readDouble: function ( buff, p ) {
 
 			var a = UTIF._binBE.ui8;
-
 			for ( var i = 0; i < 8; i ++ ) a[ i ] = buff[ p + i ];
-
 			return UTIF._binBE.fl64[ 0 ];
 
 		},
@@ -742,18 +695,15 @@
 		},
 		writeASCII: UTIF._binBE.writeASCII
 	};
-
 	UTIF._copyTile = function ( tb, tw, th, b, w, h, xoff, yoff ) {
 
 		//log("copyTile", tw, th,  w, h, xoff, yoff);
 		var xlim = Math.min( tw, w - xoff );
 		var ylim = Math.min( th, h - yoff );
-
 		for ( var y = 0; y < ylim; y ++ ) {
 
 			var tof = ( yoff + y ) * w + xoff;
 			var sof = y * tw;
-
 			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;
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const quality = this._quality || 1;
@@ -18,7 +17,9 @@
 			loader.setWithCredentials( this.withCredentials );
 			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
 
 				const container = document.createElement( 'div' );
@@ -43,7 +44,6 @@
 
 				} );
 				container.style.display = 'none';
-
 				if ( onLoad !== undefined ) {
 
 					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)
  * vertex data for each frame (sequence of float32)
  */
-
 	class MDDLoader extends THREE.Loader {
 
 		constructor( manager ) {
@@ -19,7 +18,6 @@
 			super( manager );
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const scope = this;
@@ -33,17 +31,17 @@
 			}, onProgress, onError );
 
 		}
-
 		parse( data ) {
 
 			const view = new DataView( data );
 			const totalFrames = view.getUint32( 0 );
 			const totalPoints = view.getUint32( 4 );
-			let offset = 8; // animation clip
+			let offset = 8;
+
+			// animation clip
 
 			const times = new Float32Array( totalFrames );
 			const values = new Float32Array( totalFrames * totalFrames ).fill( 0 );
-
 			for ( let i = 0; i < totalFrames; i ++ ) {
 
 				times[ i ] = view.getFloat32( offset );
@@ -53,23 +51,21 @@
 			}
 
 			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 ++ ) {
 
 				const morphTarget = new Float32Array( totalPoints * 3 );
-
 				for ( let j = 0; j < totalPoints; j ++ ) {
 
 					const stride = j * 3;
 					morphTarget[ stride + 0 ] = view.getFloat32( offset );
 					offset += 4; // x
-
 					morphTarget[ stride + 1 ] = view.getFloat32( offset );
 					offset += 4; // y
-
 					morphTarget[ stride + 2 ] = view.getFloat32( offset );
 					offset += 4; // z
 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 22 - 35
examples/js/loaders/MMDLoader.js


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

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

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

@@ -7,7 +7,6 @@
 			super( manager );
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const scope = this;
@@ -41,18 +40,15 @@
 			}, onProgress, onError );
 
 		}
-
 		parse( data ) {
 
 			// this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X
+
 			let _data = data;
 			let _dataPointer = 0;
-
 			const _nativeLittleEndian = new Int8Array( new Int16Array( [ 1 ] ).buffer )[ 0 ] > 0;
-
 			const _littleEndian = true;
 			const headerObject = {};
-
 			function scan( type, chunks ) {
 
 				if ( chunks === undefined || chunks === null ) {
@@ -63,60 +59,51 @@
 
 				let _chunkSize = 1;
 				let _array_type = Uint8Array;
-
 				switch ( type ) {
 
 					// 1 byte data types
 					case 'uchar':
 						break;
-
 					case 'schar':
 						_array_type = Int8Array;
 						break;
 						// 2 byte data types
-
 					case 'ushort':
 						_array_type = Uint16Array;
 						_chunkSize = 2;
 						break;
-
 					case 'sshort':
 						_array_type = Int16Array;
 						_chunkSize = 2;
 						break;
 						// 4 byte data types
-
 					case 'uint':
 						_array_type = Uint32Array;
 						_chunkSize = 4;
 						break;
-
 					case 'sint':
 						_array_type = Int32Array;
 						_chunkSize = 4;
 						break;
-
 					case 'float':
 						_array_type = Float32Array;
 						_chunkSize = 4;
 						break;
-
 					case 'complex':
 						_array_type = Float64Array;
 						_chunkSize = 8;
 						break;
-
 					case 'double':
 						_array_type = Float64Array;
 						_chunkSize = 8;
 						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 ) {
 
 					// 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
 					return _bytes[ 0 ];
 
-				} // return the byte array
-
+				}
 
+				// return the byte array
 				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 ) {
 
 				const u8 = new Uint8Array( array.buffer, array.byteOffset, array.byteLength );
-
 				for ( let i = 0; i < array.byteLength; i += chunkSize ) {
 
 					for ( let j = i + chunkSize - 1, k = i; j > k; j --, k ++ ) {
@@ -155,19 +142,16 @@
 
 				return array;
 
-			} //parse the header
-
+			}
 
+			//parse the header
 			function parseHeader( header ) {
 
 				let data, field, fn, i, l, m, _i, _len;
-
 				const lines = header.split( /\r?\n/ );
-
 				for ( _i = 0, _len = lines.length; _i < _len; _i ++ ) {
 
 					l = lines[ _i ];
-
 					if ( l.match( /NRRD\d+/ ) ) {
 
 						headerObject.isNrrd = true;
@@ -177,7 +161,6 @@
 						field = m[ 1 ].trim();
 						data = m[ 2 ].trim();
 						fn = _fieldFunctions[ field ];
-
 						if ( fn ) {
 
 							fn.call( headerObject, data );
@@ -210,8 +193,9 @@
 					headerObject.vectors = [];
 					headerObject.vectors.push( [ 1, 0, 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 ) {
 
 						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 ) {
 
 				let number = '';
 				start = start || 0;
 				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 ) {
 
 					return previous * current;
 
 				}, 1 );
 				let base = 10;
-
 				if ( headerObject.encoding === 'hex' ) {
 
 					base = 16;
@@ -258,7 +241,6 @@
 				const result = new headerObject.__array( lengthOfTheResult );
 				let resultIndex = 0;
 				let parsingFunction = parseInt;
-
 				if ( headerObject.__array === Float32Array || headerObject.__array === Float64Array ) {
 
 					parsingFunction = parseFloat;
@@ -267,8 +249,8 @@
 
 				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 ) {
 
 						number += String.fromCharCode( value );
@@ -300,31 +282,28 @@
 			}
 
 			const _bytes = scan( 'uchar', data.byteLength );
-
 			const _length = _bytes.length;
 			let _header = null;
 			let _data_start = 0;
 			let i;
-
 			for ( i = 1; i < _length; i ++ ) {
 
 				if ( _bytes[ i - 1 ] == 10 && _bytes[ i ] == 10 ) {
 
 					// we found two line breaks in a row
 					// 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;
 					break;
 
 				}
 
-			} // parse the header
-
+			}
 
+			// parse the header
 			parseHeader( _header );
 			_data = _bytes.subarray( _data_start ); // the data without header
-
 			if ( headerObject.encoding.substring( 0, 2 ) === 'gz' ) {
 
 				// 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
 				const _copy = new Uint8Array( _data.length );
-
 				for ( let i = 0; i < _data.length; i ++ ) {
 
 					_copy[ i ] = _data[ i ];
@@ -348,29 +326,31 @@
 
 				_data = _copy;
 
-			} // .. let's use the underlying array buffer
-
+			}
 
+			// .. let's use the underlying array buffer
 			_data = _data.buffer;
 			const volume = new THREE.Volume();
-			volume.header = headerObject; //
+			volume.header = headerObject;
+			//
 			// 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 = 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.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.xLength = volume.dimensions[ 0 ];
 			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 ) {
 
 				const xIndex = headerObject.vectors.findIndex( vector => vector[ 0 ] !== 0 );
@@ -386,17 +366,17 @@
 
 				volume.axisOrder = [ 'x', 'y', 'z' ];
 
-			} // spacing
-
+			}
 
+			// spacing
 			const spacingX = new THREE.Vector3().fromArray( headerObject.vectors[ 0 ] ).length();
 			const spacingY = new THREE.Vector3().fromArray( headerObject.vectors[ 1 ] ).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();
 			const transitionMatrix = new THREE.Matrix4();
-
 			if ( headerObject.space === 'left-posterior-superior' ) {
 
 				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.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 ) {
 
 				volume.lowerThreshold = min;
@@ -440,7 +421,6 @@
 			return volume;
 
 		}
-
 		parseChars( array, start, end ) {
 
 			// 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;
-
 			for ( i = start; i < end; ++ i ) {
 
 				output += String.fromCharCode( array[ i ] );
@@ -471,7 +450,6 @@
 		}
 
 	}
-
 	const _fieldFunctions = {
 		type: function ( data ) {
 
@@ -483,13 +461,11 @@
 				case 'uint8_t':
 					this.__array = Uint8Array;
 					break;
-
 				case 'signed char':
 				case 'int8':
 				case 'int8_t':
 					this.__array = Int8Array;
 					break;
-
 				case 'short':
 				case 'short int':
 				case 'signed short':
@@ -498,7 +474,6 @@
 				case 'int16_t':
 					this.__array = Int16Array;
 					break;
-
 				case 'ushort':
 				case 'unsigned short':
 				case 'unsigned short int':
@@ -506,29 +481,24 @@
 				case 'uint16_t':
 					this.__array = Uint16Array;
 					break;
-
 				case 'int':
 				case 'signed int':
 				case 'int32':
 				case 'int32_t':
 					this.__array = Int32Array;
 					break;
-
 				case 'uint':
 				case 'unsigned int':
 				case 'uint32':
 				case 'uint32_t':
 					this.__array = Uint32Array;
 					break;
-
 				case 'float':
 					this.__array = Float32Array;
 					break;
-
 				case 'double':
 					this.__array = Float64Array;
 					break;
-
 				default:
 					throw new Error( 'Unsupported NRRD data type: ' + data );
 
@@ -558,13 +528,10 @@
 			return this.sizes = function () {
 
 				const _ref = data.split( /\s+/ );
-
 				const _results = [];
-
 				for ( let _i = 0, _len = _ref.length; _i < _len; _i ++ ) {
 
 					i = _ref[ _i ];
-
 					_results.push( parseInt( i, 10 ) );
 
 				}
@@ -591,21 +558,16 @@
 			return this.vectors = function () {
 
 				const _results = [];
-
 				for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) {
 
 					v = parts[ _i ];
-
 					_results.push( function () {
 
 						const _ref = v.slice( 1, - 1 ).split( /,/ );
-
 						const _results2 = [];
-
 						for ( let _j = 0, _len2 = _ref.length; _j < _len2; _j ++ ) {
 
 							f = _ref[ _j ];
-
 							_results2.push( parseFloat( f ) );
 
 						}
@@ -628,11 +590,9 @@
 			return this.spacings = function () {
 
 				const _results = [];
-
 				for ( let _i = 0, _len = parts.length; _i < _len; _i ++ ) {
 
 					f = parts[ _i ];
-
 					_results.push( parseFloat( f ) );
 
 				}

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

@@ -1,26 +1,20 @@
 ( 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 _face_vertex_data_separator_pattern = /\s+/;
-
 	const _vA = new THREE.Vector3();
-
 	const _vB = new THREE.Vector3();
-
 	const _vC = new THREE.Vector3();
-
 	const _ab = new THREE.Vector3();
-
 	const _cb = new THREE.Vector3();
-
 	const _color = new THREE.Color();
-
 	function ParserState() {
 
 		const state = {
@@ -45,7 +39,6 @@
 				}
 
 				const previousMaterial = this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined;
-
 				if ( this.object && typeof this.object._finalize === 'function' ) {
 
 					this.object._finalize( true );
@@ -66,10 +59,10 @@
 					smooth: true,
 					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 ) ) {
 
 							this.materials.splice( previous.index, 1 );
@@ -120,16 +113,15 @@
 					_finalize: function ( end ) {
 
 						const lastMultiMaterial = this.currentMaterial();
-
 						if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
 
 							lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
 							lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
 							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 ) {
 
 							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 ) {
 
 							this.materials.push( {
@@ -157,7 +149,9 @@
 						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.
 				// 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
@@ -237,21 +231,13 @@
 
 				const src = this.vertices;
 				const dst = this.object.geometry.normals;
-
 				_vA.fromArray( src, a );
-
 				_vB.fromArray( src, b );
-
 				_vC.fromArray( src, c );
-
 				_cb.subVectors( _vC, _vB );
-
 				_ab.subVectors( _vA, _vB );
-
 				_cb.cross( _ab );
-
 				_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 );
@@ -297,7 +283,9 @@
 				let ib = this.parseVertexIndex( b, vLen );
 				let ic = this.parseVertexIndex( c, vLen );
 				this.addVertex( ia, ib, ic );
-				this.addColor( ia, ib, ic ); // normals
+				this.addColor( ia, ib, ic );
+
+				// normals
 
 				if ( na !== undefined && na !== '' ) {
 
@@ -311,8 +299,9 @@
 
 					this.addFaceNormal( ia, ib, ic );
 
-				} // uvs
+				}
 
+				// uvs
 
 				if ( ua !== undefined && ua !== '' ) {
 
@@ -326,6 +315,7 @@
 				} else {
 
 					// add placeholder values (for inconsistent face definitions)
+
 					this.addDefaultUV();
 
 				}
@@ -335,7 +325,6 @@
 
 				this.object.geometry.type = 'Points';
 				const vLen = this.vertices.length;
-
 				for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
 
 					const index = this.parseVertexIndex( vertices[ vi ], vLen );
@@ -350,7 +339,6 @@
 				this.object.geometry.type = 'Line';
 				const vLen = this.vertices.length;
 				const uvLen = this.uvs.length;
-
 				for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
 
 					this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
@@ -368,8 +356,9 @@
 		state.startObject( '', false );
 		return state;
 
-	} //
+	}
 
+	//
 
 	class OBJLoader extends THREE.Loader {
 
@@ -379,7 +368,6 @@
 			this.materials = null;
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			const scope = this;
@@ -412,18 +400,15 @@
 			}, onProgress, onError );
 
 		}
-
 		setMaterials( materials ) {
 
 			this.materials = materials;
 			return this;
 
 		}
-
 		parse( text ) {
 
 			const state = new ParserState();
-
 			if ( text.indexOf( '\r\n' ) !== - 1 ) {
 
 				// This is faster than String.split with regex that splits on both
@@ -440,43 +425,38 @@
 
 			const lines = text.split( '\n' );
 			let result = [];
-
 			for ( let i = 0, l = lines.length; i < l; i ++ ) {
 
 				const line = lines[ i ].trimStart();
 				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 === 'v' ) {
 
 					const data = line.split( _face_vertex_data_separator_pattern );
-
 					switch ( data[ 0 ] ) {
 
 						case 'v':
 							state.vertices.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );
-
 							if ( data.length >= 7 ) {
 
 								_color.setRGB( parseFloat( data[ 4 ] ), parseFloat( data[ 5 ] ), parseFloat( data[ 6 ] ) ).convertSRGBToLinear();
-
 								state.colors.push( _color.r, _color.g, _color.b );
 
 							} else {
 
 								// if no colors are defined, add placeholders so color and vertex indices match
+
 								state.colors.push( undefined, undefined, undefined );
 
 							}
 
 							break;
-
 						case 'vn':
 							state.normals.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );
 							break;
-
 						case 'vt':
 							state.uvs.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ) );
 							break;
@@ -487,12 +467,13 @@
 
 					const lineData = line.slice( 1 ).trim();
 					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 ++ ) {
 
 						const vertex = vertexData[ j ];
-
 						if ( vertex.length > 0 ) {
 
 							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 ];
-
 					for ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {
 
 						const v2 = faceVertices[ j ];
@@ -518,7 +499,6 @@
 					const lineParts = line.substring( 1 ).trim().split( ' ' );
 					let lineVertices = [];
 					const lineUVs = [];
-
 					if ( line.indexOf( '/' ) === - 1 ) {
 
 						lineVertices = lineParts;
@@ -548,6 +528,7 @@
 					// o object_name
 					// or
 					// g group_name
+
 					// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
 					// let name = result[ 0 ].slice( 1 ).trim();
 					const name = ( ' ' + result[ 0 ].slice( 1 ).trim() ).slice( 1 );
@@ -556,22 +537,28 @@
 				} else if ( _material_use_pattern.test( line ) ) {
 
 					// material
+
 					state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
 
 				} else if ( _material_library_pattern.test( line ) ) {
 
 					// mtl file
+
 					state.materialLibraries.push( line.substring( 7 ).trim() );
 
 				} else if ( _map_use_pattern.test( line ) ) {
 
 					// 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)
+
 					console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' );
 
 				} 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,
 					// but does not define a usemtl for each face set.
 					// 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
         	 * than 0."
         	 */
-
 					if ( result.length > 1 ) {
 
 						const value = result[ 1 ].trim().toLowerCase();
@@ -618,7 +604,6 @@
 			const container = new THREE.Group();
 			container.materialLibraries = [].concat( state.materialLibraries );
 			const hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 );
-
 			if ( hasPrimitives === true ) {
 
 				for ( let i = 0, l = state.objects.length; i < l; i ++ ) {
@@ -628,12 +613,12 @@
 					const materials = object.materials;
 					const isLine = geometry.type === 'Line';
 					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;
 					const buffergeometry = new THREE.BufferGeometry();
 					buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );
-
 					if ( geometry.normals.length > 0 ) {
 
 						buffergeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );
@@ -651,21 +636,21 @@
 
 						buffergeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );
 
-					} // Create materials
+					}
 
+					// Create materials
 
 					const createdMaterials = [];
-
 					for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
 
 						const sourceMaterial = materials[ mi ];
 						const materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors;
 						let material = state.materials[ materialHash ];
-
 						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 ) ) {
 
 								const materialLine = new THREE.LineBasicMaterial();
@@ -716,11 +701,11 @@
 
 						createdMaterials.push( material );
 
-					} // Create mesh
+					}
 
+					// Create mesh
 
 					let mesh;
-
 					if ( createdMaterials.length > 1 ) {
 
 						for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
@@ -770,6 +755,7 @@
 			} else {
 
 				// if there is only the default parser state object with no geometry data, interpret data as point cloud
+
 				if ( state.vertices.length > 0 ) {
 
 					const material = new THREE.PointsMaterial( {
@@ -778,7 +764,6 @@
 					} );
 					const buffergeometry = new THREE.BufferGeometry();
 					buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( state.vertices, 3 ) );
-
 					if ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) {
 
 						buffergeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( state.colors, 3 ) );

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

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

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

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

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

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

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

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

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

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

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

@@ -1,5 +1,6 @@
 ( function () {
 
+	// https://github.com/mrdoob/three.js/issues/5552
 	// http://en.wikipedia.org/wiki/RGBE_image_format
 
 	class RGBELoader extends THREE.DataTextureLoader {
@@ -9,16 +10,15 @@
 			super( manager );
 			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 ) {
 
-			const
-				/* return codes for rgbe routines */
+			const /* return codes for rgbe routines */
 				//RGBE_RETURN_SUCCESS = 0,
 				RGBE_RETURN_FAILURE = - 1,
-
 				/* default error routine.  change this to change error handling */
 				rgbe_read_error = 1,
 				rgbe_write_error = 2,
@@ -31,15 +31,12 @@
 						case rgbe_read_error:
 							console.error( 'THREE.RGBELoader Read Error: ' + ( msg || '' ) );
 							break;
-
 						case rgbe_write_error:
 							console.error( 'THREE.RGBELoader Write Error: ' + ( msg || '' ) );
 							break;
-
 						case rgbe_format_error:
 							console.error( 'THREE.RGBELoader Bad File Format: ' + ( msg || '' ) );
 							break;
-
 						default:
 						case rgbe_memory_error:
 							console.error( 'THREE.RGBELoader: Error: ' + ( msg || '' ) );
@@ -49,7 +46,6 @@
 					return RGBE_RETURN_FAILURE;
 
 				},
-
 				/* offsets to red, green, and blue components in a data (float) pixel */
 				//RGBE_DATA_RED = 0,
 				//RGBE_DATA_GREEN = 1,
@@ -72,7 +68,6 @@
 						len = 0,
 						s = '',
 						chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );
-
 					while ( 0 > ( i = chunk.indexOf( NEWLINE ) ) && len < lineLimit && p < buffer.byteLength ) {
 
 						s += chunk;
@@ -85,11 +80,11 @@
 					if ( - 1 < 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;
 						return s + chunk.slice( 0, i );
 
@@ -98,7 +93,6 @@
 					return false;
 
 				},
-
 				/* minimal header reading.  modify if you want to parse more information */
 				RGBE_ReadHeader = function ( buffer ) {
 
@@ -111,41 +105,38 @@
 						// RGBE format header struct
 						header = {
 							valid: 0,
-
 							/* indicate which fields are valid */
-							string: '',
 
+							string: '',
 							/* the actual header string */
-							comments: '',
 
+							comments: '',
 							/* comments found in header */
-							programtype: 'RGBE',
 
+							programtype: 'RGBE',
 							/* listed at beginning of file to identify it after "#?". defaults to "RGBE" */
-							format: '',
 
+							format: '',
 							/* 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) */
-							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 */
-							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 ) ) ) {
 
 						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 ) ) ) {
 
 						return rgbe_error( rgbe_format_error, 'bad initial token' );
@@ -155,13 +146,11 @@
 					header.valid |= RGBE_VALID_PROGRAMTYPE;
 					header.programtype = match[ 1 ];
 					header.string += line + '\n';
-
 					while ( true ) {
 
 						line = fgets( buffer );
 						if ( false === line ) break;
 						header.string += line + '\n';
-
 						if ( '#' === line.charAt( 0 ) ) {
 
 							header.comments += line + '\n';
@@ -218,10 +207,11 @@
 				RGBE_ReadPixels_RLE = function ( buffer, w, h ) {
 
 					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 new Uint8Array( buffer );
@@ -235,7 +225,6 @@
 					}
 
 					const data_rgba = new Uint8Array( 4 * w * h );
-
 					if ( ! data_rgba.length ) {
 
 						return rgbe_error( rgbe_memory_error, 'unable to allocate buffer space' );
@@ -247,8 +236,9 @@
 					const ptr_end = 4 * scanline_width;
 					const rgbeStart = new Uint8Array( 4 );
 					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 ) {
 
 						if ( pos + 4 > buffer.byteLength ) {
@@ -261,24 +251,21 @@
 						rgbeStart[ 1 ] = buffer[ pos ++ ];
 						rgbeStart[ 2 ] = buffer[ pos ++ ];
 						rgbeStart[ 3 ] = buffer[ pos ++ ];
-
 						if ( 2 != rgbeStart[ 0 ] || 2 != rgbeStart[ 1 ] || ( rgbeStart[ 2 ] << 8 | rgbeStart[ 3 ] ) != scanline_width ) {
 
 							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,
 							count;
-
 						while ( ptr < ptr_end && pos < buffer.byteLength ) {
 
 							count = buffer[ pos ++ ];
 							const isEncodedRun = count > 128;
 							if ( isEncodedRun ) count -= 128;
-
 							if ( 0 === count || ptr + count > ptr_end ) {
 
 								return rgbe_error( rgbe_format_error, 'bad scanline data' );
@@ -289,12 +276,12 @@
 
 								// a (encoded) run of the same value
 								const byteValue = buffer[ pos ++ ];
-
 								for ( let i = 0; i < count; i ++ ) {
 
 									scanline_buffer[ ptr ++ ] = byteValue;
 
-								} //ptr += count;
+								}
+								//ptr += count;
 
 							} 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;
-
 						for ( let i = 0; i < l; i ++ ) {
 
 							let off = 0;
 							data_rgba[ offset ] = scanline_buffer[ i + off ];
 							off += scanline_width; //1;
-
 							data_rgba[ offset + 1 ] = scanline_buffer[ i + off ];
 							off += scanline_width; //1;
-
 							data_rgba[ offset + 2 ] = scanline_buffer[ i + off ];
 							off += scanline_width; //1;
-
 							data_rgba[ offset + 3 ] = scanline_buffer[ i + off ];
 							offset += 4;
 
@@ -350,8 +333,9 @@
 			const RGBEByteToRGBHalf = function ( sourceArray, sourceOffset, destArray, destOffset ) {
 
 				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 + 1 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 1 ] * scale, 65504 ) );
 				destArray[ destOffset + 2 ] = THREE.DataUtils.toHalfFloat( Math.min( sourceArray[ sourceOffset + 2 ] * scale, 65504 ) );
@@ -362,24 +346,20 @@
 			const byteArray = new Uint8Array( buffer );
 			byteArray.pos = 0;
 			const rgbe_header_info = RGBE_ReadHeader( byteArray );
-
 			if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {
 
 				const w = rgbe_header_info.width,
 					h = rgbe_header_info.height,
 					image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h );
-
 				if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {
 
 					let data, type;
 					let numElements;
-
 					switch ( this.type ) {
 
 						case THREE.FloatType:
 							numElements = image_rgba_data.length / 4;
 							const floatArray = new Float32Array( numElements * 4 );
-
 							for ( let j = 0; j < numElements; j ++ ) {
 
 								RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 4 );
@@ -389,11 +369,9 @@
 							data = floatArray;
 							type = THREE.FloatType;
 							break;
-
 						case THREE.HalfFloatType:
 							numElements = image_rgba_data.length / 4;
 							const halfArray = new Uint16Array( numElements * 4 );
-
 							for ( let j = 0; j < numElements; j ++ ) {
 
 								RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 4 );
@@ -403,7 +381,6 @@
 							data = halfArray;
 							type = THREE.HalfFloatType;
 							break;
-
 						default:
 							console.error( 'THREE.RGBELoader: unsupported type: ', this.type );
 							break;
@@ -427,14 +404,12 @@
 			return null;
 
 		}
-
 		setDataType( value ) {
 
 			this.type = value;
 			return this;
 
 		}
-
 		load( url, onLoad, onProgress, onError ) {
 
 			function onLoadCallback( texture, texData ) {

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

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

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است