diff --git a/examples/js/lines/Line2.js b/examples/js/lines/Line2.js index 874789ff751f08..c84ad7ea792f7f 100644 --- a/examples/js/lines/Line2.js +++ b/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; diff --git a/examples/js/lines/LineGeometry.js b/examples/js/lines/LineGeometry.js index 3cec6b853a5e12..20c75d6368653d 100644 --- a/examples/js/lines/LineGeometry.js +++ b/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; diff --git a/examples/js/lines/LineMaterial.js b/examples/js/lines/LineMaterial.js index 502f93f6718034..c34e0c993738e8 100644 --- a/examples/js/lines/LineMaterial.js +++ b/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; diff --git a/examples/js/lines/LineSegments2.js b/examples/js/lines/LineSegments2.js index 62d623fb39c29a..2b36ce673a8e7a 100644 --- a/examples/js/lines/LineSegments2.js +++ b/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; diff --git a/examples/js/lines/LineSegmentsGeometry.js b/examples/js/lines/LineSegmentsGeometry.js index d4e83383551d9c..ed30dad7bf6071 100644 --- a/examples/js/lines/LineSegmentsGeometry.js +++ b/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; diff --git a/examples/js/lines/Wireframe.js b/examples/js/lines/Wireframe.js index 3b3d9922618143..7c47141e78f029 100644 --- a/examples/js/lines/Wireframe.js +++ b/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; diff --git a/examples/js/lines/WireframeGeometry2.js b/examples/js/lines/WireframeGeometry2.js index 7b0f29aff31fac..a5456d5932320a 100644 --- a/examples/js/lines/WireframeGeometry2.js +++ b/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; diff --git a/examples/jsm/lines/Line2.js b/examples/jsm/lines/Line2.js index afc0f99d0ee4e7..2c1d4a650be75d 100644 --- a/examples/jsm/lines/Line2.js +++ b/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 }; diff --git a/examples/jsm/lines/LineGeometry.js b/examples/jsm/lines/LineGeometry.js index c80f9589e0b3c9..1f85e00265e386 100644 --- a/examples/jsm/lines/LineGeometry.js +++ b/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 }; diff --git a/examples/jsm/lines/LineMaterial.js b/examples/jsm/lines/LineMaterial.js index ed0ece130d3019..3af6a57101e1dc 100644 --- a/examples/jsm/lines/LineMaterial.js +++ b/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; diff --git a/examples/jsm/lines/LineSegments2.js b/examples/jsm/lines/LineSegments2.js index 6240e7867e22eb..653cd7d0e2cb5e 100644 --- a/examples/jsm/lines/LineSegments2.js +++ b/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 }; diff --git a/examples/jsm/lines/LineSegmentsGeometry.js b/examples/jsm/lines/LineSegmentsGeometry.js index b30831b658f234..019dea9f970930 100644 --- a/examples/jsm/lines/LineSegmentsGeometry.js +++ b/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 }; diff --git a/examples/jsm/lines/Wireframe.js b/examples/jsm/lines/Wireframe.js index 21d1f5c917a9ec..c06e80c5fec20b 100644 --- a/examples/jsm/lines/Wireframe.js +++ b/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 }; diff --git a/examples/jsm/lines/WireframeGeometry2.js b/examples/jsm/lines/WireframeGeometry2.js index 4b63a4a06a35dd..dfb4f6c5191993 100644 --- a/examples/jsm/lines/WireframeGeometry2.js +++ b/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 };