From d89e3c32a1eb97e9415e2c361e18af081bc66a25 Mon Sep 17 00:00:00 2001 From: Rodri Date: Mon, 5 Aug 2024 14:34:41 +0100 Subject: [PATCH] feat: remove need for manually assigning Line2 material resolution (#376) --- src/lines/LineMaterial.js | 1 - src/lines/LineSegments2.js | 38 ++++++++++++++++++++++++++++++-------- src/lines/Wireframe.js | 16 +++++++++++++++- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/lines/LineMaterial.js b/src/lines/LineMaterial.js index 728beb17..3c4959de 100644 --- a/src/lines/LineMaterial.js +++ b/src/lines/LineMaterial.js @@ -7,7 +7,6 @@ * dashSize: , * dashOffset: , * gapSize: , - * resolution: , // to be set by renderer * } */ diff --git a/src/lines/LineSegments2.js b/src/lines/LineSegments2.js index f9feecf0..71ac7b21 100644 --- a/src/lines/LineSegments2.js +++ b/src/lines/LineSegments2.js @@ -13,6 +13,8 @@ import { import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry' import { LineMaterial } from '../lines/LineMaterial' +const _viewport = new Vector4(); + const _start = new Vector3() const _end = new Vector3() @@ -29,7 +31,7 @@ const _box = new Box3() const _sphere = new Sphere() const _clipToWorldVector = new Vector4() -let _ray, _instanceStart, _instanceEnd, _lineWidth +let _ray, _lineWidth // Returns the margin required to expand by in world space given the distance from the camera, // line width, resolution, and camera projection @@ -48,9 +50,18 @@ function getWorldSpaceHalfWidth(camera, distance, resolution) { } function raycastWorldUnits(lineSegments, intersects) { - for (let i = 0, l = _instanceStart.count; i < l; i++) { - _line.start.fromBufferAttribute(_instanceStart, i) - _line.end.fromBufferAttribute(_instanceEnd, i) + + const matrixWorld = lineSegments.matrixWorld; + const geometry = lineSegments.geometry; + const instanceStart = geometry.attributes.instanceStart; + const instanceEnd = geometry.attributes.instanceEnd; + const segmentCount = Math.min(geometry.instanceCount, instanceStart.count); + + for (let i = 0, l = segmentCount; i < l; i++) { + _line.start.fromBufferAttribute(instanceStart, i) + _line.end.fromBufferAttribute(instanceEnd, i) + + _line.applyMatrix4(matrixWorld); const pointOnLine = new Vector3() const point = new Vector3() @@ -82,6 +93,7 @@ function raycastScreenSpace(lineSegments, camera, intersects) { const geometry = lineSegments.geometry const instanceStart = geometry.attributes.instanceStart const instanceEnd = geometry.attributes.instanceEnd + const segmentCount = Math.min(geometry.instanceCount, instanceStart.count); const near = -camera.near @@ -107,7 +119,7 @@ function raycastScreenSpace(lineSegments, camera, intersects) { _mvMatrix.multiplyMatrices(camera.matrixWorldInverse, matrixWorld) - for (let i = 0, l = instanceStart.count; i < l; i++) { + for (let i = 0, l = segmentCount; i < l; i++) { _start4.fromBufferAttribute(instanceStart, i) _end4.fromBufferAttribute(instanceEnd, i) @@ -247,9 +259,6 @@ class LineSegments2 extends Mesh { _lineWidth = material.linewidth + threshold - _instanceStart = geometry.attributes.instanceStart - _instanceEnd = geometry.attributes.instanceEnd - // check if we intersect the sphere bounds if (geometry.boundingSphere === null) { geometry.computeBoundingSphere() @@ -300,6 +309,19 @@ class LineSegments2 extends Mesh { raycastScreenSpace(this, camera, intersects) } } + + onBeforeRender(renderer) { + + const uniforms = this.material.uniforms; + + if (uniforms && uniforms.resolution) { + + renderer.getViewport(_viewport); + this.material.uniforms.resolution.value.set(_viewport.z, _viewport.w); + + } + + } } export { LineSegments2 } diff --git a/src/lines/Wireframe.js b/src/lines/Wireframe.js index 2e193dd4..5c3bfe87 100644 --- a/src/lines/Wireframe.js +++ b/src/lines/Wireframe.js @@ -1,9 +1,10 @@ -import { InstancedInterleavedBuffer, InterleavedBufferAttribute, Mesh, Vector3 } from 'three' +import { InstancedInterleavedBuffer, InterleavedBufferAttribute, Mesh, Vector3, Vector4 } from 'three' import { LineSegmentsGeometry } from '../lines/LineSegmentsGeometry' import { LineMaterial } from '../lines/LineMaterial' const _start = new Vector3() const _end = new Vector3() +const _viewport = new Vector4(); class Wireframe extends Mesh { constructor(geometry = new LineSegmentsGeometry(), material = new LineMaterial({ color: Math.random() * 0xffffff })) { @@ -38,6 +39,19 @@ class Wireframe extends Mesh { return this } + + onBeforeRender(renderer) { + + const uniforms = this.material.uniforms; + + if (uniforms && uniforms.resolution) { + + renderer.getViewport(_viewport); + this.material.uniforms.resolution.value.set(_viewport.z, _viewport.w); + + } + + } } export { Wireframe }