mascot-vis 1.7.3 → 1.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mascot.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable */
2
- // version: 1.7.3
2
+ // version: 1.7.5
3
3
  (function (global, factory) {
4
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3'), require('pixi.js')) :
5
- typeof define === 'function' && define.amd ? define(['exports', 'd3', 'pixi.js'], factory) :
6
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.msc = {}, global.d3, global.PIXI));
7
- }(this, (function (exports, d3, PIXI) { 'use strict';
4
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3'), require('three'), require('pixi.js')) :
5
+ typeof define === 'function' && define.amd ? define(['exports', 'd3', 'three', 'pixi.js'], factory) :
6
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.msc = {}, global.d3, global.THREE, global.PIXI));
7
+ }(this, (function (exports, d3, THREE, PIXI) { 'use strict';
8
8
 
9
9
  function _interopNamespace(e) {
10
10
  if (e && e.__esModule) return e;
@@ -27,6 +27,7 @@
27
27
  }
28
28
 
29
29
  var d3__namespace = /*#__PURE__*/_interopNamespace(d3);
30
+ var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
30
31
  var PIXI__namespace = /*#__PURE__*/_interopNamespace(PIXI);
31
32
 
32
33
  class Rectangle {
@@ -1980,12 +1981,36 @@
1980
1981
  }
1981
1982
 
1982
1983
  contains(x, y) {
1984
+ let svgData = this.getSVGPathData();
1985
+ if (svgData !== "") {
1986
+ let ctx = CanvasProvider.getContext(),
1987
+ p = new Path2D(svgData);
1988
+ ctx.lineWidth = Math.max(this.strokeWidth, 2.5);
1989
+ ctx.stroke(p);
1990
+ return ctx.isPointInPath(p, x, y);
1991
+ }
1983
1992
  if (!this._bounds) {
1984
1993
  this._updateBounds();
1985
1994
  }
1986
1995
  return this._bounds.contains(x, y);
1987
1996
  }
1988
1997
 
1998
+ getSVGPathData() {
1999
+ let d = "";
2000
+ for (let i of this.children) {
2001
+ if (i.getSVGPathData)
2002
+ d += i.getSVGPathData();
2003
+ else if (i.bounds) {
2004
+ let b = i.bounds;
2005
+ d += ["M", b.left, b.top].join(" ");
2006
+ d += ["L", b.right, b.top].join(" ");
2007
+ d += ["L", b.right, b.bottom].join(" ");
2008
+ d += ["L", b.left, b.bottom, "Z"].join(" ");
2009
+ }
2010
+ }
2011
+ return d;
2012
+ }
2013
+
1989
2014
  toJSON() {
1990
2015
  let json = {};
1991
2016
  json.type = this.type;
@@ -2738,7 +2763,8 @@
2738
2763
  case ItemType.Ring:
2739
2764
  return _doRingDivide(scene, compnt, orientation, f, datatable);
2740
2765
  case ItemType.Pie:
2741
- return _doPieDivide(scene, compnt, orientation, f, datatable);
2766
+ case ItemType.Arc:
2767
+ return _doArcDivide(scene, compnt, orientation, f, datatable);
2742
2768
  }
2743
2769
 
2744
2770
  }
@@ -2936,7 +2962,7 @@
2936
2962
  return toReturn;
2937
2963
  }
2938
2964
 
2939
- function _doPieDivide(scene, compnt, o, field, datatable) {
2965
+ function _doArcDivide(scene, compnt, o, field, datatable) {
2940
2966
  let toReturn, orientation = o ? o : Orientation.Radial;
2941
2967
  let peers = getPeers(compnt, scene);
2942
2968
  let collClassId;
@@ -3986,9 +4012,6 @@
3986
4012
 
3987
4013
  encoding._map = function() {
3988
4014
  switch (this.datatable.getFieldType(this.field)) {
3989
- case DataType.Date:
3990
- break;
3991
-
3992
4015
  case DataType.Boolean:
3993
4016
  if (!this.scale) {
3994
4017
  this.scale = createScale("ordinalColor");
@@ -4012,7 +4035,7 @@
4012
4035
  }
4013
4036
  break;
4014
4037
 
4015
- default: //integer or number
4038
+ default: //number or date
4016
4039
  if (this.scale) {
4017
4040
  if (!this._mapping) {
4018
4041
  let values = this.scale.domain.concat(this.data);
@@ -4241,10 +4264,11 @@
4241
4264
  if (channel === "width" || channel === "height") {
4242
4265
  let closestLayout = getClosestLayout(this.areas[0]);
4243
4266
  if (closestLayout) {
4244
- let vidx = 0;
4245
- for (let area of this.areas) {
4246
- let cb = getCellBoundsInLayout(area),
4247
- layout = getClosestLayout(area);
4267
+ let vidx = 0, cellBounds = this.areas.map(d => getCellBoundsInLayout(d)), layouts = this.areas.map(d => getClosestLayout(d));
4268
+ for (let [aidx, area] of this.areas.entries()) {
4269
+ let cb = cellBounds[aidx], layout = layouts[aidx];
4270
+ // let cb = getCellBoundsInLayout(area),
4271
+ // layout = getClosestLayout(area);
4248
4272
  for (let i = 0; i < area.vertices.length; i++) {
4249
4273
  let v = this._vertices[i + vidx],
4250
4274
  dx, dy;
@@ -4520,8 +4544,8 @@
4520
4544
 
4521
4545
  _inferTickValues() {
4522
4546
  let enc = this, domain = enc.scale.domain, range = enc.scale.range;
4523
- if (this.datatable.getFieldType(this.field) == DataType.String)
4524
- return domain;
4547
+ // if (this.datatable.getFieldType(this.field) == DataType.String)
4548
+ // return domain;
4525
4549
  let minPxInterval;
4526
4550
  //let minTickIntervalPx = 40, minLabelIntervalPx = 80;
4527
4551
  switch (enc.scale.type) {
@@ -4633,7 +4657,7 @@
4633
4657
  switch (this.channel) {
4634
4658
  case "width":
4635
4659
  case "height": {
4636
- let vertices = getPeers(item.firstVertex, this.scene);
4660
+ let vertices = this._vertices; // getPeers(item.firstVertex, this.scene);
4637
4661
  let offset = alignment ? Math.max(...vertices.map(d => d["y"])) : Math.min(...vertices.map(d => d["y"]));
4638
4662
  return alignment ? [offset, offset - this.scale.rangeExtent] : [offset + this.scale.rangeExtent, offset];
4639
4663
  }
@@ -6089,16 +6113,12 @@
6089
6113
  _computePosition() {
6090
6114
  let c;
6091
6115
  if (this._item.type === "vertex" && !this._item.parent.closed) {
6092
- //TODO: only for vertices that share the same x or y positions
6116
+ //only for vertices that share the same x or y positions
6093
6117
  let peers = getPeers(this._item, this._item.parent.getScene());
6094
- c = peers[0].bounds.clone();
6095
- for (let i = 1; i < peers.length; i++) {
6096
- c = c.union(peers[i].bounds);
6097
- }
6098
- if (this._channel === "x") {
6099
- return c.middle;
6100
- } else if (this._channel === "y") {
6101
- return c.center;
6118
+ if (this._channel === "x" && uniqueNumbers(peers.map(d => d.bounds.middle)).length == 1) {
6119
+ return this._item.bounds.middle;
6120
+ } else if (this._channel === "y" && uniqueNumbers(peers.map(d => d.bounds.center)).length == 1) {
6121
+ return this._item.bounds.center;
6102
6122
  } else if (this._channel === "radialDistance"){
6103
6123
  return this._item.parent.y;
6104
6124
  }
@@ -6612,6 +6632,7 @@
6612
6632
  case DataType.String:
6613
6633
  this._createCategoricalColorLegend(scene, f);
6614
6634
  break;
6635
+ case DataType.Date:
6615
6636
  case DataType.Number:
6616
6637
  case DataType.Integer:
6617
6638
  this._createNumericalColorLegend(scene, f);
@@ -6666,21 +6687,27 @@
6666
6687
  });
6667
6688
  }
6668
6689
  } else {
6669
- let domain = this.encoding.scale.domain;
6670
- let stops = [], uniqueVals = uniqueNumbers(this.encoding.data);
6690
+ let domain = this.encoding.scale.domain, dt = this.encoding.datatable, ft = dt.getFieldType(f);
6691
+ let stops = [], uniqueVals = ft === DataType.Date? dt.getUniqueFieldValues(f) : uniqueNumbers(this.encoding.data);
6671
6692
  if (uniqueVals.length <= 10){
6672
6693
  stops = uniqueVals;
6673
6694
  stops.sort((a, b) => a - b);
6674
6695
  } else {
6675
- let interval = (domain[1] - domain[0])/9;
6676
- for (let i = 0; i < 10; i++)
6677
- stops.push(domain[0] + i * interval);
6678
- let decimalPlaces = 0;
6679
- while (interval < 1) {
6680
- interval *= 10;
6681
- decimalPlaces++;
6696
+ if (ft === DataType.Date) {
6697
+ uniqueVals.sort((a, b) => a - b);
6698
+ for (let i = 0; i < uniqueVals.length; i+= Math.ceil(uniqueVals.length/10))
6699
+ stops.push(uniqueVals[i]);
6700
+ } else {
6701
+ let interval = (domain[1] - domain[0])/9;
6702
+ for (let i = 0; i < 10; i++)
6703
+ stops.push(domain[0] + i * interval);
6704
+ let decimalPlaces = 0;
6705
+ while (interval < 1) {
6706
+ interval *= 10;
6707
+ decimalPlaces++;
6708
+ }
6709
+ stops = stops.map(d => d.toFixed(decimalPlaces));
6682
6710
  }
6683
- stops = stops.map(d => d.toFixed(decimalPlaces));
6684
6711
  }
6685
6712
  if (this._orientation == Orientation.Vertical) {
6686
6713
  gradient = new LinearGradient({x1: 0, y1: 100, x2: 0, y2: 0});
@@ -6689,7 +6716,7 @@
6689
6716
  gradient.addStop(p*100, this.encoding.scale.map(d), 1.0);
6690
6717
  let tk = scene.mark("line", {"x1": this._x + wd, "x2": this._x + wd + tickSize, "y1": this._y + ht - p * ht + titleSize, "y2": this._y + ht - p * ht + titleSize, "strokeColor": this._strokeColor});
6691
6718
  ticks.push(tk);
6692
- let t = scene.mark("text", {fillColor: this._textColor, "text": d, x: this._x + wd + offset + tickSize, y: this._y + ht - p * ht + titleSize, "anchor": ["left", "middle"]});
6719
+ let t = scene.mark("text", {fillColor: this._textColor, "text": ft === DataType.Date? dt.getRawValue(f, d) : d, x: this._x + wd + offset + tickSize, y: this._y + ht - p * ht + titleSize, "anchor": ["left", "middle"]});
6693
6720
  texts.push(t);
6694
6721
  });
6695
6722
  } else {
@@ -6699,7 +6726,7 @@
6699
6726
  gradient.addStop(p*100, this.encoding.scale.map(d), 1.0);
6700
6727
  let tk = scene.mark("line", {"x1": this._x + p * wd, "x2": this._x + p * wd, "y1": this._y + ht + titleSize, "y2": this._y + ht + tickSize + titleSize, "strokeColor": this._strokeColor});
6701
6728
  ticks.push(tk);
6702
- let t = scene.mark("text", {fillColor: this._textColor, "text": d, x: this._x + p * wd, y: this._y + ht + offset + titleSize, "anchor": ["center", "top"]});
6729
+ let t = scene.mark("text", {fillColor: this._textColor, "text": ft === DataType.Date? dt.getRawValue(f, d) : d, x: this._x + p * wd, y: this._y + ht + offset + titleSize, "anchor": ["center", "top"]});
6703
6730
  texts.push(t);
6704
6731
  });
6705
6732
  }
@@ -9088,6 +9115,7 @@
9088
9115
  }
9089
9116
 
9090
9117
  let layout = getClosestLayout(item);
9118
+ if (!layout || (layout.type !== LayoutType.Grid && layout.type !== LayoutType.Stack)) return;
9091
9119
 
9092
9120
  if (layout && (channel == "x" || channel == "y")) {
9093
9121
  let group = layout.group,
@@ -11580,6 +11608,1200 @@
11580
11608
  }
11581
11609
  }
11582
11610
 
11611
+ const _box$1 = new THREE__namespace.Box3();
11612
+
11613
+ const _vector = new THREE__namespace.Vector3();
11614
+
11615
+ class LineSegmentsGeometry extends THREE__namespace.InstancedBufferGeometry {
11616
+
11617
+ constructor() {
11618
+
11619
+ super();
11620
+ this.type = 'LineSegmentsGeometry';
11621
+ 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 ];
11622
+ const uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
11623
+ const index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
11624
+ this.setIndex( index );
11625
+ this.setAttribute( 'position', new THREE__namespace.Float32BufferAttribute( positions, 3 ) );
11626
+ this.setAttribute( 'uv', new THREE__namespace.Float32BufferAttribute( uvs, 2 ) );
11627
+
11628
+ }
11629
+
11630
+ applyMatrix4( matrix ) {
11631
+
11632
+ const start = this.attributes.instanceStart;
11633
+ const end = this.attributes.instanceEnd;
11634
+
11635
+ if ( start !== undefined ) {
11636
+
11637
+ start.applyMatrix4( matrix );
11638
+ end.applyMatrix4( matrix );
11639
+ start.needsUpdate = true;
11640
+
11641
+ }
11642
+
11643
+ if ( this.boundingBox !== null ) {
11644
+
11645
+ this.computeBoundingBox();
11646
+
11647
+ }
11648
+
11649
+ if ( this.boundingSphere !== null ) {
11650
+
11651
+ this.computeBoundingSphere();
11652
+
11653
+ }
11654
+
11655
+ return this;
11656
+
11657
+ }
11658
+
11659
+ setPositions( array ) {
11660
+
11661
+ let lineSegments;
11662
+
11663
+ if ( array instanceof Float32Array ) {
11664
+
11665
+ lineSegments = array;
11666
+
11667
+ } else if ( Array.isArray( array ) ) {
11668
+
11669
+ lineSegments = new Float32Array( array );
11670
+
11671
+ }
11672
+
11673
+ const instanceBuffer = new THREE__namespace.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
11674
+
11675
+ this.setAttribute( 'instanceStart', new THREE__namespace.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
11676
+
11677
+ this.setAttribute( 'instanceEnd', new THREE__namespace.InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
11678
+ //
11679
+
11680
+ this.computeBoundingBox();
11681
+ this.computeBoundingSphere();
11682
+ return this;
11683
+
11684
+ }
11685
+
11686
+ setColors( array ) {
11687
+
11688
+ let colors;
11689
+
11690
+ if ( array instanceof Float32Array ) {
11691
+
11692
+ colors = array;
11693
+
11694
+ } else if ( Array.isArray( array ) ) {
11695
+
11696
+ colors = new Float32Array( array );
11697
+
11698
+ }
11699
+
11700
+ const instanceColorBuffer = new THREE__namespace.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
11701
+
11702
+ this.setAttribute( 'instanceColorStart', new THREE__namespace.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
11703
+
11704
+ this.setAttribute( 'instanceColorEnd', new THREE__namespace.InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
11705
+
11706
+ return this;
11707
+
11708
+ }
11709
+
11710
+ fromWireframeGeometry( geometry ) {
11711
+
11712
+ this.setPositions( geometry.attributes.position.array );
11713
+ return this;
11714
+
11715
+ }
11716
+
11717
+ fromEdgesGeometry( geometry ) {
11718
+
11719
+ this.setPositions( geometry.attributes.position.array );
11720
+ return this;
11721
+
11722
+ }
11723
+
11724
+ fromMesh( mesh ) {
11725
+
11726
+ this.fromWireframeGeometry( new THREE__namespace.WireframeGeometry( mesh.geometry ) ); // set colors, maybe
11727
+
11728
+ return this;
11729
+
11730
+ }
11731
+
11732
+ fromLineSegments( lineSegments ) {
11733
+
11734
+ const geometry = lineSegments.geometry;
11735
+
11736
+ if ( geometry.isGeometry ) {
11737
+
11738
+ console.error( 'THREE.LineSegmentsGeometry no longer supports Geometry. Use THREE.BufferGeometry instead.' );
11739
+ return;
11740
+
11741
+ } else if ( geometry.isBufferGeometry ) {
11742
+
11743
+ this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
11744
+
11745
+ } // set colors, maybe
11746
+
11747
+
11748
+ return this;
11749
+
11750
+ }
11751
+
11752
+ computeBoundingBox() {
11753
+
11754
+ if ( this.boundingBox === null ) {
11755
+
11756
+ this.boundingBox = new THREE__namespace.Box3();
11757
+
11758
+ }
11759
+
11760
+ const start = this.attributes.instanceStart;
11761
+ const end = this.attributes.instanceEnd;
11762
+
11763
+ if ( start !== undefined && end !== undefined ) {
11764
+
11765
+ this.boundingBox.setFromBufferAttribute( start );
11766
+
11767
+ _box$1.setFromBufferAttribute( end );
11768
+
11769
+ this.boundingBox.union( _box$1 );
11770
+
11771
+ }
11772
+
11773
+ }
11774
+
11775
+ computeBoundingSphere() {
11776
+
11777
+ if ( this.boundingSphere === null ) {
11778
+
11779
+ this.boundingSphere = new THREE__namespace.Sphere();
11780
+
11781
+ }
11782
+
11783
+ if ( this.boundingBox === null ) {
11784
+
11785
+ this.computeBoundingBox();
11786
+
11787
+ }
11788
+
11789
+ const start = this.attributes.instanceStart;
11790
+ const end = this.attributes.instanceEnd;
11791
+
11792
+ if ( start !== undefined && end !== undefined ) {
11793
+
11794
+ const center = this.boundingSphere.center;
11795
+ this.boundingBox.getCenter( center );
11796
+ let maxRadiusSq = 0;
11797
+
11798
+ for ( let i = 0, il = start.count; i < il; i ++ ) {
11799
+
11800
+ _vector.fromBufferAttribute( start, i );
11801
+
11802
+ maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
11803
+
11804
+ _vector.fromBufferAttribute( end, i );
11805
+
11806
+ maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
11807
+
11808
+ }
11809
+
11810
+ this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
11811
+
11812
+ if ( isNaN( this.boundingSphere.radius ) ) {
11813
+
11814
+ console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
11815
+
11816
+ }
11817
+
11818
+ }
11819
+
11820
+ }
11821
+
11822
+ toJSON() { // todo
11823
+ }
11824
+
11825
+ applyMatrix( matrix ) {
11826
+
11827
+ console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
11828
+ return this.applyMatrix4( matrix );
11829
+
11830
+ }
11831
+
11832
+ }
11833
+
11834
+ LineSegmentsGeometry.prototype.isLineSegmentsGeometry = true;
11835
+
11836
+ class LineGeometry extends LineSegmentsGeometry {
11837
+
11838
+ constructor() {
11839
+
11840
+ super();
11841
+ this.type = 'LineGeometry';
11842
+
11843
+ }
11844
+
11845
+ setPositions( array ) {
11846
+
11847
+ // converts [ x1, y1, z1, x2, y2, z2, ... ] to pairs format
11848
+ var length = array.length - 3;
11849
+ var points = new Float32Array( 2 * length );
11850
+
11851
+ for ( var i = 0; i < length; i += 3 ) {
11852
+
11853
+ points[ 2 * i ] = array[ i ];
11854
+ points[ 2 * i + 1 ] = array[ i + 1 ];
11855
+ points[ 2 * i + 2 ] = array[ i + 2 ];
11856
+ points[ 2 * i + 3 ] = array[ i + 3 ];
11857
+ points[ 2 * i + 4 ] = array[ i + 4 ];
11858
+ points[ 2 * i + 5 ] = array[ i + 5 ];
11859
+ }
11860
+
11861
+ super.setPositions( points );
11862
+ return this;
11863
+
11864
+ }
11865
+
11866
+ setColors( array ) {
11867
+
11868
+ // converts [ r1, g1, b1, r2, g2, b2, ... ] to pairs format
11869
+ var length = array.length - 3;
11870
+ var colors = new Float32Array( 2 * length );
11871
+
11872
+ for ( var i = 0; i < length; i += 3 ) {
11873
+
11874
+ colors[ 2 * i ] = array[ i ];
11875
+ colors[ 2 * i + 1 ] = array[ i + 1 ];
11876
+ colors[ 2 * i + 2 ] = array[ i + 2 ];
11877
+ colors[ 2 * i + 3 ] = array[ i + 3 ];
11878
+ colors[ 2 * i + 4 ] = array[ i + 4 ];
11879
+ colors[ 2 * i + 5 ] = array[ i + 5 ];
11880
+
11881
+ }
11882
+
11883
+ super.setColors( colors );
11884
+ return this;
11885
+
11886
+ }
11887
+
11888
+ fromLine( line ) {
11889
+
11890
+ var geometry = line.geometry;
11891
+
11892
+ if ( geometry.isGeometry ) {
11893
+
11894
+ console.error( 'THREE.LineGeometry no longer supports Geometry. Use THREE.BufferGeometry instead.' );
11895
+ return;
11896
+
11897
+ } else if ( geometry.isBufferGeometry ) {
11898
+
11899
+ this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
11900
+
11901
+ } // set colors, maybe
11902
+
11903
+
11904
+ return this;
11905
+
11906
+ }
11907
+
11908
+ }
11909
+
11910
+ LineGeometry.prototype.isLineGeometry = true;
11911
+
11912
+ /**
11913
+ * parameters = {
11914
+ * color: <hex>,
11915
+ * linewidth: <float>,
11916
+ * dashed: <boolean>,
11917
+ * dashScale: <float>,
11918
+ * dashSize: <float>,
11919
+ * gapSize: <float>,
11920
+ * resolution: <Vector2>, // to be set by renderer
11921
+ * }
11922
+ */
11923
+ THREE__namespace.UniformsLib.line = {
11924
+ worldUnits: {
11925
+ value: 1
11926
+ },
11927
+ linewidth: {
11928
+ value: 1
11929
+ },
11930
+ resolution: {
11931
+ value: new THREE__namespace.Vector2( 1, 1 )
11932
+ },
11933
+ dashScale: {
11934
+ value: 1
11935
+ },
11936
+ dashSize: {
11937
+ value: 1
11938
+ },
11939
+ gapSize: {
11940
+ value: 1
11941
+ } // todo FIX - maybe change to totalSize
11942
+
11943
+ };
11944
+
11945
+ THREE__namespace.ShaderLib[ 'line' ] = {
11946
+ uniforms: THREE__namespace.UniformsUtils.merge( [ THREE__namespace.UniformsLib.common, THREE__namespace.UniformsLib.fog, THREE__namespace.UniformsLib.line ] ),
11947
+ vertexShader:
11948
+ /* glsl */
11949
+ `
11950
+ #include <common>
11951
+ #include <color_pars_vertex>
11952
+ #include <fog_pars_vertex>
11953
+ #include <logdepthbuf_pars_vertex>
11954
+ #include <clipping_planes_pars_vertex>
11955
+
11956
+ uniform float linewidth;
11957
+ uniform vec2 resolution;
11958
+
11959
+ attribute vec3 instanceStart;
11960
+ attribute vec3 instanceEnd;
11961
+
11962
+ attribute vec3 instanceColorStart;
11963
+ attribute vec3 instanceColorEnd;
11964
+
11965
+ varying vec2 vUv;
11966
+ varying vec4 worldPos;
11967
+ varying vec3 worldStart;
11968
+ varying vec3 worldEnd;
11969
+
11970
+ #ifdef USE_DASH
11971
+
11972
+ uniform float dashScale;
11973
+ attribute float instanceDistanceStart;
11974
+ attribute float instanceDistanceEnd;
11975
+ varying float vLineDistance;
11976
+
11977
+ #endif
11978
+
11979
+ void trimSegment( const in vec4 start, inout vec4 end ) {
11980
+
11981
+ // trim end segment so it terminates between the camera plane and the near plane
11982
+
11983
+ // conservative estimate of the near plane
11984
+ float a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column
11985
+ float b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column
11986
+ float nearEstimate = - 0.5 * b / a;
11987
+
11988
+ float alpha = ( nearEstimate - start.z ) / ( end.z - start.z );
11989
+
11990
+ end.xyz = mix( start.xyz, end.xyz, alpha );
11991
+
11992
+ }
11993
+
11994
+ void main() {
11995
+
11996
+ #ifdef USE_COLOR
11997
+
11998
+ vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
11999
+
12000
+ #endif
12001
+
12002
+ #ifdef USE_DASH
12003
+
12004
+ vLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;
12005
+
12006
+ #endif
12007
+
12008
+ float aspect = resolution.x / resolution.y;
12009
+
12010
+ vUv = uv;
12011
+
12012
+ // camera space
12013
+ vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
12014
+ vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
12015
+
12016
+ worldStart = start.xyz;
12017
+ worldEnd = end.xyz;
12018
+
12019
+ // special case for perspective projection, and segments that terminate either in, or behind, the camera plane
12020
+ // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
12021
+ // but we need to perform ndc-space calculations in the shader, so we must address this issue directly
12022
+ // perhaps there is a more elegant solution -- WestLangley
12023
+
12024
+ bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column
12025
+
12026
+ if ( perspective ) {
12027
+
12028
+ if ( start.z < 0.0 && end.z >= 0.0 ) {
12029
+
12030
+ trimSegment( start, end );
12031
+
12032
+ } else if ( end.z < 0.0 && start.z >= 0.0 ) {
12033
+
12034
+ trimSegment( end, start );
12035
+
12036
+ }
12037
+
12038
+ }
12039
+
12040
+ // clip space
12041
+ vec4 clipStart = projectionMatrix * start;
12042
+ vec4 clipEnd = projectionMatrix * end;
12043
+
12044
+ // ndc space
12045
+ vec3 ndcStart = clipStart.xyz / clipStart.w;
12046
+ vec3 ndcEnd = clipEnd.xyz / clipEnd.w;
12047
+
12048
+ // direction
12049
+ vec2 dir = ndcEnd.xy - ndcStart.xy;
12050
+
12051
+ // account for clip-space aspect ratio
12052
+ dir.x *= aspect;
12053
+ dir = normalize( dir );
12054
+
12055
+ #ifdef WORLD_UNITS
12056
+
12057
+ // get the offset direction as perpendicular to the view vector
12058
+ vec3 worldDir = normalize( end.xyz - start.xyz );
12059
+ vec3 offset;
12060
+ if ( position.y < 0.5 ) {
12061
+
12062
+ offset = normalize( cross( start.xyz, worldDir ) );
12063
+
12064
+ } else {
12065
+
12066
+ offset = normalize( cross( end.xyz, worldDir ) );
12067
+
12068
+ }
12069
+
12070
+ // sign flip
12071
+ if ( position.x < 0.0 ) offset *= - 1.0;
12072
+
12073
+ float forwardOffset = dot( worldDir, vec3( 0.0, 0.0, 1.0 ) );
12074
+
12075
+ // don't extend the line if we're rendering dashes because we
12076
+ // won't be rendering the endcaps
12077
+ #ifndef USE_DASH
12078
+
12079
+ // extend the line bounds to encompass endcaps
12080
+ start.xyz += - worldDir * linewidth * 0.5;
12081
+ end.xyz += worldDir * linewidth * 0.5;
12082
+
12083
+ // shift the position of the quad so it hugs the forward edge of the line
12084
+ offset.xy -= dir * forwardOffset;
12085
+ offset.z += 0.5;
12086
+
12087
+ #endif
12088
+
12089
+ // endcaps
12090
+ if ( position.y > 1.0 || position.y < 0.0 ) {
12091
+
12092
+ offset.xy += dir * 2.0 * forwardOffset;
12093
+
12094
+ }
12095
+
12096
+ // adjust for linewidth
12097
+ offset *= linewidth * 0.5;
12098
+
12099
+ // set the world position
12100
+ worldPos = ( position.y < 0.5 ) ? start : end;
12101
+ worldPos.xyz += offset;
12102
+
12103
+ // project the worldpos
12104
+ vec4 clip = projectionMatrix * worldPos;
12105
+
12106
+ // shift the depth of the projected points so the line
12107
+ // segements overlap neatly
12108
+ vec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;
12109
+ clip.z = clipPose.z * clip.w;
12110
+
12111
+ #else
12112
+
12113
+ vec2 offset = vec2( dir.y, - dir.x );
12114
+ // undo aspect ratio adjustment
12115
+ dir.x /= aspect;
12116
+ offset.x /= aspect;
12117
+
12118
+ // sign flip
12119
+ if ( position.x < 0.0 ) offset *= - 1.0;
12120
+
12121
+ // endcaps
12122
+ if ( position.y < 0.0 ) {
12123
+
12124
+ offset += - dir;
12125
+
12126
+ } else if ( position.y > 1.0 ) {
12127
+
12128
+ offset += dir;
12129
+
12130
+ }
12131
+
12132
+ // adjust for linewidth
12133
+ offset *= linewidth;
12134
+
12135
+ // adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
12136
+ offset /= resolution.y;
12137
+
12138
+ // select end
12139
+ vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
12140
+
12141
+ // back to clip space
12142
+ offset *= clip.w;
12143
+
12144
+ clip.xy += offset;
12145
+
12146
+ #endif
12147
+
12148
+ gl_Position = clip;
12149
+
12150
+ vec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation
12151
+
12152
+ #include <logdepthbuf_vertex>
12153
+ #include <clipping_planes_vertex>
12154
+ #include <fog_vertex>
12155
+
12156
+ }
12157
+ ` ,
12158
+ fragmentShader:
12159
+ /* glsl */
12160
+ `
12161
+ uniform vec3 diffuse;
12162
+ uniform float opacity;
12163
+ uniform float linewidth;
12164
+
12165
+ #ifdef USE_DASH
12166
+
12167
+ uniform float dashSize;
12168
+ uniform float gapSize;
12169
+
12170
+ #endif
12171
+
12172
+ varying float vLineDistance;
12173
+ varying vec4 worldPos;
12174
+ varying vec3 worldStart;
12175
+ varying vec3 worldEnd;
12176
+
12177
+ #include <common>
12178
+ #include <color_pars_fragment>
12179
+ #include <fog_pars_fragment>
12180
+ #include <logdepthbuf_pars_fragment>
12181
+ #include <clipping_planes_pars_fragment>
12182
+
12183
+ varying vec2 vUv;
12184
+
12185
+ vec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {
12186
+
12187
+ float mua;
12188
+ float mub;
12189
+
12190
+ vec3 p13 = p1 - p3;
12191
+ vec3 p43 = p4 - p3;
12192
+
12193
+ vec3 p21 = p2 - p1;
12194
+
12195
+ float d1343 = dot( p13, p43 );
12196
+ float d4321 = dot( p43, p21 );
12197
+ float d1321 = dot( p13, p21 );
12198
+ float d4343 = dot( p43, p43 );
12199
+ float d2121 = dot( p21, p21 );
12200
+
12201
+ float denom = d2121 * d4343 - d4321 * d4321;
12202
+
12203
+ float numer = d1343 * d4321 - d1321 * d4343;
12204
+
12205
+ mua = numer / denom;
12206
+ mua = clamp( mua, 0.0, 1.0 );
12207
+ mub = ( d1343 + d4321 * ( mua ) ) / d4343;
12208
+ mub = clamp( mub, 0.0, 1.0 );
12209
+
12210
+ return vec2( mua, mub );
12211
+
12212
+ }
12213
+
12214
+ void main() {
12215
+
12216
+ #include <clipping_planes_fragment>
12217
+
12218
+ #ifdef USE_DASH
12219
+
12220
+ if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps
12221
+
12222
+ if ( mod( vLineDistance, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
12223
+
12224
+ #endif
12225
+
12226
+ float alpha = opacity;
12227
+
12228
+ #ifdef WORLD_UNITS
12229
+
12230
+ // Find the closest points on the view ray and the line segment
12231
+ vec3 rayEnd = normalize( worldPos.xyz ) * 1e5;
12232
+ vec3 lineDir = worldEnd - worldStart;
12233
+ vec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );
12234
+
12235
+ vec3 p1 = worldStart + lineDir * params.x;
12236
+ vec3 p2 = rayEnd * params.y;
12237
+ vec3 delta = p1 - p2;
12238
+ float len = length( delta );
12239
+ float norm = len / linewidth;
12240
+
12241
+ #ifndef USE_DASH
12242
+
12243
+ #ifdef ALPHA_TO_COVERAGE
12244
+
12245
+ float dnorm = fwidth( norm );
12246
+ alpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );
12247
+
12248
+ #else
12249
+
12250
+ if ( norm > 0.5 ) {
12251
+
12252
+ discard;
12253
+
12254
+ }
12255
+
12256
+ #endif
12257
+
12258
+ #endif
12259
+
12260
+ #else
12261
+
12262
+ #ifdef ALPHA_TO_COVERAGE
12263
+
12264
+ // artifacts appear on some hardware if a derivative is taken within a conditional
12265
+ float a = vUv.x;
12266
+ float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
12267
+ float len2 = a * a + b * b;
12268
+ float dlen = fwidth( len2 );
12269
+
12270
+ if ( abs( vUv.y ) > 1.0 ) {
12271
+
12272
+ alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );
12273
+
12274
+ }
12275
+
12276
+ #else
12277
+
12278
+ if ( abs( vUv.y ) > 1.0 ) {
12279
+
12280
+ float a = vUv.x;
12281
+ float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
12282
+ float len2 = a * a + b * b;
12283
+
12284
+ if ( len2 > 1.0 ) discard;
12285
+
12286
+ }
12287
+
12288
+ #endif
12289
+
12290
+ #endif
12291
+
12292
+ vec4 diffuseColor = vec4( diffuse, alpha );
12293
+
12294
+ #include <logdepthbuf_fragment>
12295
+ #include <color_fragment>
12296
+
12297
+ gl_FragColor = vec4( diffuseColor.rgb, alpha );
12298
+
12299
+ #include <tonemapping_fragment>
12300
+ #include <encodings_fragment>
12301
+ #include <fog_fragment>
12302
+ #include <premultiplied_alpha_fragment>
12303
+
12304
+ }
12305
+ `
12306
+ };
12307
+
12308
+ class LineMaterial extends THREE__namespace.ShaderMaterial {
12309
+
12310
+ constructor( parameters ) {
12311
+
12312
+ super( {
12313
+ type: 'LineMaterial',
12314
+ uniforms: THREE__namespace.UniformsUtils.clone( THREE__namespace.ShaderLib[ 'line' ].uniforms ),
12315
+ vertexShader: THREE__namespace.ShaderLib[ 'line' ].vertexShader,
12316
+ fragmentShader: THREE__namespace.ShaderLib[ 'line' ].fragmentShader,
12317
+ clipping: true // required for clipping support
12318
+
12319
+ } );
12320
+ Object.defineProperties( this, {
12321
+ color: {
12322
+ enumerable: true,
12323
+ get: function () {
12324
+
12325
+ return this.uniforms.diffuse.value;
12326
+
12327
+ },
12328
+ set: function ( value ) {
12329
+
12330
+ this.uniforms.diffuse.value = value;
12331
+
12332
+ }
12333
+ },
12334
+ worldUnits: {
12335
+ enumerable: true,
12336
+ get: function () {
12337
+
12338
+ return 'WORLD_UNITS' in this.defines;
12339
+
12340
+ },
12341
+ set: function ( value ) {
12342
+
12343
+ if ( value === true ) {
12344
+
12345
+ this.defines.WORLD_UNITS = '';
12346
+
12347
+ } else {
12348
+
12349
+ delete this.defines.WORLD_UNITS;
12350
+
12351
+ }
12352
+
12353
+ }
12354
+ },
12355
+ linewidth: {
12356
+ enumerable: true,
12357
+ get: function () {
12358
+
12359
+ return this.uniforms.linewidth.value;
12360
+
12361
+ },
12362
+ set: function ( value ) {
12363
+
12364
+ this.uniforms.linewidth.value = value;
12365
+
12366
+ }
12367
+ },
12368
+ dashed: {
12369
+ enumerable: true,
12370
+ get: function () {
12371
+
12372
+ return Boolean( 'USE_DASH' in this.defines );
12373
+
12374
+ },
12375
+
12376
+ set( value ) {
12377
+
12378
+ if ( Boolean( value ) !== Boolean( 'USE_DASH' in this.defines ) ) {
12379
+
12380
+ this.needsUpdate = true;
12381
+
12382
+ }
12383
+
12384
+ if ( value === true ) {
12385
+
12386
+ this.defines.USE_DASH = '';
12387
+
12388
+ } else {
12389
+
12390
+ delete this.defines.USE_DASH;
12391
+
12392
+ }
12393
+
12394
+ }
12395
+
12396
+ },
12397
+ dashScale: {
12398
+ enumerable: true,
12399
+ get: function () {
12400
+
12401
+ return this.uniforms.dashScale.value;
12402
+
12403
+ },
12404
+ set: function ( value ) {
12405
+
12406
+ this.uniforms.dashScale.value = value;
12407
+
12408
+ }
12409
+ },
12410
+ dashSize: {
12411
+ enumerable: true,
12412
+ get: function () {
12413
+
12414
+ return this.uniforms.dashSize.value;
12415
+
12416
+ },
12417
+ set: function ( value ) {
12418
+
12419
+ this.uniforms.dashSize.value = value;
12420
+
12421
+ }
12422
+ },
12423
+ dashOffset: {
12424
+ enumerable: true,
12425
+ get: function () {
12426
+
12427
+ return this.uniforms.dashOffset.value;
12428
+
12429
+ },
12430
+ set: function ( value ) {
12431
+
12432
+ this.uniforms.dashOffset.value = value;
12433
+
12434
+ }
12435
+ },
12436
+ gapSize: {
12437
+ enumerable: true,
12438
+ get: function () {
12439
+
12440
+ return this.uniforms.gapSize.value;
12441
+
12442
+ },
12443
+ set: function ( value ) {
12444
+
12445
+ this.uniforms.gapSize.value = value;
12446
+
12447
+ }
12448
+ },
12449
+ opacity: {
12450
+ enumerable: true,
12451
+ get: function () {
12452
+
12453
+ return this.uniforms.opacity.value;
12454
+
12455
+ },
12456
+ set: function ( value ) {
12457
+
12458
+ this.uniforms.opacity.value = value;
12459
+
12460
+ }
12461
+ },
12462
+ resolution: {
12463
+ enumerable: true,
12464
+ get: function () {
12465
+
12466
+ return this.uniforms.resolution.value;
12467
+
12468
+ },
12469
+ set: function ( value ) {
12470
+
12471
+ this.uniforms.resolution.value.copy( value );
12472
+
12473
+ }
12474
+ },
12475
+ alphaToCoverage: {
12476
+ enumerable: true,
12477
+ get: function () {
12478
+
12479
+ return Boolean( 'ALPHA_TO_COVERAGE' in this.defines );
12480
+
12481
+ },
12482
+ set: function ( value ) {
12483
+
12484
+ if ( Boolean( value ) !== Boolean( 'ALPHA_TO_COVERAGE' in this.defines ) ) {
12485
+
12486
+ this.needsUpdate = true;
12487
+
12488
+ }
12489
+
12490
+ if ( value === true ) {
12491
+
12492
+ this.defines.ALPHA_TO_COVERAGE = '';
12493
+ this.extensions.derivatives = true;
12494
+
12495
+ } else {
12496
+
12497
+ delete this.defines.ALPHA_TO_COVERAGE;
12498
+ this.extensions.derivatives = false;
12499
+
12500
+ }
12501
+
12502
+ }
12503
+ }
12504
+ } );
12505
+ this.setValues( parameters );
12506
+
12507
+ }
12508
+
12509
+ }
12510
+
12511
+ LineMaterial.prototype.isLineMaterial = true;
12512
+
12513
+ const _start = new THREE__namespace.Vector3();
12514
+
12515
+ const _end = new THREE__namespace.Vector3();
12516
+
12517
+ const _start4 = new THREE__namespace.Vector4();
12518
+
12519
+ const _end4 = new THREE__namespace.Vector4();
12520
+
12521
+ const _ssOrigin = new THREE__namespace.Vector4();
12522
+
12523
+ const _ssOrigin3 = new THREE__namespace.Vector3();
12524
+
12525
+ const _mvMatrix = new THREE__namespace.Matrix4();
12526
+
12527
+ const _line = new THREE__namespace.Line3();
12528
+
12529
+ const _closestPoint = new THREE__namespace.Vector3();
12530
+
12531
+ const _box = new THREE__namespace.Box3();
12532
+
12533
+ const _sphere = new THREE__namespace.Sphere();
12534
+
12535
+ const _clipToWorldVector = new THREE__namespace.Vector4();
12536
+
12537
+ class LineSegments2 extends THREE__namespace.Mesh {
12538
+
12539
+ constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( {
12540
+ color: Math.random() * 0xffffff
12541
+ } ) ) {
12542
+
12543
+ super( geometry, material );
12544
+ this.type = 'LineSegments2';
12545
+
12546
+ } // for backwards-compatability, but could be a method of THREE.LineSegmentsGeometry...
12547
+
12548
+ computeLineDistances() {
12549
+
12550
+ const geometry = this.geometry;
12551
+ const instanceStart = geometry.attributes.instanceStart;
12552
+ const instanceEnd = geometry.attributes.instanceEnd;
12553
+ const lineDistances = new Float32Array( 2 * instanceStart.count );
12554
+
12555
+ for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
12556
+
12557
+ _start.fromBufferAttribute( instanceStart, i );
12558
+
12559
+ _end.fromBufferAttribute( instanceEnd, i );
12560
+
12561
+ lineDistances[ j ] = j === 0 ? 0 : lineDistances[ j - 1 ];
12562
+ lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
12563
+
12564
+ }
12565
+
12566
+ const instanceDistanceBuffer = new THREE__namespace.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
12567
+
12568
+ geometry.setAttribute( 'instanceDistanceStart', new THREE__namespace.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
12569
+
12570
+ geometry.setAttribute( 'instanceDistanceEnd', new THREE__namespace.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
12571
+
12572
+ return this;
12573
+
12574
+ }
12575
+
12576
+ raycast( raycaster, intersects ) {
12577
+
12578
+ if ( raycaster.camera === null ) {
12579
+
12580
+ console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' );
12581
+
12582
+ }
12583
+
12584
+ const threshold = raycaster.params.Line2 !== undefined ? raycaster.params.Line2.threshold || 0 : 0;
12585
+ const ray = raycaster.ray;
12586
+ const camera = raycaster.camera;
12587
+ const projectionMatrix = camera.projectionMatrix;
12588
+ const matrixWorld = this.matrixWorld;
12589
+ const geometry = this.geometry;
12590
+ const material = this.material;
12591
+ const resolution = material.resolution;
12592
+ const lineWidth = material.linewidth + threshold;
12593
+ const instanceStart = geometry.attributes.instanceStart;
12594
+ const instanceEnd = geometry.attributes.instanceEnd; // camera forward is negative
12595
+
12596
+ const near = - camera.near; // clip space is [ - 1, 1 ] so multiply by two to get the full
12597
+ // width in clip space
12598
+
12599
+ const ssMaxWidth = 2.0 * Math.max( lineWidth / resolution.width, lineWidth / resolution.height ); //
12600
+ // check if we intersect the sphere bounds
12601
+
12602
+ if ( geometry.boundingSphere === null ) {
12603
+
12604
+ geometry.computeBoundingSphere();
12605
+
12606
+ }
12607
+
12608
+ _sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );
12609
+
12610
+ const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( ray.origin ) ); // get the w component to scale the world space line width
12611
+
12612
+ _clipToWorldVector.set( 0, 0, - distanceToSphere, 1.0 ).applyMatrix4( camera.projectionMatrix );
12613
+
12614
+ _clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
12615
+
12616
+ _clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse ); // increase the sphere bounds by the worst case line screen space width
12617
+
12618
+
12619
+ const sphereMargin = Math.abs( ssMaxWidth / _clipToWorldVector.w ) * 0.5;
12620
+ _sphere.radius += sphereMargin;
12621
+
12622
+ if ( raycaster.ray.intersectsSphere( _sphere ) === false ) {
12623
+
12624
+ return;
12625
+
12626
+ } //
12627
+ // check if we intersect the box bounds
12628
+
12629
+
12630
+ if ( geometry.boundingBox === null ) {
12631
+
12632
+ geometry.computeBoundingBox();
12633
+
12634
+ }
12635
+
12636
+ _box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );
12637
+
12638
+ const distanceToBox = Math.max( camera.near, _box.distanceToPoint( ray.origin ) ); // get the w component to scale the world space line width
12639
+
12640
+ _clipToWorldVector.set( 0, 0, - distanceToBox, 1.0 ).applyMatrix4( camera.projectionMatrix );
12641
+
12642
+ _clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
12643
+
12644
+ _clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse ); // increase the sphere bounds by the worst case line screen space width
12645
+
12646
+
12647
+ const boxMargin = Math.abs( ssMaxWidth / _clipToWorldVector.w ) * 0.5;
12648
+ _box.max.x += boxMargin;
12649
+ _box.max.y += boxMargin;
12650
+ _box.max.z += boxMargin;
12651
+ _box.min.x -= boxMargin;
12652
+ _box.min.y -= boxMargin;
12653
+ _box.min.z -= boxMargin;
12654
+
12655
+ if ( raycaster.ray.intersectsBox( _box ) === false ) {
12656
+
12657
+ return;
12658
+
12659
+ } //
12660
+ // pick a point 1 unit out along the ray to avoid the ray origin
12661
+ // sitting at the camera origin which will cause "w" to be 0 when
12662
+ // applying the projection matrix.
12663
+
12664
+
12665
+ ray.at( 1, _ssOrigin ); // ndc space [ - 1.0, 1.0 ]
12666
+
12667
+ _ssOrigin.w = 1;
12668
+
12669
+ _ssOrigin.applyMatrix4( camera.matrixWorldInverse );
12670
+
12671
+ _ssOrigin.applyMatrix4( projectionMatrix );
12672
+
12673
+ _ssOrigin.multiplyScalar( 1 / _ssOrigin.w ); // screen space
12674
+
12675
+
12676
+ _ssOrigin.x *= resolution.x / 2;
12677
+ _ssOrigin.y *= resolution.y / 2;
12678
+ _ssOrigin.z = 0;
12679
+
12680
+ _ssOrigin3.copy( _ssOrigin );
12681
+
12682
+ _mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );
12683
+
12684
+ for ( let i = 0, l = instanceStart.count; i < l; i ++ ) {
12685
+
12686
+ _start4.fromBufferAttribute( instanceStart, i );
12687
+
12688
+ _end4.fromBufferAttribute( instanceEnd, i );
12689
+
12690
+ _start4.w = 1;
12691
+ _end4.w = 1; // camera space
12692
+
12693
+ _start4.applyMatrix4( _mvMatrix );
12694
+
12695
+ _end4.applyMatrix4( _mvMatrix ); // skip the segment if it's entirely behind the camera
12696
+
12697
+
12698
+ var isBehindCameraNear = _start4.z > near && _end4.z > near;
12699
+
12700
+ if ( isBehindCameraNear ) {
12701
+
12702
+ continue;
12703
+
12704
+ } // trim the segment if it extends behind camera near
12705
+
12706
+
12707
+ if ( _start4.z > near ) {
12708
+
12709
+ const deltaDist = _start4.z - _end4.z;
12710
+ const t = ( _start4.z - near ) / deltaDist;
12711
+
12712
+ _start4.lerp( _end4, t );
12713
+
12714
+ } else if ( _end4.z > near ) {
12715
+
12716
+ const deltaDist = _end4.z - _start4.z;
12717
+ const t = ( _end4.z - near ) / deltaDist;
12718
+
12719
+ _end4.lerp( _start4, t );
12720
+
12721
+ } // clip space
12722
+
12723
+
12724
+ _start4.applyMatrix4( projectionMatrix );
12725
+
12726
+ _end4.applyMatrix4( projectionMatrix ); // ndc space [ - 1.0, 1.0 ]
12727
+
12728
+
12729
+ _start4.multiplyScalar( 1 / _start4.w );
12730
+
12731
+ _end4.multiplyScalar( 1 / _end4.w ); // screen space
12732
+
12733
+
12734
+ _start4.x *= resolution.x / 2;
12735
+ _start4.y *= resolution.y / 2;
12736
+ _end4.x *= resolution.x / 2;
12737
+ _end4.y *= resolution.y / 2; // create 2d segment
12738
+
12739
+ _line.start.copy( _start4 );
12740
+
12741
+ _line.start.z = 0;
12742
+
12743
+ _line.end.copy( _end4 );
12744
+
12745
+ _line.end.z = 0; // get closest point on ray to segment
12746
+
12747
+ const param = _line.closestPointToPointParameter( _ssOrigin3, true );
12748
+
12749
+ _line.at( param, _closestPoint ); // check if the intersection point is within clip space
12750
+
12751
+
12752
+ const zPos = THREE__namespace.MathUtils.lerp( _start4.z, _end4.z, param );
12753
+ const isInClipSpace = zPos >= - 1 && zPos <= 1;
12754
+ const isInside = _ssOrigin3.distanceTo( _closestPoint ) < lineWidth * 0.5;
12755
+
12756
+ if ( isInClipSpace && isInside ) {
12757
+
12758
+ _line.start.fromBufferAttribute( instanceStart, i );
12759
+
12760
+ _line.end.fromBufferAttribute( instanceEnd, i );
12761
+
12762
+ _line.start.applyMatrix4( matrixWorld );
12763
+
12764
+ _line.end.applyMatrix4( matrixWorld );
12765
+
12766
+ const pointOnLine = new THREE__namespace.Vector3();
12767
+ const point = new THREE__namespace.Vector3();
12768
+ ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
12769
+ intersects.push( {
12770
+ point: point,
12771
+ pointOnLine: pointOnLine,
12772
+ distance: ray.origin.distanceTo( point ),
12773
+ object: this,
12774
+ face: null,
12775
+ faceIndex: i,
12776
+ uv: null,
12777
+ uv2: null
12778
+ } );
12779
+
12780
+ }
12781
+
12782
+ }
12783
+
12784
+ }
12785
+
12786
+ }
12787
+
12788
+ LineSegments2.prototype.LineSegments2 = true;
12789
+
12790
+ class Line2 extends LineSegments2 {
12791
+
12792
+ constructor( geometry = new THREE__namespace.LineGeometry(), material = new THREE__namespace.LineMaterial( {
12793
+ color: Math.random() * 0xffffff
12794
+ } ) ) {
12795
+
12796
+ super( geometry, material );
12797
+ this.type = 'Line2';
12798
+
12799
+ }
12800
+
12801
+ }
12802
+
12803
+ Line2.prototype.isLine2 = true;
12804
+
11583
12805
  let DEG2RAD = Math.PI / 180;
11584
12806
  class WebGLRenderer {
11585
12807