Bladeren bron

Examples: Convert lines to ES6. (#21599)

Michael Herzog 4 jaren geleden
bovenliggende
commit
7a8a35eca8

+ 10 - 11
examples/js/lines/Line2.js

@@ -1,20 +1,19 @@
 ( function () {
 
-	var Line2 = function ( geometry, material ) {
+	class Line2 extends THREE.LineSegments2 {
 
-		if ( geometry === undefined ) geometry = new THREE.LineGeometry();
-		if ( material === undefined ) material = new THREE.LineMaterial( {
+		constructor( geometry = new THREE.LineGeometry(), material = new THREE.LineMaterial( {
 			color: Math.random() * 0xffffff
-		} );
-		THREE.LineSegments2.call( this, geometry, material );
-		this.type = 'Line2';
+		} ) ) {
 
-	};
+			super( geometry, material );
+			this.type = 'Line2';
 
-	Line2.prototype = Object.assign( Object.create( THREE.LineSegments2.prototype ), {
-		constructor: Line2,
-		isLine2: true
-	} );
+		}
+
+	}
+
+	Line2.prototype.isLine2 = true;
 
 	THREE.Line2 = Line2;
 

+ 22 - 17
examples/js/lines/LineGeometry.js

@@ -1,16 +1,15 @@
 ( function () {
 
-	var LineGeometry = function () {
+	class LineGeometry extends THREE.LineSegmentsGeometry {
 
-		THREE.LineSegmentsGeometry.call( this );
-		this.type = 'LineGeometry';
+		constructor() {
 
-	};
+			super();
+			this.type = 'LineGeometry';
 
-	LineGeometry.prototype = Object.assign( Object.create( THREE.LineSegmentsGeometry.prototype ), {
-		constructor: LineGeometry,
-		isLineGeometry: true,
-		setPositions: function ( array ) {
+		}
+
+		setPositions( array ) {
 
 			// converts [ x1, y1, z1,	x2, y2, z2, ... ] to pairs format
 			var length = array.length - 3;
@@ -27,11 +26,12 @@
 
 			}
 
-			THREE.LineSegmentsGeometry.prototype.setPositions.call( this, points );
+			super.setPositions( points );
 			return this;
 
-		},
-		setColors: function ( array ) {
+		}
+
+		setColors( array ) {
 
 			// converts [ r1, g1, b1,	r2, g2, b2, ... ] to pairs format
 			var length = array.length - 3;
@@ -48,11 +48,12 @@
 
 			}
 
-			THREE.LineSegmentsGeometry.prototype.setColors.call( this, colors );
+			super.setColors( colors );
 			return this;
 
-		},
-		fromLine: function ( line ) {
+		}
+
+		fromLine( line ) {
 
 			var geometry = line.geometry;
 
@@ -70,14 +71,18 @@
 
 			return this;
 
-		},
-		copy: function ( ) {
+		}
+
+		copy( ) {
 
 			// todo
 			return this;
 
 		}
-	} );
+
+	}
+
+	LineGeometry.prototype.isLineGeometry = true;
 
 	THREE.LineGeometry = LineGeometry;
 

+ 99 - 97
examples/js/lines/LineMaterial.js

@@ -264,158 +264,160 @@
 		`
 	};
 
-	var LineMaterial = function ( parameters ) {
+	class LineMaterial extends THREE.ShaderMaterial {
 
-		THREE.ShaderMaterial.call( this, {
-			type: 'LineMaterial',
-			uniforms: THREE.UniformsUtils.clone( THREE.ShaderLib[ 'line' ].uniforms ),
-			vertexShader: THREE.ShaderLib[ 'line' ].vertexShader,
-			fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader,
-			clipping: true // required for clipping support
+		constructor( parameters ) {
 
-		} );
-		this.dashed = false;
-		Object.defineProperties( this, {
-			color: {
-				enumerable: true,
-				get: function () {
+			super( {
+				type: 'LineMaterial',
+				uniforms: THREE.UniformsUtils.clone( THREE.ShaderLib[ 'line' ].uniforms ),
+				vertexShader: THREE.ShaderLib[ 'line' ].vertexShader,
+				fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader,
+				clipping: true // required for clipping support
 
-					return this.uniforms.diffuse.value;
+			} );
+			this.dashed = false;
+			Object.defineProperties( this, {
+				color: {
+					enumerable: true,
+					get: function () {
 
-				},
-				set: function ( value ) {
-
-					this.uniforms.diffuse.value = value;
+						return this.uniforms.diffuse.value;
 
-				}
-			},
-			linewidth: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return this.uniforms.linewidth.value;
+						this.uniforms.diffuse.value = value;
 
+					}
 				},
-				set: function ( value ) {
+				linewidth: {
+					enumerable: true,
+					get: function () {
 
-					this.uniforms.linewidth.value = value;
+						return this.uniforms.linewidth.value;
 
-				}
-			},
-			dashScale: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return this.uniforms.dashScale.value;
+						this.uniforms.linewidth.value = value;
 
+					}
 				},
-				set: function ( value ) {
+				dashScale: {
+					enumerable: true,
+					get: function () {
 
-					this.uniforms.dashScale.value = value;
+						return this.uniforms.dashScale.value;
 
-				}
-			},
-			dashSize: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return this.uniforms.dashSize.value;
+						this.uniforms.dashScale.value = value;
 
+					}
 				},
-				set: function ( value ) {
+				dashSize: {
+					enumerable: true,
+					get: function () {
 
-					this.uniforms.dashSize.value = value;
+						return this.uniforms.dashSize.value;
 
-				}
-			},
-			dashOffset: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return this.uniforms.dashOffset.value;
+						this.uniforms.dashSize.value = value;
 
+					}
 				},
-				set: function ( value ) {
+				dashOffset: {
+					enumerable: true,
+					get: function () {
 
-					this.uniforms.dashOffset.value = value;
+						return this.uniforms.dashOffset.value;
 
-				}
-			},
-			gapSize: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return this.uniforms.gapSize.value;
+						this.uniforms.dashOffset.value = value;
 
+					}
 				},
-				set: function ( value ) {
+				gapSize: {
+					enumerable: true,
+					get: function () {
 
-					this.uniforms.gapSize.value = value;
+						return this.uniforms.gapSize.value;
 
-				}
-			},
-			opacity: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return this.uniforms.opacity.value;
+						this.uniforms.gapSize.value = value;
 
+					}
 				},
-				set: function ( value ) {
+				opacity: {
+					enumerable: true,
+					get: function () {
 
-					this.uniforms.opacity.value = value;
+						return this.uniforms.opacity.value;
 
-				}
-			},
-			resolution: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return this.uniforms.resolution.value;
+						this.uniforms.opacity.value = value;
 
+					}
 				},
-				set: function ( value ) {
+				resolution: {
+					enumerable: true,
+					get: function () {
 
-					this.uniforms.resolution.value.copy( value );
+						return this.uniforms.resolution.value;
 
-				}
-			},
-			alphaToCoverage: {
-				enumerable: true,
-				get: function () {
+					},
+					set: function ( value ) {
 
-					return Boolean( 'ALPHA_TO_COVERAGE' in this.defines );
+						this.uniforms.resolution.value.copy( value );
 
+					}
 				},
-				set: function ( value ) {
+				alphaToCoverage: {
+					enumerable: true,
+					get: function () {
 
-					if ( Boolean( value ) !== Boolean( 'ALPHA_TO_COVERAGE' in this.defines ) ) {
+						return Boolean( 'ALPHA_TO_COVERAGE' in this.defines );
 
-						this.needsUpdate = true;
+					},
+					set: function ( value ) {
 
-					}
+						if ( Boolean( value ) !== Boolean( 'ALPHA_TO_COVERAGE' in this.defines ) ) {
 
-					if ( value ) {
+							this.needsUpdate = true;
 
-						this.defines.ALPHA_TO_COVERAGE = '';
-						this.extensions.derivatives = true;
+						}
 
-					} else {
+						if ( value ) {
 
-						delete this.defines.ALPHA_TO_COVERAGE;
-						this.extensions.derivatives = false;
+							this.defines.ALPHA_TO_COVERAGE = '';
+							this.extensions.derivatives = true;
 
-					}
+						} else {
+
+							delete this.defines.ALPHA_TO_COVERAGE;
+							this.extensions.derivatives = false;
 
+						}
+
+					}
 				}
-			}
-		} );
-		this.setValues( parameters );
+			} );
+			this.setValues( parameters );
 
-	};
+		}
+
+	}
 
-	LineMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
-	LineMaterial.prototype.constructor = LineMaterial;
 	LineMaterial.prototype.isLineMaterial = true;
 
 	THREE.LineMaterial = LineMaterial;

+ 205 - 165
examples/js/lines/LineSegments2.js

@@ -1,242 +1,282 @@
 ( function () {
 
-	var LineSegments2 = function ( geometry, material ) {
+	const _start = new THREE.Vector3();
 
-		if ( geometry === undefined ) geometry = new THREE.LineSegmentsGeometry();
-		if ( material === undefined ) material = new THREE.LineMaterial( {
+	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();
+
+	class LineSegments2 extends THREE.Mesh {
+
+		constructor( geometry = new THREE.LineSegmentsGeometry(), material = new THREE.LineMaterial( {
 			color: Math.random() * 0xffffff
-		} );
-		THREE.Mesh.call( this, geometry, material );
-		this.type = 'LineSegments2';
+		} ) ) {
 
-	};
+			super( geometry, material );
+			this.type = 'LineSegments2';
 
-	LineSegments2.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
-		constructor: LineSegments2,
-		isLineSegments2: true,
-		computeLineDistances: function () {
+		} // for backwards-compatability, but could be a method of THREE.LineSegmentsGeometry...
 
-			// for backwards-compatability, but could be a method of THREE.LineSegmentsGeometry...
-			var start = new THREE.Vector3();
-			var end = new THREE.Vector3();
-			return function computeLineDistances() {
 
-				var geometry = this.geometry;
-				var instanceStart = geometry.attributes.instanceStart;
-				var instanceEnd = geometry.attributes.instanceEnd;
-				var lineDistances = new Float32Array( 2 * instanceStart.count );
+		computeLineDistances() {
 
-				for ( var i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
+			const geometry = this.geometry;
+			const instanceStart = geometry.attributes.instanceStart;
+			const instanceEnd = geometry.attributes.instanceEnd;
+			const lineDistances = new Float32Array( 2 * instanceStart.count );
 
-					start.fromBufferAttribute( instanceStart, i );
-					end.fromBufferAttribute( instanceEnd, i );
-					lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
-					lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
+			for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 
-				}
+				_start.fromBufferAttribute( instanceStart, i );
 
-				var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
+				_end.fromBufferAttribute( instanceEnd, i );
 
-				geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
+				lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
+				lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 
-				geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
+			}
 
-				return this;
+			const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
-			};
+			geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
 
-		}(),
-		raycast: function () {
+			geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
-			var start = new THREE.Vector4();
-			var end = new THREE.Vector4();
-			var ssOrigin = new THREE.Vector4();
-			var ssOrigin3 = new THREE.Vector3();
-			var mvMatrix = new THREE.Matrix4();
-			var line = new THREE.Line3();
-			var closestPoint = new THREE.Vector3();
-			var box = new THREE.Box3();
-			var sphere = new THREE.Sphere();
-			var clipToWorldVector = new THREE.Vector4();
-			return function raycast( raycaster, intersects ) {
+			return this;
 
-				if ( raycaster.camera === null ) {
+		}
 
-					console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' );
+		raycast( raycaster, intersects ) {
 
-				}
+			if ( raycaster.camera === null ) {
 
-				var threshold = raycaster.params.Line2 !== undefined ? raycaster.params.Line2.threshold || 0 : 0;
-				var ray = raycaster.ray;
-				var camera = raycaster.camera;
-				var projectionMatrix = camera.projectionMatrix;
-				var matrixWorld = this.matrixWorld;
-				var geometry = this.geometry;
-				var material = this.material;
-				var resolution = material.resolution;
-				var lineWidth = material.linewidth + threshold;
-				var instanceStart = geometry.attributes.instanceStart;
-				var instanceEnd = geometry.attributes.instanceEnd; // camera forward is negative
+				console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' );
 
-				var near = - camera.near; // clip space is [ - 1, 1 ] so multiply by two to get the full
-				// width in clip space
+			}
 
-				var ssMaxWidth = 2.0 * Math.max( lineWidth / resolution.width, lineWidth / resolution.height ); //
-				// check if we intersect the sphere bounds
+			const threshold = raycaster.params.Line2 !== undefined ? raycaster.params.Line2.threshold || 0 : 0;
+			const ray = raycaster.ray;
+			const camera = raycaster.camera;
+			const projectionMatrix = camera.projectionMatrix;
+			const matrixWorld = this.matrixWorld;
+			const geometry = this.geometry;
+			const material = this.material;
+			const resolution = material.resolution;
+			const lineWidth = material.linewidth + threshold;
+			const instanceStart = geometry.attributes.instanceStart;
+			const instanceEnd = geometry.attributes.instanceEnd; // camera forward is negative
 
-				if ( geometry.boundingSphere === null ) {
+			const near = - camera.near; // clip space is [ - 1, 1 ] so multiply by two to get the full
+			// width in clip space
 
-					geometry.computeBoundingSphere();
+			const ssMaxWidth = 2.0 * Math.max( lineWidth / resolution.width, lineWidth / resolution.height ); //
+			// check if we intersect the sphere bounds
 
-				}
+			if ( geometry.boundingSphere === null ) {
 
-				sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
-				var distanceToSphere = Math.max( camera.near, sphere.distanceToPoint( ray.origin ) ); // get the w component to scale the world space line width
+				geometry.computeBoundingSphere();
 
-				clipToWorldVector.set( 0, 0, - distanceToSphere, 1.0 ).applyMatrix4( camera.projectionMatrix );
-				clipToWorldVector.multiplyScalar( 1.0 / clipToWorldVector.w );
-				clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse ); // increase the sphere bounds by the worst case line screen space width
+			}
 
-				var sphereMargin = Math.abs( ssMaxWidth / clipToWorldVector.w ) * 0.5;
-				sphere.radius += sphereMargin;
+			_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
 
-				if ( raycaster.ray.intersectsSphere( sphere ) === false ) {
+			const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( ray.origin ) ); // get the w component to scale the world space line width
 
-					return;
+			_clipToWorldVector.set( 0, 0, - distanceToSphere, 1.0 ).applyMatrix4( camera.projectionMatrix );
 
-				} //
-				// check if we intersect the box bounds
+			_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
 
+			_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse ); // increase the sphere bounds by the worst case line screen space width
 
-				if ( geometry.boundingBox === null ) {
 
-					geometry.computeBoundingBox();
+			const sphereMargin = Math.abs( ssMaxWidth / _clipToWorldVector.w ) * 0.5;
+			_sphere.radius += sphereMargin;
 
-				}
+			if ( raycaster.ray.intersectsSphere( _sphere ) === false ) {
+
+				return;
+
+			} //
+			// check if we intersect the box bounds
+
+
+			if ( geometry.boundingBox === null ) {
+
+				geometry.computeBoundingBox();
+
+			}
+
+			_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
+
+			const distanceToBox = Math.max( camera.near, _box.distanceToPoint( ray.origin ) ); // get the w component to scale the world space line width
+
+			_clipToWorldVector.set( 0, 0, - distanceToBox, 1.0 ).applyMatrix4( camera.projectionMatrix );
+
+			_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
 
-				box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
-				var distanceToBox = Math.max( camera.near, box.distanceToPoint( ray.origin ) ); // get the w component to scale the world space line width
+			_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse ); // increase the sphere bounds by the worst case line screen space width
 
-				clipToWorldVector.set( 0, 0, - distanceToBox, 1.0 ).applyMatrix4( camera.projectionMatrix );
-				clipToWorldVector.multiplyScalar( 1.0 / clipToWorldVector.w );
-				clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse ); // increase the sphere bounds by the worst case line screen space width
 
-				var boxMargin = Math.abs( ssMaxWidth / clipToWorldVector.w ) * 0.5;
-				box.max.x += boxMargin;
-				box.max.y += boxMargin;
-				box.max.z += boxMargin;
-				box.min.x -= boxMargin;
-				box.min.y -= boxMargin;
-				box.min.z -= boxMargin;
+			const boxMargin = Math.abs( ssMaxWidth / _clipToWorldVector.w ) * 0.5;
+			_box.max.x += boxMargin;
+			_box.max.y += boxMargin;
+			_box.max.z += boxMargin;
+			_box.min.x -= boxMargin;
+			_box.min.y -= boxMargin;
+			_box.min.z -= boxMargin;
 
-				if ( raycaster.ray.intersectsBox( box ) === false ) {
+			if ( raycaster.ray.intersectsBox( _box ) === false ) {
 
-					return;
+				return;
 
-				} //
-				// 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.
+			} //
+			// 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 ); // ndc space [ - 1.0, 1.0 ]
+			ray.at( 1, _ssOrigin ); // ndc space [ - 1.0, 1.0 ]
 
-				ssOrigin.w = 1;
-				ssOrigin.applyMatrix4( camera.matrixWorldInverse );
-				ssOrigin.applyMatrix4( projectionMatrix );
-				ssOrigin.multiplyScalar( 1 / ssOrigin.w ); // screen space
+			_ssOrigin.w = 1;
 
-				ssOrigin.x *= resolution.x / 2;
-				ssOrigin.y *= resolution.y / 2;
-				ssOrigin.z = 0;
-				ssOrigin3.copy( ssOrigin );
-				mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
+			_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
 
-				for ( var i = 0, l = instanceStart.count; i < l; i ++ ) {
+			_ssOrigin.applyMatrix4( projectionMatrix );
 
-					start.fromBufferAttribute( instanceStart, i );
-					end.fromBufferAttribute( instanceEnd, i );
-					start.w = 1;
-					end.w = 1; // camera space
+			_ssOrigin.multiplyScalar( 1 / _ssOrigin.w ); // screen space
 
-					start.applyMatrix4( mvMatrix );
-					end.applyMatrix4( mvMatrix ); // skip the segment if it's entirely behind the camera
 
-					var isBehindCameraNear = start.z > near && end.z > near;
+			_ssOrigin.x *= resolution.x / 2;
+			_ssOrigin.y *= resolution.y / 2;
+			_ssOrigin.z = 0;
 
-					if ( isBehindCameraNear ) {
+			_ssOrigin3.copy( _ssOrigin );
 
-						continue;
+			_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
 
-					} // trim the segment if it extends behind camera near
+			for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
 
+				_start4.fromBufferAttribute( instanceStart, i );
 
-					if ( start.z > near ) {
+				_end4.fromBufferAttribute( instanceEnd, i );
 
-						const deltaDist = start.z - end.z;
-						const t = ( start.z - near ) / deltaDist;
-						start.lerp( end, t );
+				_start.w = 1;
+				_end.w = 1; // camera space
 
-					} else if ( end.z > near ) {
+				_start4.applyMatrix4( _mvMatrix );
 
-						const deltaDist = end.z - start.z;
-						const t = ( end.z - near ) / deltaDist;
-						end.lerp( start, t );
+				_end4.applyMatrix4( _mvMatrix ); // skip the segment if it's entirely behind the camera
 
-					} // clip space
 
+				var isBehindCameraNear = _start4.z > near && _end4.z > near;
 
-					start.applyMatrix4( projectionMatrix );
-					end.applyMatrix4( projectionMatrix ); // ndc space [ - 1.0, 1.0 ]
+				if ( isBehindCameraNear ) {
 
-					start.multiplyScalar( 1 / start.w );
-					end.multiplyScalar( 1 / end.w ); // screen space
+					continue;
 
-					start.x *= resolution.x / 2;
-					start.y *= resolution.y / 2;
-					end.x *= resolution.x / 2;
-					end.y *= resolution.y / 2; // create 2d segment
+				} // trim the segment if it extends behind camera near
 
-					line.start.copy( start );
-					line.start.z = 0;
-					line.end.copy( end );
-					line.end.z = 0; // get closest point on ray to segment
 
-					var param = line.closestPointToPointParameter( ssOrigin3, true );
-					line.at( param, closestPoint ); // check if the intersection point is within clip space
+				if ( _start4.z > near ) {
 
-					var zPos = THREE.MathUtils.lerp( start.z, end.z, param );
-					var isInClipSpace = zPos >= - 1 && zPos <= 1;
-					var isInside = ssOrigin3.distanceTo( closestPoint ) < lineWidth * 0.5;
+					const deltaDist = _start4.z - _end4.z;
+					const t = ( _start4.z - near ) / deltaDist;
 
-					if ( isInClipSpace && isInside ) {
+					_start4.lerp( _end4, t );
 
-						line.start.fromBufferAttribute( instanceStart, i );
-						line.end.fromBufferAttribute( instanceEnd, i );
-						line.start.applyMatrix4( matrixWorld );
-						line.end.applyMatrix4( matrixWorld );
-						var pointOnLine = new THREE.Vector3();
-						var point = new THREE.Vector3();
-						ray.distanceSqToSegment( line.start, line.end, point, pointOnLine );
-						intersects.push( {
-							point: point,
-							pointOnLine: pointOnLine,
-							distance: ray.origin.distanceTo( point ),
-							object: this,
-							face: null,
-							faceIndex: i,
-							uv: null,
-							uv2: null
-						} );
+				} else if ( _end4.z > near ) {
 
-					}
+					const deltaDist = _end4.z - _start4.z;
+					const t = ( _end4.z - near ) / deltaDist;
+
+					_end4.lerp( _start4, t );
+
+				} // clip space
+
+
+				_start4.applyMatrix4( projectionMatrix );
+
+				_end4.applyMatrix4( projectionMatrix ); // ndc space [ - 1.0, 1.0 ]
+
+
+				_start4.multiplyScalar( 1 / _start4.w );
+
+				_end4.multiplyScalar( 1 / _end4.w ); // 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
+
+				_line.start.copy( _start4 );
+
+				_line.start.z = 0;
+
+				_line.end.copy( _end4 );
+
+				_line.end.z = 0; // get closest point on ray to segment
+
+				const param = _line.closestPointToPointParameter( _ssOrigin3, true );
+
+				_line.at( param, _closestPoint ); // 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,
+						distance: ray.origin.distanceTo( point ),
+						object: this,
+						face: null,
+						faceIndex: i,
+						uv: null,
+						uv2: null
+					} );
 
 				}
 
-			};
+			}
+
+		}
+
+	}
 
-		}()
-	} );
+	LineSegments2.prototype.LineSegments2 = true;
 
 	THREE.LineSegments2 = LineSegments2;
 

+ 91 - 80
examples/js/lines/LineSegmentsGeometry.js

@@ -1,25 +1,28 @@
 ( function () {
 
-	var LineSegmentsGeometry = function () {
+	const _box = new THREE.Box3();
 
-		THREE.InstancedBufferGeometry.call( this );
-		this.type = 'LineSegmentsGeometry';
-		var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
-		var uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
-		var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
-		this.setIndex( index );
-		this.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
-		this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
+	const _vector = new THREE.Vector3();
 
-	};
+	class LineSegmentsGeometry extends THREE.InstancedBufferGeometry {
 
-	LineSegmentsGeometry.prototype = Object.assign( Object.create( THREE.InstancedBufferGeometry.prototype ), {
-		constructor: LineSegmentsGeometry,
-		isLineSegmentsGeometry: true,
-		applyMatrix4: function ( matrix ) {
+		constructor() {
 
-			var start = this.attributes.instanceStart;
-			var end = this.attributes.instanceEnd;
+			super();
+			this.type = 'LineSegmentsGeometry';
+			const positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
+			const uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
+			const index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
+			this.setIndex( index );
+			this.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
+			this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
+
+		}
+
+		applyMatrix4( matrix ) {
+
+			const start = this.attributes.instanceStart;
+			const end = this.attributes.instanceEnd;
 
 			if ( start !== undefined ) {
 
@@ -43,10 +46,11 @@
 
 			return this;
 
-		},
-		setPositions: function ( array ) {
+		}
+
+		setPositions( array ) {
 
-			var lineSegments;
+			let lineSegments;
 
 			if ( array instanceof Float32Array ) {
 
@@ -58,7 +62,7 @@
 
 			}
 
-			var instanceBuffer = new THREE.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
+			const instanceBuffer = new THREE.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
 
 			this.setAttribute( 'instanceStart', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
 
@@ -69,10 +73,11 @@
 			this.computeBoundingSphere();
 			return this;
 
-		},
-		setColors: function ( array ) {
+		}
+
+		setColors( array ) {
 
-			var colors;
+			let colors;
 
 			if ( array instanceof Float32Array ) {
 
@@ -84,7 +89,7 @@
 
 			}
 
-			var instanceColorBuffer = new THREE.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
+			const instanceColorBuffer = new THREE.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
 
 			this.setAttribute( 'instanceColorStart', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
 
@@ -92,29 +97,33 @@
 
 			return this;
 
-		},
-		fromWireframeGeometry: function ( geometry ) {
+		}
+
+		fromWireframeGeometry( geometry ) {
 
 			this.setPositions( geometry.attributes.position.array );
 			return this;
 
-		},
-		fromEdgesGeometry: function ( geometry ) {
+		}
+
+		fromEdgesGeometry( geometry ) {
 
 			this.setPositions( geometry.attributes.position.array );
 			return this;
 
-		},
-		fromMesh: function ( mesh ) {
+		}
+
+		fromMesh( mesh ) {
 
 			this.fromWireframeGeometry( new THREE.WireframeGeometry( mesh.geometry ) ); // set colors, maybe
 
 			return this;
 
-		},
-		fromLineSegments: function ( lineSegments ) {
+		}
 
-			var geometry = lineSegments.geometry;
+		romLineSegments( lineSegments ) {
+
+			const geometry = lineSegments.geometry;
 
 			if ( geometry.isGeometry ) {
 
@@ -130,89 +139,91 @@
 
 			return this;
 
-		},
-		computeBoundingBox: function () {
+		}
 
-			var box = new THREE.Box3();
-			return function computeBoundingBox() {
+		computeBoundingBox() {
 
-				if ( this.boundingBox === null ) {
+			if ( this.boundingBox === null ) {
 
-					this.boundingBox = new THREE.Box3();
+				this.boundingBox = new THREE.Box3();
 
-				}
+			}
 
-				var start = this.attributes.instanceStart;
-				var end = this.attributes.instanceEnd;
+			const start = this.attributes.instanceStart;
+			const end = this.attributes.instanceEnd;
 
-				if ( start !== undefined && end !== undefined ) {
+			if ( start !== undefined && end !== undefined ) {
 
-					this.boundingBox.setFromBufferAttribute( start );
-					box.setFromBufferAttribute( end );
-					this.boundingBox.union( box );
+				this.boundingBox.setFromBufferAttribute( start );
 
-				}
+				_box.setFromBufferAttribute( end );
 
-			};
+				this.boundingBox.union( _box );
 
-		}(),
-		computeBoundingSphere: function () {
+			}
 
-			var vector = new THREE.Vector3();
-			return function computeBoundingSphere() {
+		}
 
-				if ( this.boundingSphere === null ) {
+		computeBoundingSphere() {
 
-					this.boundingSphere = new THREE.Sphere();
+			if ( this.boundingSphere === null ) {
 
-				}
+				this.boundingSphere = new THREE.Sphere();
+
+			}
 
-				if ( this.boundingBox === null ) {
+			if ( this.boundingBox === null ) {
 
-					this.computeBoundingBox();
+				this.computeBoundingBox();
 
-				}
+			}
 
-				var start = this.attributes.instanceStart;
-				var end = this.attributes.instanceEnd;
+			const start = this.attributes.instanceStart;
+			const end = this.attributes.instanceEnd;
 
-				if ( start !== undefined && end !== undefined ) {
+			if ( start !== undefined && end !== undefined ) {
 
-					var center = this.boundingSphere.center;
-					this.boundingBox.getCenter( center );
-					var maxRadiusSq = 0;
+				const center = this.boundingSphere.center;
+				this.boundingBox.getCenter( center );
+				let maxRadiusSq = 0;
 
-					for ( var i = 0, il = start.count; i < il; i ++ ) {
+				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 ) );
+					_vector.fromBufferAttribute( start, i );
 
-					}
+					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
 
-					this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
+					_vector.fromBufferAttribute( end, i );
 
-					if ( isNaN( this.boundingSphere.radius ) ) {
+					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
 
-						console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
+				}
 
-					}
+				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 );
 
 				}
 
-			};
+			}
 
-		}(),
-		toJSON: function () { // todo
-		},
-		applyMatrix: function ( matrix ) {
+		}
+
+		toJSON() { // todo
+		}
+
+		applyMatrix( matrix ) {
 
 			console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
 			return this.applyMatrix4( matrix );
 
 		}
-	} );
+
+	}
+
+	LineSegmentsGeometry.prototype.isLineSegmentsGeometry = true;
 
 	THREE.LineSegmentsGeometry = LineSegmentsGeometry;
 

+ 32 - 32
examples/js/lines/Wireframe.js

@@ -1,52 +1,52 @@
 ( function () {
 
-	var Wireframe = function ( geometry, material ) {
+	const _start = new THREE.Vector3();
 
-		THREE.Mesh.call( this );
-		this.type = 'Wireframe';
-		this.geometry = geometry !== undefined ? geometry : new THREE.LineSegmentsGeometry();
-		this.material = material !== undefined ? material : new THREE.LineMaterial( {
+	const _end = new THREE.Vector3();
+
+	class Wireframe extends THREE.Mesh {
+
+		constructor( geometry = new THREE.LineSegmentsGeometry(), material = new THREE.LineMaterial( {
 			color: Math.random() * 0xffffff
-		} );
+		} ) ) {
+
+			super( geometry, material );
+			this.type = 'Wireframe';
+
+		} // for backwards-compatability, but could be a method of THREE.LineSegmentsGeometry...
+
+
+		computeLineDistances() {
 
-	};
+			const geometry = this.geometry;
+			const instanceStart = geometry.attributes.instanceStart;
+			const instanceEnd = geometry.attributes.instanceEnd;
+			const lineDistances = new Float32Array( 2 * instanceStart.count );
 
-	Wireframe.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
-		constructor: Wireframe,
-		isWireframe: true,
-		computeLineDistances: function () {
+			for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 
-			// for backwards-compatability, but could be a method of THREE.LineSegmentsGeometry...
-			var start = new THREE.Vector3();
-			var end = new THREE.Vector3();
-			return function computeLineDistances() {
+				_start.fromBufferAttribute( instanceStart, i );
 
-				var geometry = this.geometry;
-				var instanceStart = geometry.attributes.instanceStart;
-				var instanceEnd = geometry.attributes.instanceEnd;
-				var lineDistances = new Float32Array( 2 * instanceStart.count );
+				_end.fromBufferAttribute( instanceEnd, i );
 
-				for ( var i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
+				lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
+				lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 
-					start.fromBufferAttribute( instanceStart, i );
-					end.fromBufferAttribute( instanceEnd, i );
-					lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
-					lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
+			}
 
-				}
+			const instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
-				var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
+			geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
 
-				geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
+			geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
-				geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
+			return this;
 
-				return this;
+		}
 
-			};
+	}
 
-		}()
-	} );
+	Wireframe.prototype.isWireframe = true;
 
 	THREE.Wireframe = Wireframe;
 

+ 10 - 9
examples/js/lines/WireframeGeometry2.js

@@ -1,17 +1,18 @@
 ( function () {
 
-	var WireframeGeometry2 = function ( geometry ) {
+	class WireframeGeometry2 extends THREE.LineSegmentsGeometry {
 
-		THREE.LineSegmentsGeometry.call( this );
-		this.type = 'WireframeGeometry2';
-		this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) ); // set colors, maybe
+		constructor( geometry ) {
 
-	};
+			super();
+			this.type = 'WireframeGeometry2';
+			this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) ); // set colors, maybe
 
-	WireframeGeometry2.prototype = Object.assign( Object.create( THREE.LineSegmentsGeometry.prototype ), {
-		constructor: WireframeGeometry2,
-		isWireframeGeometry2: true
-	} );
+		}
+
+	}
+
+	WireframeGeometry2.prototype.isWireframeGeometry2 = true;
 
 	THREE.WireframeGeometry2 = WireframeGeometry2;
 

+ 7 - 12
examples/jsm/lines/Line2.js

@@ -2,23 +2,18 @@ import { LineSegments2 } from '../lines/LineSegments2.js';
 import { LineGeometry } from '../lines/LineGeometry.js';
 import { LineMaterial } from '../lines/LineMaterial.js';
 
-var Line2 = function ( geometry, material ) {
+class Line2 extends LineSegments2 {
 
-	if ( geometry === undefined ) geometry = new LineGeometry();
-	if ( material === undefined ) material = new LineMaterial( { color: Math.random() * 0xffffff } );
+	constructor( geometry = new LineGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
 
-	LineSegments2.call( this, geometry, material );
+		super( geometry, material );
 
-	this.type = 'Line2';
+		this.type = 'Line2';
 
-};
+	}
 
-Line2.prototype = Object.assign( Object.create( LineSegments2.prototype ), {
+}
 
-	constructor: Line2,
-
-	isLine2: true
-
-} );
+Line2.prototype.isLine2 = true;
 
 export { Line2 };

+ 17 - 20
examples/jsm/lines/LineGeometry.js

@@ -1,20 +1,15 @@
 import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
 
-var LineGeometry = function () {
+class LineGeometry extends LineSegmentsGeometry {
 
-	LineSegmentsGeometry.call( this );
+	constructor() {
 
-	this.type = 'LineGeometry';
+		super();
+		this.type = 'LineGeometry';
 
-};
-
-LineGeometry.prototype = Object.assign( Object.create( LineSegmentsGeometry.prototype ), {
-
-	constructor: LineGeometry,
-
-	isLineGeometry: true,
+	}
 
-	setPositions: function ( array ) {
+	setPositions( array ) {
 
 		// converts [ x1, y1, z1,  x2, y2, z2, ... ] to pairs format
 
@@ -33,13 +28,13 @@ LineGeometry.prototype = Object.assign( Object.create( LineSegmentsGeometry.prot
 
 		}
 
-		LineSegmentsGeometry.prototype.setPositions.call( this, points );
+		super.setPositions( points );
 
 		return this;
 
-	},
+	}
 
-	setColors: function ( array ) {
+	setColors( array ) {
 
 		// converts [ r1, g1, b1,  r2, g2, b2, ... ] to pairs format
 
@@ -58,13 +53,13 @@ LineGeometry.prototype = Object.assign( Object.create( LineSegmentsGeometry.prot
 
 		}
 
-		LineSegmentsGeometry.prototype.setColors.call( this, colors );
+		super.setColors( colors );
 
 		return this;
 
-	},
+	}
 
-	fromLine: function ( line ) {
+	fromLine( line ) {
 
 		var geometry = line.geometry;
 
@@ -83,9 +78,9 @@ LineGeometry.prototype = Object.assign( Object.create( LineSegmentsGeometry.prot
 
 		return this;
 
-	},
+	}
 
-	copy: function ( /* source */ ) {
+	copy( /* source */ ) {
 
 		// todo
 
@@ -93,6 +88,8 @@ LineGeometry.prototype = Object.assign( Object.create( LineSegmentsGeometry.prot
 
 	}
 
-} );
+}
+
+LineGeometry.prototype.isLineGeometry = true;
 
 export { LineGeometry };

+ 100 - 99
examples/jsm/lines/LineMaterial.js

@@ -267,211 +267,212 @@ ShaderLib[ 'line' ] = {
 		`
 };
 
-var LineMaterial = function ( parameters ) {
+class LineMaterial extends ShaderMaterial {
 
-	ShaderMaterial.call( this, {
+	constructor( parameters ) {
 
-		type: 'LineMaterial',
+		super( {
 
-		uniforms: UniformsUtils.clone( ShaderLib[ 'line' ].uniforms ),
+			type: 'LineMaterial',
 
-		vertexShader: ShaderLib[ 'line' ].vertexShader,
-		fragmentShader: ShaderLib[ 'line' ].fragmentShader,
+			uniforms: UniformsUtils.clone( ShaderLib[ 'line' ].uniforms ),
 
-		clipping: true // required for clipping support
+			vertexShader: ShaderLib[ 'line' ].vertexShader,
+			fragmentShader: ShaderLib[ 'line' ].fragmentShader,
 
-	} );
+			clipping: true // required for clipping support
 
-	this.dashed = false;
+		} );
 
-	Object.defineProperties( this, {
+		this.dashed = false;
 
-		color: {
+		Object.defineProperties( this, {
 
-			enumerable: true,
+			color: {
 
-			get: function () {
+				enumerable: true,
 
-				return this.uniforms.diffuse.value;
+				get: function () {
+
+					return this.uniforms.diffuse.value;
+
+				},
+
+				set: function ( value ) {
+
+					this.uniforms.diffuse.value = value;
+
+				}
 
 			},
 
-			set: function ( value ) {
+			linewidth: {
 
-				this.uniforms.diffuse.value = value;
+				enumerable: true,
 
-			}
+				get: function () {
 
-		},
+					return this.uniforms.linewidth.value;
 
-		linewidth: {
+				},
 
-			enumerable: true,
+				set: function ( value ) {
 
-			get: function () {
+					this.uniforms.linewidth.value = value;
 
-				return this.uniforms.linewidth.value;
+				}
 
 			},
 
-			set: function ( value ) {
+			dashScale: {
 
-				this.uniforms.linewidth.value = value;
+				enumerable: true,
 
-			}
+				get: function () {
 
-		},
+					return this.uniforms.dashScale.value;
 
-		dashScale: {
+				},
 
-			enumerable: true,
+				set: function ( value ) {
 
-			get: function () {
+					this.uniforms.dashScale.value = value;
 
-				return this.uniforms.dashScale.value;
+				}
 
 			},
 
-			set: function ( value ) {
+			dashSize: {
 
-				this.uniforms.dashScale.value = value;
+				enumerable: true,
 
-			}
+				get: function () {
 
-		},
+					return this.uniforms.dashSize.value;
 
-		dashSize: {
+				},
 
-			enumerable: true,
+				set: function ( value ) {
 
-			get: function () {
+					this.uniforms.dashSize.value = value;
 
-				return this.uniforms.dashSize.value;
+				}
 
 			},
 
-			set: function ( value ) {
+			dashOffset: {
 
-				this.uniforms.dashSize.value = value;
+				enumerable: true,
 
-			}
+				get: function () {
 
-		},
+					return this.uniforms.dashOffset.value;
 
-		dashOffset: {
+				},
 
-			enumerable: true,
+				set: function ( value ) {
 
-			get: function () {
+					this.uniforms.dashOffset.value = value;
 
-				return this.uniforms.dashOffset.value;
+				}
 
 			},
 
-			set: function ( value ) {
+			gapSize: {
 
-				this.uniforms.dashOffset.value = value;
+				enumerable: true,
 
-			}
+				get: function () {
 
-		},
+					return this.uniforms.gapSize.value;
 
-		gapSize: {
+				},
 
-			enumerable: true,
+				set: function ( value ) {
 
-			get: function () {
+					this.uniforms.gapSize.value = value;
 
-				return this.uniforms.gapSize.value;
+				}
 
 			},
 
-			set: function ( value ) {
+			opacity: {
 
-				this.uniforms.gapSize.value = value;
+				enumerable: true,
 
-			}
+				get: function () {
 
-		},
+					return this.uniforms.opacity.value;
 
-		opacity: {
+				},
 
-			enumerable: true,
+				set: function ( value ) {
 
-			get: function () {
+					this.uniforms.opacity.value = value;
 
-				return this.uniforms.opacity.value;
+				}
 
 			},
 
-			set: function ( value ) {
+			resolution: {
 
-				this.uniforms.opacity.value = value;
+				enumerable: true,
 
-			}
+				get: function () {
 
-		},
+					return this.uniforms.resolution.value;
 
-		resolution: {
+				},
 
-			enumerable: true,
+				set: function ( value ) {
 
-			get: function () {
+					this.uniforms.resolution.value.copy( value );
 
-				return this.uniforms.resolution.value;
+				}
 
 			},
 
-			set: function ( value ) {
-
-				this.uniforms.resolution.value.copy( value );
-
-			}
-
-		},
+			alphaToCoverage: {
 
-		alphaToCoverage: {
+				enumerable: true,
 
-			enumerable: true,
+				get: function () {
 
-			get: function () {
+					return Boolean( 'ALPHA_TO_COVERAGE' in this.defines );
 
-				return Boolean( 'ALPHA_TO_COVERAGE' in this.defines );
+				},
 
-			},
+				set: function ( value ) {
 
-			set: function ( value ) {
+					if ( Boolean( value ) !== Boolean( 'ALPHA_TO_COVERAGE' in this.defines ) ) {
 
-				if ( Boolean( value ) !== Boolean( 'ALPHA_TO_COVERAGE' in this.defines ) ) {
+						this.needsUpdate = true;
 
-					this.needsUpdate = true;
+					}
 
-				}
+					if ( value ) {
 
-				if ( value ) {
+						this.defines.ALPHA_TO_COVERAGE = '';
+						this.extensions.derivatives = true;
 
-					this.defines.ALPHA_TO_COVERAGE = '';
-					this.extensions.derivatives = true;
+					} else {
 
-				} else {
+						delete this.defines.ALPHA_TO_COVERAGE;
+						this.extensions.derivatives = false;
 
-					delete this.defines.ALPHA_TO_COVERAGE;
-					this.extensions.derivatives = false;
+					}
 
 				}
 
 			}
 
-		}
-
-	} );
+		} );
 
-	this.setValues( parameters );
+		this.setValues( parameters );
 
-};
+	}
 
-LineMaterial.prototype = Object.create( ShaderMaterial.prototype );
-LineMaterial.prototype.constructor = LineMaterial;
+}
 
 LineMaterial.prototype.isLineMaterial = true;
 

+ 178 - 189
examples/jsm/lines/LineSegments2.js

@@ -13,285 +13,274 @@ import {
 import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
 import { LineMaterial } from '../lines/LineMaterial.js';
 
-var LineSegments2 = function ( geometry, material ) {
+const _start = new Vector3();
+const _end = new Vector3();
 
-	if ( geometry === undefined ) geometry = new LineSegmentsGeometry();
-	if ( material === undefined ) material = new LineMaterial( { color: Math.random() * 0xffffff } );
+const _start4 = new Vector4();
+const _end4 = new Vector4();
 
-	Mesh.call( this, geometry, material );
+const _ssOrigin = new Vector4();
+const _ssOrigin3 = new Vector3();
+const _mvMatrix = new Matrix4();
+const _line = new Line3();
+const _closestPoint = new Vector3();
 
-	this.type = 'LineSegments2';
+const _box = new Box3();
+const _sphere = new Sphere();
+const _clipToWorldVector = new Vector4();
 
-};
+class LineSegments2 extends Mesh {
 
-LineSegments2.prototype = Object.assign( Object.create( Mesh.prototype ), {
+	constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
 
-	constructor: LineSegments2,
+		super( geometry, material );
 
-	isLineSegments2: true,
+		this.type = 'LineSegments2';
 
-	computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
+	}
 
-		var start = new Vector3();
-		var end = new Vector3();
+	// for backwards-compatability, but could be a method of LineSegmentsGeometry...
 
-		return function computeLineDistances() {
+	computeLineDistances() {
 
-			var geometry = this.geometry;
+		const geometry = this.geometry;
 
-			var instanceStart = geometry.attributes.instanceStart;
-			var instanceEnd = geometry.attributes.instanceEnd;
-			var lineDistances = new Float32Array( 2 * instanceStart.count );
+		const instanceStart = geometry.attributes.instanceStart;
+		const instanceEnd = geometry.attributes.instanceEnd;
+		const lineDistances = new Float32Array( 2 * instanceStart.count );
 
-			for ( var i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
+		for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 
-				start.fromBufferAttribute( instanceStart, i );
-				end.fromBufferAttribute( instanceEnd, i );
+			_start.fromBufferAttribute( instanceStart, i );
+			_end.fromBufferAttribute( instanceEnd, i );
 
-				lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
-				lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
+			lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
+			lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 
-			}
-
-			var instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
+		}
 
-			geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
-			geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
+		const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
-			return this;
+		geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
+		geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
-		};
+		return this;
 
-	}() ),
+	}
 
-	raycast: ( function () {
+	raycast( raycaster, intersects ) {
 
-		var start = new Vector4();
-		var end = new Vector4();
+		if ( raycaster.camera === null ) {
 
-		var ssOrigin = new Vector4();
-		var ssOrigin3 = new Vector3();
-		var mvMatrix = new Matrix4();
-		var line = new Line3();
-		var closestPoint = new Vector3();
+			console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' );
 
-		var box = new Box3();
-		var sphere = new Sphere();
-		var clipToWorldVector = new Vector4();
+		}
 
-		return function raycast( raycaster, intersects ) {
+		const threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
 
-			if ( raycaster.camera === null ) {
+		const ray = raycaster.ray;
+		const camera = raycaster.camera;
+		const projectionMatrix = camera.projectionMatrix;
 
-				console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' );
+		const matrixWorld = this.matrixWorld;
+		const geometry = this.geometry;
+		const material = this.material;
+		const resolution = material.resolution;
+		const lineWidth = material.linewidth + threshold;
 
-			}
+		const instanceStart = geometry.attributes.instanceStart;
+		const instanceEnd = geometry.attributes.instanceEnd;
 
-			var threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;
+		// camera forward is negative
+		const near = - camera.near;
 
-			var ray = raycaster.ray;
-			var camera = raycaster.camera;
-			var projectionMatrix = camera.projectionMatrix;
+		// clip space is [ - 1, 1 ] so multiply by two to get the full
+		// width in clip space
+		const ssMaxWidth = 2.0 * Math.max( lineWidth / resolution.width, lineWidth / resolution.height );
 
-			var matrixWorld = this.matrixWorld;
-			var geometry = this.geometry;
-			var material = this.material;
-			var resolution = material.resolution;
-			var lineWidth = material.linewidth + threshold;
+		//
 
-			var instanceStart = geometry.attributes.instanceStart;
-			var instanceEnd = geometry.attributes.instanceEnd;
+		// check if we intersect the sphere bounds
+		if ( geometry.boundingSphere === null ) {
 
-			// camera forward is negative
-			var near = - camera.near;
+			geometry.computeBoundingSphere();
 
-			// clip space is [ - 1, 1 ] so multiply by two to get the full
-			// width in clip space
-			var ssMaxWidth = 2.0 * Math.max( lineWidth / resolution.width, lineWidth / resolution.height );
+		}
 
-			//
+		_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
+		const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( ray.origin ) );
 
-			// check if we intersect the sphere bounds
-			if ( geometry.boundingSphere === null ) {
+		// get the w component to scale the world space line width
+		_clipToWorldVector.set( 0, 0, - distanceToSphere, 1.0 ).applyMatrix4( camera.projectionMatrix );
+		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
+		_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
 
-				geometry.computeBoundingSphere();
-
-			}
+		// increase the sphere bounds by the worst case line screen space width
+		const sphereMargin = Math.abs( ssMaxWidth / _clipToWorldVector.w ) * 0.5;
+		_sphere.radius += sphereMargin;
 
-			sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
-			var distanceToSphere = Math.max( camera.near, sphere.distanceToPoint( ray.origin ) );
+		if ( raycaster.ray.intersectsSphere( _sphere ) === false ) {
 
-			// get the w component to scale the world space line width
-			clipToWorldVector.set( 0, 0, - distanceToSphere, 1.0 ).applyMatrix4( camera.projectionMatrix );
-			clipToWorldVector.multiplyScalar( 1.0 / clipToWorldVector.w );
-			clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
+			return;
 
-			// increase the sphere bounds by the worst case line screen space width
-			var sphereMargin = Math.abs( ssMaxWidth / clipToWorldVector.w ) * 0.5;
-			sphere.radius += sphereMargin;
+		}
 
-			if ( raycaster.ray.intersectsSphere( sphere ) === false ) {
+		//
 
-				return;
+		// check if we intersect the box bounds
+		if ( geometry.boundingBox === null ) {
 
-			}
+			geometry.computeBoundingBox();
 
-			//
+		}
 
-			// check if we intersect the box bounds
-			if ( geometry.boundingBox === null ) {
+		_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
+		const distanceToBox = Math.max( camera.near, _box.distanceToPoint( ray.origin ) );
 
-				geometry.computeBoundingBox();
+		// get the w component to scale the world space line width
+		_clipToWorldVector.set( 0, 0, - distanceToBox, 1.0 ).applyMatrix4( camera.projectionMatrix );
+		_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
+		_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
 
-			}
+		// increase the sphere bounds by the worst case line screen space width
+		const boxMargin = Math.abs( ssMaxWidth / _clipToWorldVector.w ) * 0.5;
+		_box.max.x += boxMargin;
+		_box.max.y += boxMargin;
+		_box.max.z += boxMargin;
+		_box.min.x -= boxMargin;
+		_box.min.y -= boxMargin;
+		_box.min.z -= boxMargin;
 
-			box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
-			var distanceToBox = Math.max( camera.near, box.distanceToPoint( ray.origin ) );
+		if ( raycaster.ray.intersectsBox( _box ) === false ) {
 
-			// get the w component to scale the world space line width
-			clipToWorldVector.set( 0, 0, - distanceToBox, 1.0 ).applyMatrix4( camera.projectionMatrix );
-			clipToWorldVector.multiplyScalar( 1.0 / clipToWorldVector.w );
-			clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
+			return;
 
-			// increase the sphere bounds by the worst case line screen space width
-			var boxMargin = Math.abs( ssMaxWidth / clipToWorldVector.w ) * 0.5;
-			box.max.x += boxMargin;
-			box.max.y += boxMargin;
-			box.max.z += boxMargin;
-			box.min.x -= boxMargin;
-			box.min.y -= boxMargin;
-			box.min.z -= boxMargin;
+		}
 
-			if ( raycaster.ray.intersectsBox( box ) === false ) {
+		//
 
-				return;
+		// 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 );
 
-			}
+		// ndc space [ - 1.0, 1.0 ]
+		_ssOrigin.w = 1;
+		_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
+		_ssOrigin.applyMatrix4( projectionMatrix );
+		_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );
 
-			//
+		// screen space
+		_ssOrigin.x *= resolution.x / 2;
+		_ssOrigin.y *= resolution.y / 2;
+		_ssOrigin.z = 0;
 
-			// 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 );
+		_ssOrigin3.copy( _ssOrigin );
 
-			// ndc space [ - 1.0, 1.0 ]
-			ssOrigin.w = 1;
-			ssOrigin.applyMatrix4( camera.matrixWorldInverse );
-			ssOrigin.applyMatrix4( projectionMatrix );
-			ssOrigin.multiplyScalar( 1 / ssOrigin.w );
+		_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
 
-			// screen space
-			ssOrigin.x *= resolution.x / 2;
-			ssOrigin.y *= resolution.y / 2;
-			ssOrigin.z = 0;
+		for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
 
-			ssOrigin3.copy( ssOrigin );
+			_start4.fromBufferAttribute( instanceStart, i );
+			_end4.fromBufferAttribute( instanceEnd, i );
 
-			mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
+			_start.w = 1;
+			_end.w = 1;
 
-			for ( var i = 0, l = instanceStart.count; i < l; i ++ ) {
+			// camera space
+			_start4.applyMatrix4( _mvMatrix );
+			_end4.applyMatrix4( _mvMatrix );
 
-				start.fromBufferAttribute( instanceStart, i );
-				end.fromBufferAttribute( instanceEnd, i );
+			// skip the segment if it's entirely behind the camera
+			var isBehindCameraNear = _start4.z > near && _end4.z > near;
+			if ( isBehindCameraNear ) {
 
-				start.w = 1;
-				end.w = 1;
+				continue;
 
-				// camera space
-				start.applyMatrix4( mvMatrix );
-				end.applyMatrix4( mvMatrix );
-
-				// skip the segment if it's entirely behind the camera
-				var isBehindCameraNear = start.z > near && end.z > near;
-				if ( isBehindCameraNear ) {
-
-					continue;
-
-				}
-
-				// trim the segment if it extends behind camera near
-				if ( start.z > near ) {
+			}
 
-					const deltaDist = start.z - end.z;
-					const t = ( start.z - near ) / deltaDist;
-					start.lerp( end, t );
+			// trim the segment if it extends behind camera near
+			if ( _start4.z > near ) {
 
-				} else if ( end.z > near ) {
+				const deltaDist = _start4.z - _end4.z;
+				const t = ( _start4.z - near ) / deltaDist;
+				_start4.lerp( _end4, t );
 
-					const deltaDist = end.z - start.z;
-					const t = ( end.z - near ) / deltaDist;
-					end.lerp( start, t );
+			} else if ( _end4.z > near ) {
 
-				}
+				const deltaDist = _end4.z - _start4.z;
+				const t = ( _end4.z - near ) / deltaDist;
+				_end4.lerp( _start4, t );
 
-				// clip space
-				start.applyMatrix4( projectionMatrix );
-				end.applyMatrix4( projectionMatrix );
+			}
 
-				// ndc space [ - 1.0, 1.0 ]
-				start.multiplyScalar( 1 / start.w );
-				end.multiplyScalar( 1 / end.w );
+			// clip space
+			_start4.applyMatrix4( projectionMatrix );
+			_end4.applyMatrix4( projectionMatrix );
 
-				// screen space
-				start.x *= resolution.x / 2;
-				start.y *= resolution.y / 2;
+			// ndc space [ - 1.0, 1.0 ]
+			_start4.multiplyScalar( 1 / _start4.w );
+			_end4.multiplyScalar( 1 / _end4.w );
 
-				end.x *= resolution.x / 2;
-				end.y *= resolution.y / 2;
+			// screen space
+			_start4.x *= resolution.x / 2;
+			_start4.y *= resolution.y / 2;
 
-				// create 2d segment
-				line.start.copy( start );
-				line.start.z = 0;
+			_end4.x *= resolution.x / 2;
+			_end4.y *= resolution.y / 2;
 
-				line.end.copy( end );
-				line.end.z = 0;
+			// create 2d segment
+			_line.start.copy( _start4 );
+			_line.start.z = 0;
 
-				// get closest point on ray to segment
-				var param = line.closestPointToPointParameter( ssOrigin3, true );
-				line.at( param, closestPoint );
+			_line.end.copy( _end4 );
+			_line.end.z = 0;
 
-				// check if the intersection point is within clip space
-				var zPos = MathUtils.lerp( start.z, end.z, param );
-				var isInClipSpace = zPos >= - 1 && zPos <= 1;
+			// get closest point on ray to segment
+			const param = _line.closestPointToPointParameter( _ssOrigin3, true );
+			_line.at( param, _closestPoint );
 
-				var isInside = ssOrigin3.distanceTo( closestPoint ) < lineWidth * 0.5;
+			// check if the intersection point is within clip space
+			const zPos = MathUtils.lerp( _start4.z, _end4.z, param );
+			const isInClipSpace = zPos >= - 1 && zPos <= 1;
 
-				if ( isInClipSpace && isInside ) {
+			const isInside = _ssOrigin3.distanceTo( _closestPoint ) < lineWidth * 0.5;
 
-					line.start.fromBufferAttribute( instanceStart, i );
-					line.end.fromBufferAttribute( instanceEnd, i );
+			if ( isInClipSpace && isInside ) {
 
-					line.start.applyMatrix4( matrixWorld );
-					line.end.applyMatrix4( matrixWorld );
+				_line.start.fromBufferAttribute( instanceStart, i );
+				_line.end.fromBufferAttribute( instanceEnd, i );
 
-					var pointOnLine = new Vector3();
-					var point = new Vector3();
+				_line.start.applyMatrix4( matrixWorld );
+				_line.end.applyMatrix4( matrixWorld );
 
-					ray.distanceSqToSegment( line.start, line.end, point, pointOnLine );
+				const pointOnLine = new Vector3();
+				const point = new Vector3();
 
-					intersects.push( {
+				ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
 
-						point: point,
-						pointOnLine: pointOnLine,
-						distance: ray.origin.distanceTo( point ),
+				intersects.push( {
 
-						object: this,
-						face: null,
-						faceIndex: i,
-						uv: null,
-						uv2: null,
+					point: point,
+					pointOnLine: pointOnLine,
+					distance: ray.origin.distanceTo( point ),
 
-					} );
+					object: this,
+					face: null,
+					faceIndex: i,
+					uv: null,
+					uv2: null,
 
-				}
+				} );
 
 			}
 
-		};
+		}
+
+	}
 
-	}() )
+}
 
-} );
+LineSegments2.prototype.LineSegments2 = true;
 
 export { LineSegments2 };

+ 76 - 87
examples/jsm/lines/LineSegmentsGeometry.js

@@ -9,32 +9,31 @@ import {
 	WireframeGeometry
 } from '../../../build/three.module.js';
 
-var LineSegmentsGeometry = function () {
+const _box = new Box3();
+const _vector = new Vector3();
 
-	InstancedBufferGeometry.call( this );
+class LineSegmentsGeometry extends InstancedBufferGeometry {
 
-	this.type = 'LineSegmentsGeometry';
+	constructor() {
 
-	var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
-	var uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
-	var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
+		super();
 
-	this.setIndex( index );
-	this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
-	this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
+		this.type = 'LineSegmentsGeometry';
 
-};
+		const positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
+		const uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
+		const index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
 
-LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGeometry.prototype ), {
+		this.setIndex( index );
+		this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
+		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
 
-	constructor: LineSegmentsGeometry,
-
-	isLineSegmentsGeometry: true,
+	}
 
-	applyMatrix4: function ( matrix ) {
+	applyMatrix4( matrix ) {
 
-		var start = this.attributes.instanceStart;
-		var end = this.attributes.instanceEnd;
+		const start = this.attributes.instanceStart;
+		const end = this.attributes.instanceEnd;
 
 		if ( start !== undefined ) {
 
@@ -60,11 +59,11 @@ LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGe
 
 		return this;
 
-	},
+	}
 
-	setPositions: function ( array ) {
+	setPositions( array ) {
 
-		var lineSegments;
+		let lineSegments;
 
 		if ( array instanceof Float32Array ) {
 
@@ -76,7 +75,7 @@ LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGe
 
 		}
 
-		var instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
+		const instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
 
 		this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
 		this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
@@ -88,11 +87,11 @@ LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGe
 
 		return this;
 
-	},
+	}
 
-	setColors: function ( array ) {
+	setColors( array ) {
 
-		var colors;
+		let colors;
 
 		if ( array instanceof Float32Array ) {
 
@@ -104,32 +103,32 @@ LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGe
 
 		}
 
-		var instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
+		const instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
 
 		this.setAttribute( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
 		this.setAttribute( 'instanceColorEnd', new InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
 
 		return this;
 
-	},
+	}
 
-	fromWireframeGeometry: function ( geometry ) {
+	fromWireframeGeometry( geometry ) {
 
 		this.setPositions( geometry.attributes.position.array );
 
 		return this;
 
-	},
+	}
 
-	fromEdgesGeometry: function ( geometry ) {
+	fromEdgesGeometry( geometry ) {
 
 		this.setPositions( geometry.attributes.position.array );
 
 		return this;
 
-	},
+	}
 
-	fromMesh: function ( mesh ) {
+	fromMesh( mesh ) {
 
 		this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) );
 
@@ -137,11 +136,11 @@ LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGe
 
 		return this;
 
-	},
+	}
 
-	fromLineSegments: function ( lineSegments ) {
+	romLineSegments( lineSegments ) {
 
-		var geometry = lineSegments.geometry;
+		const geometry = lineSegments.geometry;
 
 		if ( geometry.isGeometry ) {
 
@@ -158,97 +157,85 @@ LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGe
 
 		return this;
 
-	},
-
-	computeBoundingBox: function () {
-
-		var box = new Box3();
-
-		return function computeBoundingBox() {
-
-			if ( this.boundingBox === null ) {
-
-				this.boundingBox = new Box3();
-
-			}
+	}
 
-			var start = this.attributes.instanceStart;
-			var end = this.attributes.instanceEnd;
+	computeBoundingBox() {
 
-			if ( start !== undefined && end !== undefined ) {
+		if ( this.boundingBox === null ) {
 
-				this.boundingBox.setFromBufferAttribute( start );
+			this.boundingBox = new Box3();
 
-				box.setFromBufferAttribute( end );
+		}
 
-				this.boundingBox.union( box );
+		const start = this.attributes.instanceStart;
+		const end = this.attributes.instanceEnd;
 
-			}
+		if ( start !== undefined && end !== undefined ) {
 
-		};
+			this.boundingBox.setFromBufferAttribute( start );
 
-	}(),
+			_box.setFromBufferAttribute( end );
 
-	computeBoundingSphere: function () {
+			this.boundingBox.union( _box );
 
-		var vector = new Vector3();
+		}
 
-		return function computeBoundingSphere() {
+	}
 
-			if ( this.boundingSphere === null ) {
+	computeBoundingSphere() {
 
-				this.boundingSphere = new Sphere();
+		if ( this.boundingSphere === null ) {
 
-			}
+			this.boundingSphere = new Sphere();
 
-			if ( this.boundingBox === null ) {
+		}
 
-				this.computeBoundingBox();
+		if ( this.boundingBox === null ) {
 
-			}
+			this.computeBoundingBox();
 
-			var start = this.attributes.instanceStart;
-			var end = this.attributes.instanceEnd;
+		}
 
-			if ( start !== undefined && end !== undefined ) {
+		const start = this.attributes.instanceStart;
+		const end = this.attributes.instanceEnd;
 
-				var center = this.boundingSphere.center;
+		if ( start !== undefined && end !== undefined ) {
 
-				this.boundingBox.getCenter( center );
+			const center = this.boundingSphere.center;
 
-				var maxRadiusSq = 0;
+			this.boundingBox.getCenter( center );
 
-				for ( var i = 0, il = start.count; i < il; i ++ ) {
+			let maxRadiusSq = 0;
 
-					vector.fromBufferAttribute( start, i );
-					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+			for ( let i = 0, il = start.count; i < il; i ++ ) {
 
-					vector.fromBufferAttribute( end, i );
-					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+				_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 ) ) {
+			this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
 
-					console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
+			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 );
 
 			}
 
-		};
+		}
 
-	}(),
+	}
 
-	toJSON: function () {
+	toJSON() {
 
 		// todo
 
-	},
+	}
 
-	applyMatrix: function ( matrix ) {
+	applyMatrix( matrix ) {
 
 		console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
 
@@ -256,6 +243,8 @@ LineSegmentsGeometry.prototype = Object.assign( Object.create( InstancedBufferGe
 
 	}
 
-} );
+}
+
+LineSegmentsGeometry.prototype.isLineSegmentsGeometry = true;
 
 export { LineSegmentsGeometry };

+ 26 - 33
examples/jsm/lines/Wireframe.js

@@ -7,57 +7,50 @@ import {
 import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
 import { LineMaterial } from '../lines/LineMaterial.js';
 
-var Wireframe = function ( geometry, material ) {
+const _start = new Vector3();
+const _end = new Vector3();
 
-	Mesh.call( this );
+class Wireframe extends Mesh {
 
-	this.type = 'Wireframe';
+	constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
 
-	this.geometry = geometry !== undefined ? geometry : new LineSegmentsGeometry();
-	this.material = material !== undefined ? material : new LineMaterial( { color: Math.random() * 0xffffff } );
+		super( geometry, material );
 
-};
+		this.type = 'Wireframe';
 
-Wireframe.prototype = Object.assign( Object.create( Mesh.prototype ), {
+	}
 
-	constructor: Wireframe,
+	// for backwards-compatability, but could be a method of LineSegmentsGeometry...
 
-	isWireframe: true,
+	computeLineDistances() {
 
-	computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
+		const geometry = this.geometry;
 
-		var start = new Vector3();
-		var end = new Vector3();
+		const instanceStart = geometry.attributes.instanceStart;
+		const instanceEnd = geometry.attributes.instanceEnd;
+		const lineDistances = new Float32Array( 2 * instanceStart.count );
 
-		return function computeLineDistances() {
+		for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
 
-			var geometry = this.geometry;
+			_start.fromBufferAttribute( instanceStart, i );
+			_end.fromBufferAttribute( instanceEnd, i );
 
-			var instanceStart = geometry.attributes.instanceStart;
-			var instanceEnd = geometry.attributes.instanceEnd;
-			var lineDistances = new Float32Array( 2 * instanceStart.count );
+			lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
+			lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
 
-			for ( var i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
+		}
 
-				start.fromBufferAttribute( instanceStart, i );
-				end.fromBufferAttribute( instanceEnd, i );
+		const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
 
-				lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
-				lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
+		geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
+		geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
 
-			}
+		return this;
 
-			var instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
+	}
 
-			geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
-			geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
+}
 
-			return this;
-
-		};
-
-	}() )
-
-} );
+Wireframe.prototype.isWireframe = true;
 
 export { Wireframe };

+ 9 - 11
examples/jsm/lines/WireframeGeometry2.js

@@ -3,24 +3,22 @@ import {
 } from '../../../build/three.module.js';
 import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry.js';
 
-var WireframeGeometry2 = function ( geometry ) {
+class WireframeGeometry2 extends LineSegmentsGeometry {
 
-	LineSegmentsGeometry.call( this );
+	constructor( geometry ) {
 
-	this.type = 'WireframeGeometry2';
+		super();
 
-	this.fromWireframeGeometry( new WireframeGeometry( geometry ) );
+		this.type = 'WireframeGeometry2';
 
-	// set colors, maybe
+		this.fromWireframeGeometry( new WireframeGeometry( geometry ) );
 
-};
+		// set colors, maybe
 
-WireframeGeometry2.prototype = Object.assign( Object.create( LineSegmentsGeometry.prototype ), {
+	}
 
-	constructor: WireframeGeometry2,
+}
 
-	isWireframeGeometry2: true
-
-} );
+WireframeGeometry2.prototype.isWireframeGeometry2 = true;
 
 export { WireframeGeometry2 };