@niivue/niivue 0.20.1 → 0.22.2

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/niivue.es.js CHANGED
@@ -97,7 +97,7 @@ function create$2() {
97
97
  out[15] = 1;
98
98
  return out;
99
99
  }
100
- function clone(a) {
100
+ function clone$1(a) {
101
101
  var out = new ARRAY_TYPE(16);
102
102
  out[0] = a[0];
103
103
  out[1] = a[1];
@@ -117,7 +117,7 @@ function clone(a) {
117
117
  out[15] = a[15];
118
118
  return out;
119
119
  }
120
- function copy(out, a) {
120
+ function copy$1(out, a) {
121
121
  out[0] = a[0];
122
122
  out[1] = a[1];
123
123
  out[2] = a[2];
@@ -424,6 +424,19 @@ function create$1() {
424
424
  }
425
425
  return out;
426
426
  }
427
+ function clone(a) {
428
+ var out = new ARRAY_TYPE(3);
429
+ out[0] = a[0];
430
+ out[1] = a[1];
431
+ out[2] = a[2];
432
+ return out;
433
+ }
434
+ function length(a) {
435
+ var x = a[0];
436
+ var y = a[1];
437
+ var z = a[2];
438
+ return Math.hypot(x, y, z);
439
+ }
427
440
  function fromValues$1(x, y, z) {
428
441
  var out = new ARRAY_TYPE(3);
429
442
  out[0] = x;
@@ -431,25 +444,80 @@ function fromValues$1(x, y, z) {
431
444
  out[2] = z;
432
445
  return out;
433
446
  }
447
+ function copy(out, a) {
448
+ out[0] = a[0];
449
+ out[1] = a[1];
450
+ out[2] = a[2];
451
+ return out;
452
+ }
453
+ function add$1(out, a, b) {
454
+ out[0] = a[0] + b[0];
455
+ out[1] = a[1] + b[1];
456
+ out[2] = a[2] + b[2];
457
+ return out;
458
+ }
434
459
  function subtract(out, a, b) {
435
460
  out[0] = a[0] - b[0];
436
461
  out[1] = a[1] - b[1];
437
462
  out[2] = a[2] - b[2];
438
463
  return out;
439
464
  }
465
+ function min$Q(out, a, b) {
466
+ out[0] = Math.min(a[0], b[0]);
467
+ out[1] = Math.min(a[1], b[1]);
468
+ out[2] = Math.min(a[2], b[2]);
469
+ return out;
470
+ }
471
+ function max$Q(out, a, b) {
472
+ out[0] = Math.max(a[0], b[0]);
473
+ out[1] = Math.max(a[1], b[1]);
474
+ out[2] = Math.max(a[2], b[2]);
475
+ return out;
476
+ }
477
+ function negate(out, a) {
478
+ out[0] = -a[0];
479
+ out[1] = -a[1];
480
+ out[2] = -a[2];
481
+ return out;
482
+ }
440
483
  function normalize(out, a) {
441
484
  var x = a[0];
442
485
  var y = a[1];
443
486
  var z = a[2];
444
- var len = x * x + y * y + z * z;
445
- if (len > 0) {
446
- len = 1 / Math.sqrt(len);
487
+ var len2 = x * x + y * y + z * z;
488
+ if (len2 > 0) {
489
+ len2 = 1 / Math.sqrt(len2);
447
490
  }
448
- out[0] = a[0] * len;
449
- out[1] = a[1] * len;
450
- out[2] = a[2] * len;
491
+ out[0] = a[0] * len2;
492
+ out[1] = a[1] * len2;
493
+ out[2] = a[2] * len2;
494
+ return out;
495
+ }
496
+ function dot(a, b) {
497
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
498
+ }
499
+ function cross(out, a, b) {
500
+ var ax = a[0], ay = a[1], az = a[2];
501
+ var bx = b[0], by = b[1], bz = b[2];
502
+ out[0] = ay * bz - az * by;
503
+ out[1] = az * bx - ax * bz;
504
+ out[2] = ax * by - ay * bx;
505
+ return out;
506
+ }
507
+ function lerp(out, a, b, t) {
508
+ var ax = a[0];
509
+ var ay = a[1];
510
+ var az = a[2];
511
+ out[0] = ax + t * (b[0] - ax);
512
+ out[1] = ay + t * (b[1] - ay);
513
+ out[2] = az + t * (b[2] - az);
451
514
  return out;
452
515
  }
516
+ function angle(a, b) {
517
+ var ax = a[0], ay = a[1], az = a[2], bx = b[0], by = b[1], bz = b[2], mag1 = Math.sqrt(ax * ax + ay * ay + az * az), mag2 = Math.sqrt(bx * bx + by * by + bz * bz), mag = mag1 * mag2, cosine = mag && dot(a, b) / mag;
518
+ return Math.acos(Math.min(Math.max(cosine, -1), 1));
519
+ }
520
+ var len = length;
453
521
  (function() {
454
522
  var vec = create$1();
455
523
  return function(a, stride, offset, count, fn, arg) {
@@ -550,16 +618,53 @@ var mul = multiply;
550
618
  var vertRenderShader = `#version 300 es
551
619
  #line 4
552
620
  layout(location=0) in vec3 pos;
553
- in vec3 texCoords;
621
+ layout(location=1) in vec3 texCoords;
554
622
  uniform mat4 mvpMtx;
555
623
  out vec3 vColor;
556
-
557
624
  void main(void) {
558
625
  gl_Position = mvpMtx * vec4(pos, 1.0); //vec4(2.0 * (pos.xyz - 0.5), 1.0);
559
626
  vColor = texCoords;
560
627
  }`;
628
+ const kRenderFunc = `vec3 GetBackPosition(vec3 startPositionTex) {
629
+ vec3 startPosition = startPositionTex * volScale;
630
+ vec3 invR = 1.0 / rayDir;
631
+ vec3 tbot = invR * (vec3(0.0)-startPosition);
632
+ vec3 ttop = invR * (volScale-startPosition);
633
+ vec3 tmax = max(ttop, tbot);
634
+ vec2 t = min(tmax.xx, tmax.yz);
635
+ vec3 endPosition = startPosition + (rayDir * min(t.x, t.y));
636
+ //convert world position back to texture position:
637
+ endPosition = endPosition / volScale;
638
+ return endPosition;
639
+ }
640
+ vec4 applyClip (vec3 dir, inout vec4 samplePos, inout float len, inout bool isClip) {
641
+ float cdot = dot(dir,clipPlane.xyz);
642
+ isClip = false;
643
+ if ((clipPlane.a > 1.0) || (cdot == 0.0)) return samplePos;
644
+ bool frontface = (cdot > 0.0);
645
+ float clipThick = 2.0;
646
+ float dis = (-clipPlane.a - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
647
+ float disBackFace = (-(clipPlane.a-clipThick) - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
648
+ if (((frontface) && (dis >= len)) || ((!frontface) && (dis <= 0.0))) {
649
+ samplePos.a = len + 1.0;
650
+ return samplePos;
651
+ }
652
+ if (frontface) {
653
+ dis = max(0.0, dis);
654
+ samplePos = vec4(samplePos.xyz+dir * dis, dis);
655
+ if (dis > 0.0) isClip = true;
656
+ len = min(disBackFace, len);
657
+ }
658
+ if (!frontface) {
659
+ len = min(dis, len);
660
+ disBackFace = max(0.0, disBackFace);
661
+ if (len == dis) isClip = true;
662
+ samplePos = vec4(samplePos.xyz+dir * disBackFace, disBackFace);
663
+ }
664
+ return samplePos;
665
+ }`;
561
666
  var fragRenderShader = `#version 300 es
562
- #line 15
667
+ #line 14
563
668
  precision highp int;
564
669
  precision highp float;
565
670
  uniform vec3 rayDir;
@@ -569,65 +674,46 @@ uniform vec4 clipPlane;
569
674
  uniform highp sampler3D volume, overlay;
570
675
  uniform float overlays;
571
676
  uniform float backOpacity;
677
+ uniform mat4 mvpMtx;
678
+ uniform mat4 matRAS;
679
+ uniform vec4 clipPlaneColor;
572
680
  in vec3 vColor;
573
681
  out vec4 fColor;
574
- vec3 GetBackPosition(vec3 startPositionTex) {
575
- //texture space is 0..1 in each dimension, volScale adjusts for relative field of view
576
- //convert startPosition to world space units:
577
- vec3 startPosition = startPositionTex * volScale;
578
- vec3 invR = 1.0 / rayDir;
579
- vec3 tbot = invR * (vec3(0.0)-startPosition);
580
- vec3 ttop = invR * (volScale-startPosition);
581
- vec3 tmax = max(ttop, tbot);
582
- vec2 t = min(tmax.xx, tmax.yz);
583
- vec3 endPosition = startPosition + (rayDir * min(t.x, t.y));
584
- //convert world position back to texture position:
585
- endPosition = endPosition / volScale;
586
- return endPosition;
587
- }
588
- vec4 applyClip (vec3 dir, inout vec4 samplePos, inout float len) {
589
- float cdot = dot(dir,clipPlane.xyz);
590
- if ((clipPlane.a > 1.0) || (cdot == 0.0)) return samplePos;
591
- bool frontface = (cdot > 0.0);
592
- float clipThick = 2.0;
593
- float dis = (-clipPlane.a - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
594
- float disBackFace = (-(clipPlane.a-clipThick) - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
595
- if (((frontface) && (dis >= len)) || ((!frontface) && (dis <= 0.0))) {
596
- samplePos.a = len + 1.0;
597
- return samplePos;
598
- }
599
- if (frontface) {
600
- dis = max(0.0, dis);
601
- samplePos = vec4(samplePos.xyz+dir * dis, dis);
602
- len = min(disBackFace, len);
603
- }
604
- if (!frontface) {
605
- len = min(dis, len);
606
- disBackFace = max(0.0, disBackFace);
607
- samplePos = vec4(samplePos.xyz+dir * disBackFace, disBackFace);
608
- }
609
- return samplePos;
682
+ ` + kRenderFunc + `
683
+ float frac2ndc(vec3 frac) {
684
+ //https://stackoverflow.com/questions/7777913/how-to-render-depth-linearly-in-modern-opengl-with-gl-fragcoord-z-in-fragment-sh
685
+ vec4 pos = vec4(frac.xyz, 1.0); //fraction
686
+ vec4 dim = vec4(vec3(textureSize(volume, 0)), 1.0);
687
+ pos = pos * dim;
688
+ vec4 shim = vec4(-0.5, -0.5, -0.5, 0.0);
689
+ pos += shim;
690
+ vec4 mm = transpose(matRAS) * pos;
691
+ float z_ndc = (mvpMtx * vec4(mm.xyz, 1.0)).z;
692
+ return (z_ndc + 1.0) / 2.0;
693
+
610
694
  }
611
695
  void main() {
612
- fColor = vec4(0.0,0.0,0.0,0.0);
696
+ fColor = vec4(0.0,0.0,0.0,0.0);
613
697
  //fColor = vec4(vColor.rgb, 1.0); return;
614
- // fColor = texture(volume, vColor.xyz);
615
- // return;
616
698
  vec3 start = vColor;
699
+ gl_FragDepth = 0.0;
617
700
  vec3 backPosition = GetBackPosition(start);
618
701
  // fColor = vec4(backPosition, 1.0); return;
619
- vec3 dir = backPosition - start;
620
- float len = length(dir);
702
+ vec3 dir = backPosition - start;
703
+ float len = length(dir);
621
704
  float lenVox = length((texVox * start) - (texVox * backPosition));
622
- if (lenVox < 0.5) return;
705
+ if ((lenVox < 0.5) || (len > 3.0)) { //length limit for parallel rays
706
+ return;
707
+ }
623
708
  float sliceSize = len / lenVox; //e.g. if ray length is 1.0 and traverses 50 voxels, each voxel is 0.02 in unit cube
624
709
  float stepSize = sliceSize; //quality: larger step is faster traversal, but fewer samples
625
710
  float opacityCorrection = stepSize/sliceSize;
626
- dir = normalize(dir);
711
+ dir = normalize(dir);
627
712
  vec4 deltaDir = vec4(dir.xyz * stepSize, stepSize);
628
713
  vec4 samplePos = vec4(start.xyz, 0.0); //ray position
629
714
  float lenNoClip = len;
630
- vec4 clipPos = applyClip(dir, samplePos, len);
715
+ bool isClip = false;
716
+ vec4 clipPos = applyClip(dir, samplePos, len, isClip);
631
717
  //start: OPTIONAL fast pass: rapid traversal until first hit
632
718
  float stepSizeFast = sliceSize * 1.9;
633
719
  vec4 deltaDirFast = vec4(dir.xyz * stepSizeFast, stepSizeFast);
@@ -636,21 +722,29 @@ void main() {
636
722
  if (val > 0.01) break;
637
723
  samplePos += deltaDirFast; //advance ray position
638
724
  }
639
- // fColor = vec4(1.0, 0.0, 0.0, 1.0);
640
- if ((samplePos.a > len) && (overlays < 1.0)) return;
725
+ if ((samplePos.a >= len) && (overlays < 1.0)) {
726
+ if (isClip)
727
+ fColor += clipPlaneColor;
728
+ return;
729
+ }
730
+ fColor = vec4(1.0, 1.0, 1.0, 1.0);
731
+ //gl_FragDepth = frac2ndc(samplePos.xyz); //crude due to fast pass resolution
641
732
  samplePos -= deltaDirFast;
642
733
  if (samplePos.a < 0.0)
643
734
  vec4 samplePos = vec4(start.xyz, 0.0); //ray position
644
735
  //end: fast pass
645
736
  vec4 colAcc = vec4(0.0,0.0,0.0,0.0);
737
+ vec4 firstHit = colAcc;
646
738
  const float earlyTermination = 0.95;
647
739
  float backNearest = len; //assume no hit
648
- float ran = fract(sin(gl_FragCoord.x * 12.9898 + gl_FragCoord.y * 78.233) * 43758.5453);
649
- samplePos += deltaDir * ran; //jitter ray
740
+ float ran = fract(sin(gl_FragCoord.x * 12.9898 + gl_FragCoord.y * 78.233) * 43758.5453);
741
+ samplePos += deltaDir * ran; //jitter ray
650
742
  while (samplePos.a <= len) {
651
743
  vec4 colorSample = texture(volume, samplePos.xyz);
652
744
  samplePos += deltaDir; //advance ray position
653
745
  if (colorSample.a < 0.01) continue;
746
+ if (firstHit.a == 0.0)
747
+ firstHit = samplePos;
654
748
  backNearest = min(backNearest, samplePos.a);
655
749
  colorSample.a = 1.0-pow((1.0 - colorSample.a), opacityCorrection);
656
750
  colorSample.rgb *= colorSample.a;
@@ -658,13 +752,15 @@ void main() {
658
752
  if ( colAcc.a > earlyTermination )
659
753
  break;
660
754
  }
755
+ if (firstHit.a != 0.0)
756
+ gl_FragDepth = frac2ndc(firstHit.xyz);
661
757
  colAcc.a = (colAcc.a / earlyTermination) * backOpacity;
662
758
  fColor = colAcc;
663
759
  if (overlays < 1.0) return;
664
760
  //overlay pass
665
761
  len = lenNoClip;
666
762
  samplePos = vec4(start.xyz, 0.0); //ray position
667
- //start: OPTIONAL fast pass: rapid traversal until first hit
763
+ //start: OPTIONAL fast pass: rapid traversal until first hit
668
764
  stepSizeFast = sliceSize * 1.9;
669
765
  deltaDirFast = vec4(dir.xyz * stepSizeFast, stepSizeFast);
670
766
  while (samplePos.a <= len) {
@@ -672,7 +768,11 @@ void main() {
672
768
  if (val > 0.01) break;
673
769
  samplePos += deltaDirFast; //advance ray position
674
770
  }
675
- if (samplePos.a > len) return;
771
+ if (samplePos.a >= len) {
772
+ if (isClip && (fColor.a == 0.0))
773
+ fColor += clipPlaneColor;
774
+ return;
775
+ }
676
776
  samplePos -= deltaDirFast;
677
777
  if (samplePos.a < 0.0)
678
778
  vec4 samplePos = vec4(start.xyz, 0.0); //ray position
@@ -848,6 +948,55 @@ uniform highp isampler3D intensityVol;
848
948
  var fragOrientShaderF = `#version 300 es
849
949
  uniform highp sampler3D intensityVol;
850
950
  `;
951
+ var fragOrientShaderAtlas = `#line 309
952
+ precision highp int;
953
+ precision highp float;
954
+ in vec2 TexCoord;
955
+ out vec4 FragColor;
956
+ uniform float coordZ;
957
+ uniform float layer;
958
+ uniform float numLayers;
959
+ uniform highp sampler2D colormap;
960
+ uniform lowp sampler3D blend3D;
961
+ uniform float opacity;
962
+ uniform vec3 xyzFrac;
963
+ uniform mat4 mtx;
964
+ void main(void) {
965
+ vec4 vx = vec4(TexCoord.x, TexCoord.y, coordZ, 1.0) * mtx;
966
+ uint idx = texture(intensityVol, vx.xyz).r;
967
+ FragColor = vec4(0.0, 0.0, 0.0, 0.0);
968
+ if (idx == uint(0))
969
+ return;
970
+ if (xyzFrac.x > 0.0) { //outline
971
+ vx = vec4(TexCoord.x+xyzFrac.x, TexCoord.y, coordZ, 1.0) * mtx;
972
+ uint R = texture(intensityVol, vx.xyz).r;
973
+ vx = vec4(TexCoord.x-xyzFrac.x, TexCoord.y, coordZ, 1.0) * mtx;
974
+ uint L = texture(intensityVol, vx.xyz).r;
975
+ vx = vec4(TexCoord.x, TexCoord.y+xyzFrac.y, coordZ, 1.0) * mtx;
976
+ uint A = texture(intensityVol, vx.xyz).r;
977
+ vx = vec4(TexCoord.x, TexCoord.y-xyzFrac.y, coordZ, 1.0) * mtx;
978
+ uint P = texture(intensityVol, vx.xyz).r;
979
+ vx = vec4(TexCoord.x, TexCoord.y, coordZ+xyzFrac.z, 1.0) * mtx;
980
+ uint S = texture(intensityVol, vx.xyz).r;
981
+ vx = vec4(TexCoord.x, TexCoord.y, coordZ-xyzFrac.z, 1.0) * mtx;
982
+ uint I = texture(intensityVol, vx.xyz).r;
983
+ if ((idx == R) && (idx == L) && (idx == A) && (idx == P) && (idx == S) && (idx == I))
984
+ return;
985
+ }
986
+ idx = ((idx - uint(1)) % uint(100))+uint(1);
987
+ float fx = (float(idx)+0.5) / 256.0;
988
+ float y = (2.0 * layer + 1.0)/(2.0 * numLayers);
989
+ FragColor = texture(colormap, vec2(fx, y)).rgba;
990
+ FragColor.a *= opacity;
991
+ if (layer < 2.0) return;
992
+ vec2 texXY = TexCoord.xy*0.5 +vec2(0.5,0.5);
993
+ vec4 prevColor = texture(blend3D, vec3(texXY, coordZ));
994
+ // https://en.wikipedia.org/wiki/Alpha_compositing
995
+ float aout = FragColor.a + (1.0 - FragColor.a) * prevColor.a;
996
+ if (aout <= 0.0) return;
997
+ FragColor.rgb = ((FragColor.rgb * FragColor.a) + (prevColor.rgb * prevColor.a * (1.0 - FragColor.a))) / aout;
998
+ FragColor.a = aout;
999
+ }`;
851
1000
  var fragOrientShader = `#line 309
852
1001
  precision highp int;
853
1002
  precision highp float;
@@ -903,7 +1052,8 @@ uniform float opacity;
903
1052
  uniform mat4 mtx;
904
1053
  uniform bool hasAlpha;
905
1054
  void main(void) {
906
- uvec4 aColor = texture(intensityVol, vec3(TexCoord.xy, coordZ));
1055
+ vec4 vx = vec4(TexCoord.xy, coordZ, 1.0) * mtx;
1056
+ uvec4 aColor = texture(intensityVol, vx.xyz);
907
1057
  FragColor = vec4(float(aColor.r) / 255.0, float(aColor.g) / 255.0, float(aColor.b) / 255.0, float(aColor.a) / 255.0);
908
1058
  if (!hasAlpha)
909
1059
  FragColor.a = (FragColor.r * 0.21 + FragColor.g * 0.72 + FragColor.b * 0.07);
@@ -933,7 +1083,7 @@ var vertSurfaceShader = `#version 300 es
933
1083
  layout(location=0) in vec3 pos;
934
1084
  uniform mat4 mvpMtx;
935
1085
  void main(void) {
936
- gl_Position = mvpMtx * vec4(2.0 * (pos.xyz - 0.5), 1.0);
1086
+ gl_Position = mvpMtx * vec4(pos, 1.0);
937
1087
  }`;
938
1088
  var fragSurfaceShader = `#version 300 es
939
1089
  precision highp int;
@@ -943,38 +1093,18 @@ out vec4 color;
943
1093
  void main() {
944
1094
  color = surfaceColor;
945
1095
  }`;
946
- var vertDepthPickingShader = `#version 300 es
947
- #line 414
948
- layout(location=0) in vec3 pos;
949
- in vec3 texCoords;
950
- uniform mat4 mvpMtx;
951
- out vec3 posColor;
952
- void main(void) {
953
- gl_Position = mvpMtx * vec4(pos, 1.0);
954
- posColor = texCoords;
955
- }`;
956
1096
  var fragDepthPickingShader = `#version 300 es
957
1097
  precision highp int;
958
1098
  precision highp float;
959
1099
  uniform int id;
960
- in vec3 posColor;
1100
+ in vec3 vColor;
961
1101
  out vec4 color;
962
1102
  void main() {
963
- color = vec4(posColor, float(id & 255) / 255.0);
964
- }`;
965
- var vertVolumePickingShader = `#version 300 es
966
- #line 4
967
- layout(location=0) in vec3 pos;
968
- in vec3 texCoords;
969
- uniform mat4 mvpMtx;
970
- out vec3 posColor;
971
- void main(void) {
972
- gl_Position = mvpMtx * vec4(pos, 1.0);//mvpMtx * vec4(2.0 * (pos.xyz - 0.5), 1.0);
973
- posColor = texCoords; //pos;
1103
+ color = vec4(vColor, float(id & 255) / 255.0);
974
1104
  }`;
975
1105
  var fragVolumePickingShader = `#version 300 es
976
- #line 15
977
- precision highp int;
1106
+ #line 506
1107
+ //precision highp int;
978
1108
  precision highp float;
979
1109
  uniform vec3 rayDir;
980
1110
  uniform vec3 volScale;
@@ -982,92 +1112,57 @@ uniform vec3 texVox;
982
1112
  uniform vec4 clipPlane;
983
1113
  uniform highp sampler3D volume, overlay;
984
1114
  uniform float overlays;
985
- uniform float backOpacity;
986
1115
  uniform int id;
987
- in vec3 posColor;
1116
+ in vec3 vColor;
988
1117
  out vec4 fColor;
989
- vec3 GetBackPosition(vec3 startPositionTex) {
990
- //texture space is 0..1 in each dimension, volScale adjusts for relative field of view
991
- //convert startPosition to world space units:
992
- vec3 startPosition = startPositionTex * volScale;
993
- vec3 invR = 1.0 / rayDir;
994
- vec3 tbot = invR * (vec3(0.0)-startPosition);
995
- vec3 ttop = invR * (volScale-startPosition);
996
- vec3 tmax = max(ttop, tbot);
997
- vec2 t = min(tmax.xx, tmax.yz);
998
- vec3 endPosition = startPosition + (rayDir * min(t.x, t.y));
999
- //convert world position back to texture position:
1000
- endPosition = endPosition / volScale;
1001
- return endPosition;
1002
- }
1003
- vec4 applyClip (vec3 dir, inout vec4 samplePos, inout float len) {
1004
- float cdot = dot(dir,clipPlane.xyz);
1005
- if ((clipPlane.a > 1.0) || (cdot == 0.0)) return samplePos;
1006
- bool frontface = (cdot > 0.0);
1007
- float clipThick = 2.0;
1008
- float dis = (-clipPlane.a - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
1009
- float disBackFace = (-(clipPlane.a-clipThick) - dot(clipPlane.xyz, samplePos.xyz-0.5)) / cdot;
1010
- if (((frontface) && (dis >= len)) || ((!frontface) && (dis <= 0.0))) {
1011
- samplePos.a = len + 1.0;
1012
- return samplePos;
1013
- }
1014
- if (frontface) {
1015
- dis = max(0.0, dis);
1016
- samplePos = vec4(samplePos.xyz+dir * dis, dis);
1017
- len = min(disBackFace, len);
1018
- }
1019
- if (!frontface) {
1020
- len = min(dis, len);
1021
- disBackFace = max(0.0, disBackFace);
1022
- samplePos = vec4(samplePos.xyz+dir * disBackFace, disBackFace);
1023
- }
1024
- return samplePos;
1025
- }
1118
+ ` + kRenderFunc + `
1026
1119
  void main() {
1027
- vec3 start = posColor;
1120
+ vec3 start = vColor;
1121
+ fColor = vec4(0.0, 0.0, 0.0, 0.0); //assume no hit: ID = 0
1122
+ float fid = float(id & 255)/ 255.0;
1028
1123
  vec3 backPosition = GetBackPosition(start);
1029
- vec3 dir = backPosition - start;
1030
- float len = length(dir);
1124
+ vec3 dir = backPosition - start;
1125
+ float len = length(dir);
1031
1126
  float lenVox = length((texVox * start) - (texVox * backPosition));
1032
- if (lenVox < 0.5) return;
1033
- // fColor = vec4(posColor, 1.0);
1127
+ if ((lenVox < 0.5) || (len > 3.0)) return;//discard; //length limit for parallel rays
1034
1128
  float sliceSize = len / lenVox; //e.g. if ray length is 1.0 and traverses 50 voxels, each voxel is 0.02 in unit cube
1035
1129
  float stepSize = sliceSize; //quality: larger step is faster traversal, but fewer samples
1036
1130
  float opacityCorrection = stepSize/sliceSize;
1037
- dir = normalize(dir);
1038
- vec4 deltaDir = vec4(dir.xyz * stepSize, stepSize);
1131
+ dir = normalize(dir);
1039
1132
  vec4 samplePos = vec4(start.xyz, 0.0); //ray position
1040
1133
  float lenNoClip = len;
1041
- vec4 clipPos = applyClip(dir, samplePos, len);
1134
+ bool isClip = false;
1135
+ vec4 clipPos = applyClip(dir, samplePos, len, isClip);
1136
+ if (isClip) fColor = vec4(samplePos.xyz, 253.0 / 255.0); //assume no hit: ID = 0
1042
1137
  //start: OPTIONAL fast pass: rapid traversal until first hit
1043
1138
  float stepSizeFast = sliceSize * 1.9;
1044
1139
  vec4 deltaDirFast = vec4(dir.xyz * stepSizeFast, stepSizeFast);
1045
1140
  while (samplePos.a <= len) {
1046
1141
  float val = texture(volume, samplePos.xyz).a;
1047
1142
  if (val > 0.01) {
1048
- fColor = vec4(samplePos.rgb, float(id & 255) / 255.0);
1049
- return;
1143
+ fColor = vec4(samplePos.rgb, fid);
1144
+ break;
1050
1145
  }
1051
1146
  samplePos += deltaDirFast; //advance ray position
1052
1147
  }
1053
1148
  //end: fast pass
1054
-
1055
-
1056
- if (overlays < 1.0) discard;
1057
-
1149
+ if (overlays < 1.0) {
1150
+ //if (fColor.a == 0.0) discard; //no hit, no overlays
1151
+ return; //background hit, no overlays
1152
+ }
1058
1153
  //overlay pass
1059
- len = lenNoClip;
1154
+ len = min(lenNoClip, samplePos.a); //only find overlay closer than background
1060
1155
  samplePos = vec4(start.xyz, 0.0); //ray position
1061
- //start: OPTIONAL fast pass: rapid traversal until first hit
1062
- stepSizeFast = sliceSize * 1.9;
1063
- deltaDirFast = vec4(dir.xyz * stepSizeFast, stepSizeFast);
1064
1156
  while (samplePos.a <= len) {
1065
1157
  float val = texture(overlay, samplePos.xyz).a;
1066
- if (val > 0.01) break;
1158
+ if (val > 0.01) {
1159
+ fColor = vec4(samplePos.rgb, fid);
1160
+ return;
1161
+ }
1067
1162
  samplePos += deltaDirFast; //advance ray position
1068
1163
  }
1069
- if (samplePos.a > len) return;
1070
- fColor = vec4(posColor, float(id & 255) / 255.0);
1164
+ //if (fColor.a == 0.0) discard; //no hit in either background or overlays
1165
+ //you only get here if there is a hit with the background that is closer than any overlay
1071
1166
  }`;
1072
1167
  const min$P = 0;
1073
1168
  const max$P = 0;
@@ -5552,6 +5647,7 @@ var NiivueObject3D = function(id, vertexBuffer, mode, indexCount, indexBuffer =
5552
5647
  this.renderShaders = [];
5553
5648
  this.pickingShader = null;
5554
5649
  this.isVisible = true;
5650
+ this.isPickable = true;
5555
5651
  this.vertexBuffer = vertexBuffer;
5556
5652
  this.indexCount = indexCount;
5557
5653
  this.indexBuffer = indexBuffer;
@@ -5573,6 +5669,110 @@ var NiivueObject3D = function(id, vertexBuffer, mode, indexCount, indexBuffer =
5573
5669
  this.extentsMin = [];
5574
5670
  this.extentsMax = [];
5575
5671
  };
5672
+ NiivueObject3D.generateCrosshairs = function(gl, id, xyzMM, xyzMin, xyzMax, radius, sides = 20) {
5673
+ let geometry = this.generateCrosshairsGeometry(gl, xyzMM, xyzMin, xyzMax, radius, sides);
5674
+ return new NiivueObject3D(id, geometry.vertexBuffer, gl.TRIANGLES, geometry.indexCount, geometry.indexBuffer);
5675
+ };
5676
+ NiivueObject3D.generateCrosshairsGeometry = function(gl, xyzMM, xyzMin, xyzMax, radius, sides = 20) {
5677
+ let vertices = [];
5678
+ let indices = [];
5679
+ let start = fromValues$1(xyzMin[0], xyzMM[1], xyzMM[2]);
5680
+ let dest = fromValues$1(xyzMax[0], xyzMM[1], xyzMM[2]);
5681
+ NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides);
5682
+ start = fromValues$1(xyzMM[0], xyzMin[1], xyzMM[2]);
5683
+ dest = fromValues$1(xyzMM[0], xyzMax[1], xyzMM[2]);
5684
+ NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides);
5685
+ start = fromValues$1(xyzMM[0], xyzMM[1], xyzMin[2]);
5686
+ dest = fromValues$1(xyzMM[0], xyzMM[1], xyzMax[2]);
5687
+ NiivueObject3D.makeCylinder(vertices, indices, start, dest, radius, sides);
5688
+ let vertexBuffer = gl.createBuffer();
5689
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
5690
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
5691
+ let indexBuffer = gl.createBuffer();
5692
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
5693
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
5694
+ return {
5695
+ vertexBuffer,
5696
+ indexBuffer,
5697
+ indexCount: indices.length
5698
+ };
5699
+ };
5700
+ NiivueObject3D.getFirstPerpVector = function(v1) {
5701
+ let v2 = fromValues$1(0, 0, 0);
5702
+ if (v1[0] === 0)
5703
+ v2[0] = 1;
5704
+ else if (v1[1] === 0)
5705
+ v2[1] = 1;
5706
+ else if (v1[2] === 0)
5707
+ v2[2] = 1;
5708
+ else {
5709
+ v2[0] = v1[2];
5710
+ v2[1] = v1[2];
5711
+ v2[2] = -(v1[0] + v1[1]);
5712
+ normalize(v2, v2);
5713
+ }
5714
+ return v2;
5715
+ };
5716
+ NiivueObject3D.makeCylinder = function(vertices, indices, start, dest, radius, sides = 20) {
5717
+ if (sides < 3)
5718
+ sides = 3;
5719
+ let v1 = create$1();
5720
+ subtract(v1, dest, start);
5721
+ normalize(v1, v1);
5722
+ let v2 = NiivueObject3D.getFirstPerpVector(v1);
5723
+ let v3 = create$1();
5724
+ cross(v3, v1, v2);
5725
+ normalize(v3, v3);
5726
+ let num_v = 2 * sides;
5727
+ let num_f = 2 * sides;
5728
+ {
5729
+ num_f += 2 * sides;
5730
+ num_v += 2;
5731
+ }
5732
+ let idx0 = Math.floor(vertices.length / 3);
5733
+ let idx = new Uint16Array(num_f * 3);
5734
+ let vtx = new Float32Array(num_v * 3);
5735
+ function setV(i, vec3) {
5736
+ vtx[i * 3 + 0] = vec3[0];
5737
+ vtx[i * 3 + 1] = vec3[1];
5738
+ vtx[i * 3 + 2] = vec3[2];
5739
+ }
5740
+ function setI(i, a, b, c) {
5741
+ idx[i * 3 + 0] = a + idx0;
5742
+ idx[i * 3 + 1] = b + idx0;
5743
+ idx[i * 3 + 2] = c + idx0;
5744
+ }
5745
+ let startPole = 2 * sides;
5746
+ let destPole = startPole + 1;
5747
+ {
5748
+ setV(startPole, start);
5749
+ setV(destPole, dest);
5750
+ }
5751
+ let pt1 = create$1();
5752
+ let pt2 = create$1();
5753
+ for (let i = 0; i < sides; i++) {
5754
+ let c = Math.cos(i / sides * 2 * Math.PI);
5755
+ let s = Math.sin(i / sides * 2 * Math.PI);
5756
+ pt1[0] = radius * (c * v2[0] + s * v3[0]);
5757
+ pt1[1] = radius * (c * v2[1] + s * v3[1]);
5758
+ pt1[2] = radius * (c * v2[2] + s * v3[2]);
5759
+ add$1(pt2, start, pt1);
5760
+ setV(i, pt2);
5761
+ add$1(pt2, dest, pt1);
5762
+ setV(i + sides, pt2);
5763
+ let nxt = 0;
5764
+ if (i < sides - 1)
5765
+ nxt = i + 1;
5766
+ setI(i * 2, i, nxt, i + sides);
5767
+ setI(i * 2 + 1, nxt, nxt + sides, i + sides);
5768
+ {
5769
+ setI(sides * 2 + i, i, startPole, nxt);
5770
+ setI(sides * 2 + i + sides, destPole, i + sides, nxt + sides);
5771
+ }
5772
+ }
5773
+ indices.push(...idx);
5774
+ vertices.push(...vtx);
5775
+ };
5576
5776
  var NiivueShader3D = function(shader) {
5577
5777
  this.shader = shader;
5578
5778
  this.uniforms = shader.uniforms;
@@ -6377,9 +6577,9 @@ const Z_BINARY = 0;
6377
6577
  const Z_TEXT = 1;
6378
6578
  const Z_UNKNOWN$1 = 2;
6379
6579
  function zero$1(buf) {
6380
- let len = buf.length;
6381
- while (--len >= 0) {
6382
- buf[len] = 0;
6580
+ let len2 = buf.length;
6581
+ while (--len2 >= 0) {
6582
+ buf[len2] = 0;
6383
6583
  }
6384
6584
  }
6385
6585
  const STORED_BLOCK = 0;
@@ -6440,27 +6640,27 @@ const put_short = (s, w) => {
6440
6640
  s.pending_buf[s.pending++] = w & 255;
6441
6641
  s.pending_buf[s.pending++] = w >>> 8 & 255;
6442
6642
  };
6443
- const send_bits = (s, value, length) => {
6444
- if (s.bi_valid > Buf_size - length) {
6643
+ const send_bits = (s, value, length2) => {
6644
+ if (s.bi_valid > Buf_size - length2) {
6445
6645
  s.bi_buf |= value << s.bi_valid & 65535;
6446
6646
  put_short(s, s.bi_buf);
6447
6647
  s.bi_buf = value >> Buf_size - s.bi_valid;
6448
- s.bi_valid += length - Buf_size;
6648
+ s.bi_valid += length2 - Buf_size;
6449
6649
  } else {
6450
6650
  s.bi_buf |= value << s.bi_valid & 65535;
6451
- s.bi_valid += length;
6651
+ s.bi_valid += length2;
6452
6652
  }
6453
6653
  };
6454
6654
  const send_code = (s, c, tree) => {
6455
6655
  send_bits(s, tree[c * 2], tree[c * 2 + 1]);
6456
6656
  };
6457
- const bi_reverse = (code, len) => {
6657
+ const bi_reverse = (code, len2) => {
6458
6658
  let res = 0;
6459
6659
  do {
6460
6660
  res |= code & 1;
6461
6661
  code >>>= 1;
6462
6662
  res <<= 1;
6463
- } while (--len > 0);
6663
+ } while (--len2 > 0);
6464
6664
  return res >>> 1;
6465
6665
  };
6466
6666
  const bi_flush = (s) => {
@@ -6551,28 +6751,28 @@ const gen_codes = (tree, max_code, bl_count) => {
6551
6751
  next_code[bits] = code = code + bl_count[bits - 1] << 1;
6552
6752
  }
6553
6753
  for (n = 0; n <= max_code; n++) {
6554
- let len = tree[n * 2 + 1];
6555
- if (len === 0) {
6754
+ let len2 = tree[n * 2 + 1];
6755
+ if (len2 === 0) {
6556
6756
  continue;
6557
6757
  }
6558
- tree[n * 2] = bi_reverse(next_code[len]++, len);
6758
+ tree[n * 2] = bi_reverse(next_code[len2]++, len2);
6559
6759
  }
6560
6760
  };
6561
6761
  const tr_static_init = () => {
6562
6762
  let n;
6563
6763
  let bits;
6564
- let length;
6764
+ let length2;
6565
6765
  let code;
6566
6766
  let dist;
6567
6767
  const bl_count = new Array(MAX_BITS$1 + 1);
6568
- length = 0;
6768
+ length2 = 0;
6569
6769
  for (code = 0; code < LENGTH_CODES$1 - 1; code++) {
6570
- base_length[code] = length;
6770
+ base_length[code] = length2;
6571
6771
  for (n = 0; n < 1 << extra_lbits[code]; n++) {
6572
- _length_code[length++] = code;
6772
+ _length_code[length2++] = code;
6573
6773
  }
6574
6774
  }
6575
- _length_code[length - 1] = code;
6775
+ _length_code[length2 - 1] = code;
6576
6776
  dist = 0;
6577
6777
  for (code = 0; code < 16; code++) {
6578
6778
  base_dist[code] = dist;
@@ -6644,14 +6844,14 @@ const bi_windup = (s) => {
6644
6844
  s.bi_buf = 0;
6645
6845
  s.bi_valid = 0;
6646
6846
  };
6647
- const copy_block = (s, buf, len, header) => {
6847
+ const copy_block = (s, buf, len2, header) => {
6648
6848
  bi_windup(s);
6649
6849
  if (header) {
6650
- put_short(s, len);
6651
- put_short(s, ~len);
6850
+ put_short(s, len2);
6851
+ put_short(s, ~len2);
6652
6852
  }
6653
- s.pending_buf.set(s.window.subarray(buf, buf + len), s.pending);
6654
- s.pending += len;
6853
+ s.pending_buf.set(s.window.subarray(buf, buf + len2), s.pending);
6854
+ s.pending += len2;
6655
6855
  };
6656
6856
  const smaller = (tree, n, m, depth) => {
6657
6857
  const _n2 = n * 2;
@@ -6967,11 +7167,11 @@ trees._tr_stored_block = _tr_stored_block$1;
6967
7167
  trees._tr_flush_block = _tr_flush_block$1;
6968
7168
  trees._tr_tally = _tr_tally$1;
6969
7169
  trees._tr_align = _tr_align$1;
6970
- const adler32$2 = (adler, buf, len, pos) => {
7170
+ const adler32$2 = (adler, buf, len2, pos) => {
6971
7171
  let s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0;
6972
- while (len !== 0) {
6973
- n = len > 2e3 ? 2e3 : len;
6974
- len -= n;
7172
+ while (len2 !== 0) {
7173
+ n = len2 > 2e3 ? 2e3 : len2;
7174
+ len2 -= n;
6975
7175
  do {
6976
7176
  s1 = s1 + buf[pos++] | 0;
6977
7177
  s2 = s2 + s1 | 0;
@@ -6994,9 +7194,9 @@ const makeTable = () => {
6994
7194
  return table;
6995
7195
  };
6996
7196
  const crcTable = new Uint32Array(makeTable());
6997
- const crc32$2 = (crc, buf, len, pos) => {
7197
+ const crc32$2 = (crc, buf, len2, pos) => {
6998
7198
  const t = crcTable;
6999
- const end = pos + len;
7199
+ const end = pos + len2;
7000
7200
  crc ^= -1;
7001
7201
  for (let i = pos; i < end; i++) {
7002
7202
  crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 255];
@@ -7103,28 +7303,28 @@ const rank = (f) => {
7103
7303
  return (f << 1) - (f > 4 ? 9 : 0);
7104
7304
  };
7105
7305
  const zero = (buf) => {
7106
- let len = buf.length;
7107
- while (--len >= 0) {
7108
- buf[len] = 0;
7306
+ let len2 = buf.length;
7307
+ while (--len2 >= 0) {
7308
+ buf[len2] = 0;
7109
7309
  }
7110
7310
  };
7111
7311
  let HASH_ZLIB = (s, prev, data) => (prev << s.hash_shift ^ data) & s.hash_mask;
7112
7312
  let HASH = HASH_ZLIB;
7113
7313
  const flush_pending = (strm) => {
7114
7314
  const s = strm.state;
7115
- let len = s.pending;
7116
- if (len > strm.avail_out) {
7117
- len = strm.avail_out;
7315
+ let len2 = s.pending;
7316
+ if (len2 > strm.avail_out) {
7317
+ len2 = strm.avail_out;
7118
7318
  }
7119
- if (len === 0) {
7319
+ if (len2 === 0) {
7120
7320
  return;
7121
7321
  }
7122
- strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out);
7123
- strm.next_out += len;
7124
- s.pending_out += len;
7125
- strm.total_out += len;
7126
- strm.avail_out -= len;
7127
- s.pending -= len;
7322
+ strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len2), strm.next_out);
7323
+ strm.next_out += len2;
7324
+ s.pending_out += len2;
7325
+ strm.total_out += len2;
7326
+ strm.avail_out -= len2;
7327
+ s.pending -= len2;
7128
7328
  if (s.pending === 0) {
7129
7329
  s.pending_out = 0;
7130
7330
  }
@@ -7142,29 +7342,29 @@ const putShortMSB = (s, b) => {
7142
7342
  s.pending_buf[s.pending++] = b & 255;
7143
7343
  };
7144
7344
  const read_buf = (strm, buf, start, size) => {
7145
- let len = strm.avail_in;
7146
- if (len > size) {
7147
- len = size;
7345
+ let len2 = strm.avail_in;
7346
+ if (len2 > size) {
7347
+ len2 = size;
7148
7348
  }
7149
- if (len === 0) {
7349
+ if (len2 === 0) {
7150
7350
  return 0;
7151
7351
  }
7152
- strm.avail_in -= len;
7153
- buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start);
7352
+ strm.avail_in -= len2;
7353
+ buf.set(strm.input.subarray(strm.next_in, strm.next_in + len2), start);
7154
7354
  if (strm.state.wrap === 1) {
7155
- strm.adler = adler32$1(strm.adler, buf, len, start);
7355
+ strm.adler = adler32$1(strm.adler, buf, len2, start);
7156
7356
  } else if (strm.state.wrap === 2) {
7157
- strm.adler = crc32$1(strm.adler, buf, len, start);
7357
+ strm.adler = crc32$1(strm.adler, buf, len2, start);
7158
7358
  }
7159
- strm.next_in += len;
7160
- strm.total_in += len;
7161
- return len;
7359
+ strm.next_in += len2;
7360
+ strm.total_in += len2;
7361
+ return len2;
7162
7362
  };
7163
7363
  const longest_match = (s, cur_match) => {
7164
7364
  let chain_length = s.max_chain_length;
7165
7365
  let scan = s.strstart;
7166
7366
  let match;
7167
- let len;
7367
+ let len2;
7168
7368
  let best_len = s.prev_length;
7169
7369
  let nice_match = s.nice_match;
7170
7370
  const limit = s.strstart > s.w_size - MIN_LOOKAHEAD ? s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0;
@@ -7189,12 +7389,12 @@ const longest_match = (s, cur_match) => {
7189
7389
  match++;
7190
7390
  do {
7191
7391
  } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && scan < strend);
7192
- len = MAX_MATCH - (strend - scan);
7392
+ len2 = MAX_MATCH - (strend - scan);
7193
7393
  scan = strend - MAX_MATCH;
7194
- if (len > best_len) {
7394
+ if (len2 > best_len) {
7195
7395
  s.match_start = cur_match;
7196
- best_len = len;
7197
- if (len >= nice_match) {
7396
+ best_len = len2;
7397
+ if (len2 >= nice_match) {
7198
7398
  break;
7199
7399
  }
7200
7400
  scan_end1 = _win[scan + best_len - 1];
@@ -8088,11 +8288,11 @@ common.assign = function(obj) {
8088
8288
  return obj;
8089
8289
  };
8090
8290
  common.flattenChunks = (chunks) => {
8091
- let len = 0;
8291
+ let len2 = 0;
8092
8292
  for (let i = 0, l = chunks.length; i < l; i++) {
8093
- len += chunks[i].length;
8293
+ len2 += chunks[i].length;
8094
8294
  }
8095
- const result = new Uint8Array(len);
8295
+ const result = new Uint8Array(len2);
8096
8296
  for (let i = 0, pos = 0, l = chunks.length; i < l; i++) {
8097
8297
  let chunk = chunks[i];
8098
8298
  result.set(chunk, pos);
@@ -8156,26 +8356,26 @@ strings$2.string2buf = (str) => {
8156
8356
  }
8157
8357
  return buf;
8158
8358
  };
8159
- const buf2binstring = (buf, len) => {
8160
- if (len < 65534) {
8359
+ const buf2binstring = (buf, len2) => {
8360
+ if (len2 < 65534) {
8161
8361
  if (buf.subarray && STR_APPLY_UIA_OK) {
8162
- return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len));
8362
+ return String.fromCharCode.apply(null, buf.length === len2 ? buf : buf.subarray(0, len2));
8163
8363
  }
8164
8364
  }
8165
8365
  let result = "";
8166
- for (let i = 0; i < len; i++) {
8366
+ for (let i = 0; i < len2; i++) {
8167
8367
  result += String.fromCharCode(buf[i]);
8168
8368
  }
8169
8369
  return result;
8170
8370
  };
8171
8371
  strings$2.buf2string = (buf, max2) => {
8172
- const len = max2 || buf.length;
8372
+ const len2 = max2 || buf.length;
8173
8373
  if (typeof TextDecoder === "function" && TextDecoder.prototype.decode) {
8174
8374
  return new TextDecoder().decode(buf.subarray(0, max2));
8175
8375
  }
8176
8376
  let i, out;
8177
- const utf16buf = new Array(len * 2);
8178
- for (out = 0, i = 0; i < len; ) {
8377
+ const utf16buf = new Array(len2 * 2);
8378
+ for (out = 0, i = 0; i < len2; ) {
8179
8379
  let c = buf[i++];
8180
8380
  if (c < 128) {
8181
8381
  utf16buf[out++] = c;
@@ -8188,7 +8388,7 @@ strings$2.buf2string = (buf, max2) => {
8188
8388
  continue;
8189
8389
  }
8190
8390
  c &= c_len === 2 ? 31 : c_len === 3 ? 15 : 7;
8191
- while (c_len > 1 && i < len) {
8391
+ while (c_len > 1 && i < len2) {
8192
8392
  c = c << 6 | buf[i++] & 63;
8193
8393
  c_len--;
8194
8394
  }
@@ -8411,7 +8611,7 @@ var inffast = function inflate_fast(strm, start) {
8411
8611
  let dmask;
8412
8612
  let here;
8413
8613
  let op;
8414
- let len;
8614
+ let len2;
8415
8615
  let dist;
8416
8616
  let from;
8417
8617
  let from_source;
@@ -8453,14 +8653,14 @@ var inffast = function inflate_fast(strm, start) {
8453
8653
  if (op === 0) {
8454
8654
  output[_out++] = here & 65535;
8455
8655
  } else if (op & 16) {
8456
- len = here & 65535;
8656
+ len2 = here & 65535;
8457
8657
  op &= 15;
8458
8658
  if (op) {
8459
8659
  if (bits < op) {
8460
8660
  hold += input[_in++] << bits;
8461
8661
  bits += 8;
8462
8662
  }
8463
- len += hold & (1 << op) - 1;
8663
+ len2 += hold & (1 << op) - 1;
8464
8664
  hold >>>= op;
8465
8665
  bits -= op;
8466
8666
  }
@@ -8510,8 +8710,8 @@ var inffast = function inflate_fast(strm, start) {
8510
8710
  from_source = s_window;
8511
8711
  if (wnext === 0) {
8512
8712
  from += wsize - op;
8513
- if (op < len) {
8514
- len -= op;
8713
+ if (op < len2) {
8714
+ len2 -= op;
8515
8715
  do {
8516
8716
  output[_out++] = s_window[from++];
8517
8717
  } while (--op);
@@ -8521,15 +8721,15 @@ var inffast = function inflate_fast(strm, start) {
8521
8721
  } else if (wnext < op) {
8522
8722
  from += wsize + wnext - op;
8523
8723
  op -= wnext;
8524
- if (op < len) {
8525
- len -= op;
8724
+ if (op < len2) {
8725
+ len2 -= op;
8526
8726
  do {
8527
8727
  output[_out++] = s_window[from++];
8528
8728
  } while (--op);
8529
8729
  from = 0;
8530
- if (wnext < len) {
8730
+ if (wnext < len2) {
8531
8731
  op = wnext;
8532
- len -= op;
8732
+ len2 -= op;
8533
8733
  do {
8534
8734
  output[_out++] = s_window[from++];
8535
8735
  } while (--op);
@@ -8539,8 +8739,8 @@ var inffast = function inflate_fast(strm, start) {
8539
8739
  }
8540
8740
  } else {
8541
8741
  from += wnext - op;
8542
- if (op < len) {
8543
- len -= op;
8742
+ if (op < len2) {
8743
+ len2 -= op;
8544
8744
  do {
8545
8745
  output[_out++] = s_window[from++];
8546
8746
  } while (--op);
@@ -8548,15 +8748,15 @@ var inffast = function inflate_fast(strm, start) {
8548
8748
  from_source = output;
8549
8749
  }
8550
8750
  }
8551
- while (len > 2) {
8751
+ while (len2 > 2) {
8552
8752
  output[_out++] = from_source[from++];
8553
8753
  output[_out++] = from_source[from++];
8554
8754
  output[_out++] = from_source[from++];
8555
- len -= 3;
8755
+ len2 -= 3;
8556
8756
  }
8557
- if (len) {
8757
+ if (len2) {
8558
8758
  output[_out++] = from_source[from++];
8559
- if (len > 1) {
8759
+ if (len2 > 1) {
8560
8760
  output[_out++] = from_source[from++];
8561
8761
  }
8562
8762
  }
@@ -8566,11 +8766,11 @@ var inffast = function inflate_fast(strm, start) {
8566
8766
  output[_out++] = output[from++];
8567
8767
  output[_out++] = output[from++];
8568
8768
  output[_out++] = output[from++];
8569
- len -= 3;
8570
- } while (len > 2);
8571
- if (len) {
8769
+ len2 -= 3;
8770
+ } while (len2 > 2);
8771
+ if (len2) {
8572
8772
  output[_out++] = output[from++];
8573
- if (len > 1) {
8773
+ if (len2 > 1) {
8574
8774
  output[_out++] = output[from++];
8575
8775
  }
8576
8776
  }
@@ -8599,9 +8799,9 @@ var inffast = function inflate_fast(strm, start) {
8599
8799
  break;
8600
8800
  }
8601
8801
  } while (_in < last && _out < end);
8602
- len = bits >> 3;
8603
- _in -= len;
8604
- bits -= len << 3;
8802
+ len2 = bits >> 3;
8803
+ _in -= len2;
8804
+ bits -= len2 << 3;
8605
8805
  hold &= (1 << bits) - 1;
8606
8806
  strm.next_in = _in;
8607
8807
  strm.next_out = _out;
@@ -8753,7 +8953,7 @@ const dext = new Uint8Array([
8753
8953
  ]);
8754
8954
  const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work, opts) => {
8755
8955
  const bits = opts.bits;
8756
- let len = 0;
8956
+ let len2 = 0;
8757
8957
  let sym = 0;
8758
8958
  let min2 = 0, max2 = 0;
8759
8959
  let root = 0;
@@ -8775,8 +8975,8 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8775
8975
  let extra = null;
8776
8976
  let extra_index = 0;
8777
8977
  let here_bits, here_op, here_val;
8778
- for (len = 0; len <= MAXBITS; len++) {
8779
- count[len] = 0;
8978
+ for (len2 = 0; len2 <= MAXBITS; len2++) {
8979
+ count[len2] = 0;
8780
8980
  }
8781
8981
  for (sym = 0; sym < codes; sym++) {
8782
8982
  count[lens[lens_index + sym]]++;
@@ -8805,9 +9005,9 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8805
9005
  root = min2;
8806
9006
  }
8807
9007
  left = 1;
8808
- for (len = 1; len <= MAXBITS; len++) {
9008
+ for (len2 = 1; len2 <= MAXBITS; len2++) {
8809
9009
  left <<= 1;
8810
- left -= count[len];
9010
+ left -= count[len2];
8811
9011
  if (left < 0) {
8812
9012
  return -1;
8813
9013
  }
@@ -8816,8 +9016,8 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8816
9016
  return -1;
8817
9017
  }
8818
9018
  offs[1] = 0;
8819
- for (len = 1; len < MAXBITS; len++) {
8820
- offs[len + 1] = offs[len] + count[len];
9019
+ for (len2 = 1; len2 < MAXBITS; len2++) {
9020
+ offs[len2 + 1] = offs[len2] + count[len2];
8821
9021
  }
8822
9022
  for (sym = 0; sym < codes; sym++) {
8823
9023
  if (lens[lens_index + sym] !== 0) {
@@ -8840,7 +9040,7 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8840
9040
  }
8841
9041
  huff = 0;
8842
9042
  sym = 0;
8843
- len = min2;
9043
+ len2 = min2;
8844
9044
  next = table_index;
8845
9045
  curr = root;
8846
9046
  drop = 0;
@@ -8851,7 +9051,7 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8851
9051
  return 1;
8852
9052
  }
8853
9053
  for (; ; ) {
8854
- here_bits = len - drop;
9054
+ here_bits = len2 - drop;
8855
9055
  if (work[sym] < end) {
8856
9056
  here_op = 0;
8857
9057
  here_val = work[sym];
@@ -8862,14 +9062,14 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8862
9062
  here_op = 32 + 64;
8863
9063
  here_val = 0;
8864
9064
  }
8865
- incr = 1 << len - drop;
9065
+ incr = 1 << len2 - drop;
8866
9066
  fill = 1 << curr;
8867
9067
  min2 = fill;
8868
9068
  do {
8869
9069
  fill -= incr;
8870
9070
  table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;
8871
9071
  } while (fill !== 0);
8872
- incr = 1 << len - 1;
9072
+ incr = 1 << len2 - 1;
8873
9073
  while (huff & incr) {
8874
9074
  incr >>= 1;
8875
9075
  }
@@ -8880,18 +9080,18 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8880
9080
  huff = 0;
8881
9081
  }
8882
9082
  sym++;
8883
- if (--count[len] === 0) {
8884
- if (len === max2) {
9083
+ if (--count[len2] === 0) {
9084
+ if (len2 === max2) {
8885
9085
  break;
8886
9086
  }
8887
- len = lens[lens_index + work[sym]];
9087
+ len2 = lens[lens_index + work[sym]];
8888
9088
  }
8889
- if (len > root && (huff & mask) !== low) {
9089
+ if (len2 > root && (huff & mask) !== low) {
8890
9090
  if (drop === 0) {
8891
9091
  drop = root;
8892
9092
  }
8893
9093
  next += min2;
8894
- curr = len - drop;
9094
+ curr = len2 - drop;
8895
9095
  left = 1 << curr;
8896
9096
  while (curr + drop < max2) {
8897
9097
  left -= count[curr + drop];
@@ -8910,7 +9110,7 @@ const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work
8910
9110
  }
8911
9111
  }
8912
9112
  if (huff !== 0) {
8913
- table[next + huff] = len - drop << 24 | 64 << 16 | 0;
9113
+ table[next + huff] = len2 - drop << 24 | 64 << 16 | 0;
8914
9114
  }
8915
9115
  opts.bits = root;
8916
9116
  return 0;
@@ -9169,7 +9369,7 @@ const inflate$2 = (strm, flush) => {
9169
9369
  let here = 0;
9170
9370
  let here_bits, here_op, here_val;
9171
9371
  let last_bits, last_op, last_val;
9172
- let len;
9372
+ let len2;
9173
9373
  let ret;
9174
9374
  const hbuf = new Uint8Array(4);
9175
9375
  let opts;
@@ -9235,10 +9435,10 @@ const inflate$2 = (strm, flush) => {
9235
9435
  }
9236
9436
  hold >>>= 4;
9237
9437
  bits -= 4;
9238
- len = (hold & 15) + 8;
9438
+ len2 = (hold & 15) + 8;
9239
9439
  if (state.wbits === 0) {
9240
- state.wbits = len;
9241
- } else if (len > state.wbits) {
9440
+ state.wbits = len2;
9441
+ } else if (len2 > state.wbits) {
9242
9442
  strm.msg = "invalid window size";
9243
9443
  state.mode = BAD;
9244
9444
  break;
@@ -9356,11 +9556,11 @@ const inflate$2 = (strm, flush) => {
9356
9556
  }
9357
9557
  if (copy2) {
9358
9558
  if (state.head) {
9359
- len = state.head.extra_len - state.length;
9559
+ len2 = state.head.extra_len - state.length;
9360
9560
  if (!state.head.extra) {
9361
9561
  state.head.extra = new Uint8Array(state.head.extra_len);
9362
9562
  }
9363
- state.head.extra.set(input.subarray(next, next + copy2), len);
9563
+ state.head.extra.set(input.subarray(next, next + copy2), len2);
9364
9564
  }
9365
9565
  if (state.flags & 512) {
9366
9566
  state.check = crc32(state.check, input, copy2, next);
@@ -9382,17 +9582,17 @@ const inflate$2 = (strm, flush) => {
9382
9582
  }
9383
9583
  copy2 = 0;
9384
9584
  do {
9385
- len = input[next + copy2++];
9386
- if (state.head && len && state.length < 65536) {
9387
- state.head.name += String.fromCharCode(len);
9585
+ len2 = input[next + copy2++];
9586
+ if (state.head && len2 && state.length < 65536) {
9587
+ state.head.name += String.fromCharCode(len2);
9388
9588
  }
9389
- } while (len && copy2 < have);
9589
+ } while (len2 && copy2 < have);
9390
9590
  if (state.flags & 512) {
9391
9591
  state.check = crc32(state.check, input, copy2, next);
9392
9592
  }
9393
9593
  have -= copy2;
9394
9594
  next += copy2;
9395
- if (len) {
9595
+ if (len2) {
9396
9596
  break inf_leave;
9397
9597
  }
9398
9598
  } else if (state.head) {
@@ -9407,17 +9607,17 @@ const inflate$2 = (strm, flush) => {
9407
9607
  }
9408
9608
  copy2 = 0;
9409
9609
  do {
9410
- len = input[next + copy2++];
9411
- if (state.head && len && state.length < 65536) {
9412
- state.head.comment += String.fromCharCode(len);
9610
+ len2 = input[next + copy2++];
9611
+ if (state.head && len2 && state.length < 65536) {
9612
+ state.head.comment += String.fromCharCode(len2);
9413
9613
  }
9414
- } while (len && copy2 < have);
9614
+ } while (len2 && copy2 < have);
9415
9615
  if (state.flags & 512) {
9416
9616
  state.check = crc32(state.check, input, copy2, next);
9417
9617
  }
9418
9618
  have -= copy2;
9419
9619
  next += copy2;
9420
- if (len) {
9620
+ if (len2) {
9421
9621
  break inf_leave;
9422
9622
  }
9423
9623
  } else if (state.head) {
@@ -9659,7 +9859,7 @@ const inflate$2 = (strm, flush) => {
9659
9859
  state.mode = BAD;
9660
9860
  break;
9661
9861
  }
9662
- len = state.lens[state.have - 1];
9862
+ len2 = state.lens[state.have - 1];
9663
9863
  copy2 = 3 + (hold & 3);
9664
9864
  hold >>>= 2;
9665
9865
  bits -= 2;
@@ -9675,7 +9875,7 @@ const inflate$2 = (strm, flush) => {
9675
9875
  }
9676
9876
  hold >>>= here_bits;
9677
9877
  bits -= here_bits;
9678
- len = 0;
9878
+ len2 = 0;
9679
9879
  copy2 = 3 + (hold & 7);
9680
9880
  hold >>>= 3;
9681
9881
  bits -= 3;
@@ -9691,7 +9891,7 @@ const inflate$2 = (strm, flush) => {
9691
9891
  }
9692
9892
  hold >>>= here_bits;
9693
9893
  bits -= here_bits;
9694
- len = 0;
9894
+ len2 = 0;
9695
9895
  copy2 = 11 + (hold & 127);
9696
9896
  hold >>>= 7;
9697
9897
  bits -= 7;
@@ -9702,7 +9902,7 @@ const inflate$2 = (strm, flush) => {
9702
9902
  break;
9703
9903
  }
9704
9904
  while (copy2--) {
9705
- state.lens[state.have++] = len;
9905
+ state.lens[state.have++] = len2;
9706
9906
  }
9707
9907
  }
9708
9908
  }
@@ -10432,7 +10632,40 @@ function v4(options, buf, offset) {
10432
10632
  }
10433
10633
  return stringify(rnds);
10434
10634
  }
10435
- var NVImage = function(dataBuffer, name = "", colorMap = "gray", opacity = 1, trustCalMinMax = true, percentileFrac = 0.02, ignoreZeroVoxels = false, visible = true) {
10635
+ const Log = function(logLevel) {
10636
+ this.LOGGING_ON = true;
10637
+ this.LOGGING_OFF = false;
10638
+ this.LOG_PREFIX = "NiiVue:";
10639
+ this.logLevel = logLevel;
10640
+ };
10641
+ Log.prototype.getTimeStamp = function() {
10642
+ return `${this.LOG_PREFIX} `;
10643
+ };
10644
+ Log.prototype.debug = function() {
10645
+ if (this.logLevel === this.LOGGING_ON) {
10646
+ console.log(this.getTimeStamp(), "DEBUG", ...arguments);
10647
+ }
10648
+ };
10649
+ Log.prototype.info = function() {
10650
+ if (this.logLevel === this.LOGGING_ON) {
10651
+ console.log(this.getTimeStamp(), "INFO", ...arguments);
10652
+ }
10653
+ };
10654
+ Log.prototype.warn = function() {
10655
+ if (this.logLevel === this.LOGGING_ON) {
10656
+ console.warn(this.getTimeStamp(), "WARN", ...arguments);
10657
+ }
10658
+ };
10659
+ Log.prototype.error = function() {
10660
+ if (this.logLevel === this.LOGGING_ON) {
10661
+ console.error(this.getTimeStamp(), "ERROR", ...arguments);
10662
+ }
10663
+ };
10664
+ Log.prototype.setLogLevel = function(logLevel) {
10665
+ this.logLevel = logLevel;
10666
+ };
10667
+ const log$1 = new Log();
10668
+ var NVImage = function(dataBuffer, name = "", colorMap = "gray", opacity = 1, trustCalMinMax = true, percentileFrac = 0.02, ignoreZeroVoxels = false, visible = true, useQFormNotSForm = false) {
10436
10669
  this.DT_NONE = 0;
10437
10670
  this.DT_UNKNOWN = 0;
10438
10671
  this.DT_BINARY = 1;
@@ -10465,6 +10698,97 @@ var NVImage = function(dataBuffer, name = "", colorMap = "gray", opacity = 1, tr
10465
10698
  return;
10466
10699
  }
10467
10700
  this.hdr = nifti.exports.readHeader(dataBuffer);
10701
+ function isAffineOK(mtx) {
10702
+ let iOK = [false, false, false, false];
10703
+ let jOK = [false, false, false, false];
10704
+ for (let i2 = 0; i2 < 4; i2++) {
10705
+ for (let j = 0; j < 4; j++) {
10706
+ if (isNaN(mtx[i2][j]))
10707
+ return false;
10708
+ }
10709
+ }
10710
+ for (let i2 = 0; i2 < 3; i2++) {
10711
+ for (let j = 0; j < 3; j++) {
10712
+ if (mtx[i2][j] === 0)
10713
+ continue;
10714
+ iOK[i2] = true;
10715
+ jOK[j] = true;
10716
+ }
10717
+ }
10718
+ for (let i2 = 0; i2 < 3; i2++) {
10719
+ if (!iOK[i2])
10720
+ return false;
10721
+ if (!jOK[i2])
10722
+ return false;
10723
+ }
10724
+ return true;
10725
+ }
10726
+ if (isNaN(this.hdr.scl_slope) || this.hdr.scl_slope === 0)
10727
+ this.hdr.scl_slope = 1;
10728
+ if (isNaN(this.hdr.scl_inter))
10729
+ this.hdr.scl_inter = 0;
10730
+ let affineOK = isAffineOK(this.hdr.affine);
10731
+ if (useQFormNotSForm || !affineOK || this.hdr.qform_code > this.hdr.sform_code) {
10732
+ log$1.debug("spatial transform based on QForm");
10733
+ const b = this.hdr.quatern_b;
10734
+ const c = this.hdr.quatern_c;
10735
+ const d = this.hdr.quatern_d;
10736
+ const a = Math.sqrt(1 - (Math.pow(b, 2) + Math.pow(c, 2) + Math.pow(d, 2)));
10737
+ const qfac = this.hdr.pixDims[0] === 0 ? 1 : this.hdr.pixDims[0];
10738
+ const quatern_R = [
10739
+ [
10740
+ a * a + b * b - c * c - d * d,
10741
+ 2 * b * c - 2 * a * d,
10742
+ 2 * b * d + 2 * a * c
10743
+ ],
10744
+ [
10745
+ 2 * b * c + 2 * a * d,
10746
+ a * a + c * c - b * b - d * d,
10747
+ 2 * c * d - 2 * a * b
10748
+ ],
10749
+ [
10750
+ 2 * b * d - 2 * a * c,
10751
+ 2 * c * d + 2 * a * b,
10752
+ a * a + d * d - c * c - b * b
10753
+ ]
10754
+ ];
10755
+ const affine = this.hdr.affine;
10756
+ for (let ctrOut = 0; ctrOut < 3; ctrOut += 1) {
10757
+ for (let ctrIn = 0; ctrIn < 3; ctrIn += 1) {
10758
+ affine[ctrOut][ctrIn] = quatern_R[ctrOut][ctrIn] * this.hdr.pixDims[ctrIn + 1];
10759
+ if (ctrIn === 2) {
10760
+ affine[ctrOut][ctrIn] *= qfac;
10761
+ }
10762
+ }
10763
+ }
10764
+ affine[0][3] = this.hdr.qoffset_x;
10765
+ affine[1][3] = this.hdr.qoffset_y;
10766
+ affine[2][3] = this.hdr.qoffset_z;
10767
+ this.hdr.affine = affine;
10768
+ }
10769
+ affineOK = isAffineOK(this.hdr.affine);
10770
+ if (!affineOK) {
10771
+ log$1.debug("Defective NIfTI: spatial transform does not make sense");
10772
+ let x = this.hdr.pixDims[1];
10773
+ let y = this.hdr.pixDims[2];
10774
+ let z = this.hdr.pixDims[3];
10775
+ if (isNaN(x) || x === 0)
10776
+ x = 1;
10777
+ if (isNaN(y) || y === 0)
10778
+ y = 1;
10779
+ if (isNaN(z) || z === 0)
10780
+ z = 1;
10781
+ this.hdr.pixDims[1] = x;
10782
+ this.hdr.pixDims[2] = y;
10783
+ this.hdr.pixDims[3] = z;
10784
+ const affine = [
10785
+ [x, 0, 0, 0],
10786
+ [0, y, 0, 0],
10787
+ [0, 0, z, 0],
10788
+ [0, 0, 0, 1]
10789
+ ];
10790
+ this.hdr.affine = affine;
10791
+ }
10468
10792
  let imgRaw = null;
10469
10793
  if (nifti.exports.isCompressed(dataBuffer)) {
10470
10794
  imgRaw = nifti.exports.readImage(this.hdr, nifti.exports.decompress(dataBuffer));
@@ -10531,6 +10855,23 @@ var NVImage = function(dataBuffer, name = "", colorMap = "gray", opacity = 1, tr
10531
10855
  this.calculateRAS();
10532
10856
  this.calMinMax();
10533
10857
  };
10858
+ NVImage.prototype.calculateOblique = function() {
10859
+ let LPI = this.vox2mm([0, 0, 0], this.matRAS);
10860
+ let X1mm = this.vox2mm([1 / this.pixDimsRAS[1], 0, 0], this.matRAS);
10861
+ let Y1mm = this.vox2mm([0, 1 / this.pixDimsRAS[2], 0], this.matRAS);
10862
+ let Z1mm = this.vox2mm([0, 0, 1 / this.pixDimsRAS[3]], this.matRAS);
10863
+ subtract(X1mm, X1mm, LPI);
10864
+ subtract(Y1mm, Y1mm, LPI);
10865
+ subtract(Z1mm, Z1mm, LPI);
10866
+ let oblique = fromValues$2(X1mm[0], X1mm[1], X1mm[2], 0, Y1mm[0], Y1mm[1], Y1mm[2], 0, Z1mm[0], Z1mm[1], Z1mm[2], 0, 0, 0, 0, 1);
10867
+ this.obliqueRAS = clone$1(oblique);
10868
+ let XY = Math.abs(90 - angle(X1mm, Y1mm) * (180 / Math.PI));
10869
+ let XZ = Math.abs(90 - angle(X1mm, Z1mm) * (180 / Math.PI));
10870
+ let YZ = Math.abs(90 - angle(Y1mm, Z1mm) * (180 / Math.PI));
10871
+ let maxShear = Math.max(Math.max(XY, XZ), YZ);
10872
+ if (maxShear > 0.1)
10873
+ log$1.debug("Warning: shear detected (gantry tilt) of %f degrees", maxShear);
10874
+ };
10534
10875
  NVImage.prototype.calculateRAS = function() {
10535
10876
  let a = this.hdr.affine;
10536
10877
  let header = this.hdr;
@@ -10573,7 +10914,7 @@ NVImage.prototype.calculateRAS = function() {
10573
10914
  this.mm010 = this.vox2mm([-0.5, header.dims[2] - 0.5, -0.5], rotM);
10574
10915
  this.mm001 = this.vox2mm([-0.5, -0.5, header.dims[3] - 0.5], rotM);
10575
10916
  let R2 = create$2();
10576
- copy(R2, rotM);
10917
+ copy$1(R2, rotM);
10577
10918
  for (let i = 0; i < 3; i++) {
10578
10919
  for (let j = 0; j < 3; j++) {
10579
10920
  R2[i * 4 + j] = rotM[i * 4 + perm[j] - 1];
@@ -10603,7 +10944,8 @@ NVImage.prototype.calculateRAS = function() {
10603
10944
  ];
10604
10945
  if (this.arrayEquals(perm, [1, 2, 3]) && this.arrayEquals(flip, [0, 0, 0])) {
10605
10946
  this.toRAS = create$2();
10606
- this.matRAS = clone(rotM);
10947
+ this.matRAS = clone$1(rotM);
10948
+ this.calculateOblique();
10607
10949
  return;
10608
10950
  }
10609
10951
  identity$1(rotM);
@@ -10616,7 +10958,7 @@ NVImage.prototype.calculateRAS = function() {
10616
10958
  let residualR = create$2();
10617
10959
  invert(residualR, rotM);
10618
10960
  multiply$1(residualR, residualR, R2);
10619
- this.matRAS = clone(residualR);
10961
+ this.matRAS = clone$1(residualR);
10620
10962
  rotM = fromValues$2(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
10621
10963
  rotM[perm[0] - 1 + 0 * 4] = -flip[0] * 2 + 1;
10622
10964
  rotM[perm[1] - 1 + 1 * 4] = -flip[1] * 2 + 1;
@@ -10624,12 +10966,13 @@ NVImage.prototype.calculateRAS = function() {
10624
10966
  rotM[3 + 0 * 4] = flip[0];
10625
10967
  rotM[3 + 1 * 4] = flip[1];
10626
10968
  rotM[3 + 2 * 4] = flip[2];
10627
- this.toRAS = clone(rotM);
10628
- console.log(this.hdr.dims);
10629
- console.log(this.dimsRAS);
10969
+ this.toRAS = clone$1(rotM);
10970
+ log$1.debug(this.hdr.dims);
10971
+ log$1.debug(this.dimsRAS);
10972
+ this.calculateOblique();
10630
10973
  };
10631
10974
  NVImage.prototype.vox2mm = function(XYZ, mtx) {
10632
- let sform = clone(mtx);
10975
+ let sform = clone$1(mtx);
10633
10976
  transpose(sform, sform);
10634
10977
  let pos = fromValues(XYZ[0], XYZ[1], XYZ[2], 1);
10635
10978
  transformMat4(pos, pos, sform);
@@ -10638,7 +10981,7 @@ NVImage.prototype.vox2mm = function(XYZ, mtx) {
10638
10981
  };
10639
10982
  NVImage.prototype.mm2vox = function(mm) {
10640
10983
  let sform = fromValues$2(...this.hdr.affine.flat());
10641
- let out = clone(sform);
10984
+ let out = clone$1(sform);
10642
10985
  transpose(out, sform);
10643
10986
  invert(out, out);
10644
10987
  let pos = fromValues(mm[0], mm[1], mm[2], 1);
@@ -10660,6 +11003,8 @@ NVImage.prototype.calMinMax = function() {
10660
11003
  if (this.trustCalMinMax && isFinite(this.hdr.cal_min) && isFinite(this.hdr.cal_max) && this.hdr.cal_max > this.hdr.cal_min) {
10661
11004
  this.cal_min = this.hdr.cal_min;
10662
11005
  this.cal_max = this.hdr.cal_max;
11006
+ this.robust_min = this.cal_min;
11007
+ this.robust_max = this.cal_max;
10663
11008
  this.global_min = this.hdr.cal_min;
10664
11009
  this.global_max = this.hdr.cal_max;
10665
11010
  return [
@@ -10680,6 +11025,8 @@ NVImage.prototype.calMinMax = function() {
10680
11025
  if (cmMin != cmMax) {
10681
11026
  this.cal_min = cmMin;
10682
11027
  this.cal_max = cmMax;
11028
+ this.robust_min = this.cal_min;
11029
+ this.robust_max = this.cal_max;
10683
11030
  return [cmMin, cmMax, cmMin, cmMax];
10684
11031
  }
10685
11032
  let mn = this.img[0];
@@ -10708,9 +11055,11 @@ NVImage.prototype.calMinMax = function() {
10708
11055
  nZero += nNan;
10709
11056
  let n2pct = Math.round((nVox - nZero) * this.percentileFrac);
10710
11057
  if (n2pct < 1 || mn === mx) {
10711
- console.log("no variability in image intensity?");
11058
+ log$1.debug("no variability in image intensity?");
10712
11059
  this.cal_min = mnScale;
10713
11060
  this.cal_max = mxScale;
11061
+ this.robust_min = this.cal_min;
11062
+ this.robust_max = this.cal_max;
10714
11063
  this.global_min = mnScale;
10715
11064
  this.global_max = mxScale;
10716
11065
  return [mnScale, mxScale, mnScale, mxScale];
@@ -10775,6 +11124,8 @@ NVImage.prototype.calMinMax = function() {
10775
11124
  }
10776
11125
  this.cal_min = pct2;
10777
11126
  this.cal_max = pct98;
11127
+ this.robust_min = this.cal_min;
11128
+ this.robust_max = this.cal_max;
10778
11129
  this.global_min = mnScale;
10779
11130
  this.global_max = mxScale;
10780
11131
  return [pct2, pct98, mnScale, mxScale];
@@ -10816,7 +11167,7 @@ NVImage.loadFromFile = async function(file, name = "", colorMap = "gray", opacit
10816
11167
  let dataBuffer = await this.readFileAsync(file);
10817
11168
  nvimage = new NVImage(dataBuffer, name, colorMap, opacity, trustCalMinMax, percentileFrac, ignoreZeroVoxels, visible);
10818
11169
  } catch (err2) {
10819
- console.log(err2);
11170
+ log$1.debug(err2);
10820
11171
  }
10821
11172
  return nvimage;
10822
11173
  };
@@ -10882,138 +11233,69 @@ NVImage.prototype.getValue = function(x, y, z) {
10882
11233
  let vx = 3 * (x + y * nx + z * nx * ny);
10883
11234
  return Math.round(this.img[vx] * 0.21 + this.img[vx + 1] * 0.72 + this.img[vx + 2] * 0.07);
10884
11235
  }
10885
- return this.img[x + y * nx + z * nx * ny];
11236
+ let i = this.img[x + y * nx + z * nx * ny];
11237
+ return this.hdr.scl_slope * i + this.hdr.scl_inter;
10886
11238
  };
10887
- function getExtents(positions) {
10888
- const min2 = positions.slice(0, 3);
10889
- const max2 = positions.slice(0, 3);
11239
+ function getExtents(positions, forceOriginInVolume = true) {
11240
+ let nV = (positions.length / 3).toFixed();
11241
+ let origin = fromValues$1(0, 0, 0);
11242
+ let mn = create$1();
11243
+ let mx = create$1();
10890
11244
  let mxDx = 0;
10891
- for (let i = 3; i < positions.length; i += 3) {
11245
+ let nLoops = 1;
11246
+ if (forceOriginInVolume)
11247
+ nLoops = 2;
11248
+ for (let loop = 0; loop < nLoops; loop++) {
11249
+ mxDx = 0;
11250
+ for (let i = 0; i < nV; i++) {
11251
+ let v = fromValues$1(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
11252
+ if (i === 0) {
11253
+ copy(mn, v);
11254
+ copy(mx, v);
11255
+ }
11256
+ min$Q(mn, mn, v);
11257
+ max$Q(mx, mx, v);
11258
+ subtract(v, v, origin);
11259
+ let dx = len(v);
11260
+ mxDx = Math.max(mxDx, dx);
11261
+ }
11262
+ if (loop + 1 >= nLoops)
11263
+ break;
11264
+ let ok = true;
10892
11265
  for (let j = 0; j < 3; ++j) {
10893
- const v = positions[i + j];
10894
- min2[j] = Math.min(v, min2[j]);
10895
- max2[j] = Math.max(v, max2[j]);
11266
+ if (mn[j] > origin[j])
11267
+ ok = false;
11268
+ if (mx[j] < origin[j])
11269
+ ok = false;
10896
11270
  }
10897
- let dx = positions[i] * positions[i] + positions[i + 1] * positions[i + 1] + positions[i + 2] * positions[i + 2];
10898
- mxDx = Math.max(mxDx, dx);
11271
+ if (ok)
11272
+ break;
11273
+ lerp(origin, mn, mx, 0.5);
11274
+ log$1.debug("origin moved inside volume: ", origin);
10899
11275
  }
10900
- let furthestVertexFromOrigin = Math.sqrt(mxDx);
10901
- return { min: min2, max: max2, furthestVertexFromOrigin };
11276
+ let min2 = [mn[0], mn[1], mn[2]];
11277
+ let max2 = [mx[0], mx[1], mx[2]];
11278
+ let furthestVertexFromOrigin = mxDx;
11279
+ return { min: min2, max: max2, furthestVertexFromOrigin, origin };
10902
11280
  }
10903
- NVImage.prototype.method1 = function() {
10904
- return {
10905
- left: -(this.dimsRAS[1] / 2) * this.pixDimsRAS[1],
10906
- right: this.dimsRAS[1] / 2 * this.pixDimsRAS[1],
10907
- posterior: -(this.dimsRAS[2] / 2) * this.pixDimsRAS[2],
10908
- anterior: this.dimsRAS[2] / 2 * this.pixDimsRAS[2],
10909
- inferior: -(this.dimsRAS[3] / 2) * this.pixDimsRAS[3],
10910
- superior: this.dimsRAS[3] / 2 * this.pixDimsRAS[3]
10911
- };
10912
- };
10913
- NVImage.prototype.method2 = function() {
10914
- const affine = [];
10915
- for (let i = 0; i < 4; i++) {
10916
- for (let j = 0; j < 4; j++) {
10917
- affine.push(this.hdr.affine[i][j]);
10918
- }
10919
- }
10920
- const affineMatrix = fromValues$2(...affine);
10921
- const qfac = this.hdr.dims[0] ? this.hdr.pixDims[0] : 1;
10922
- let rightTopFront = fromValues(this.hdr.dims[1] * this.hdr.pixDims[1], this.hdr.dims[2] * this.hdr.pixDims[2], qfac * this.hdr.dims[3] * this.hdr.pixDims[3], 1);
10923
- let maxExtent = create();
10924
- transformMat4(maxExtent, rightTopFront, affineMatrix);
10925
- return {
10926
- left: maxExtent[0] / 2,
10927
- right: 0 - maxExtent[0] / 2,
10928
- posterior: 0 - maxExtent[1] / 2,
10929
- anterior: maxExtent[1] / 2,
10930
- inferior: 0 - maxExtent[2] / 2,
10931
- superior: maxExtent[2] / 2
10932
- };
10933
- };
10934
- NVImage.prototype.method3 = function() {
10935
- };
10936
11281
  NVImage.prototype.toNiivueObject3D = function(id, gl) {
10937
- let cuboid = this.method1();
10938
- let left = cuboid.left;
10939
- let right = cuboid.right;
10940
- let posterior = cuboid.posterior;
10941
- let anterior = cuboid.anterior;
10942
- let inferior = cuboid.inferior;
10943
- let superior = cuboid.superior;
11282
+ let LPI = this.vox2mm([0, 0, 0], this.matRAS);
11283
+ let LAI = this.vox2mm([0, this.dimsRAS[2] - 1, 0], this.matRAS);
11284
+ let LPS = this.vox2mm([0, 0, this.dimsRAS[3] - 1], this.matRAS);
11285
+ let LAS = this.vox2mm([0, this.dimsRAS[2] - 1, this.dimsRAS[3] - 1], this.matRAS);
11286
+ let RPI = this.vox2mm([this.dimsRAS[1] - 1, 0, 0], this.matRAS);
11287
+ let RAI = this.vox2mm([this.dimsRAS[1] - 1, this.dimsRAS[2] - 1, 0], this.matRAS);
11288
+ let RPS = this.vox2mm([this.dimsRAS[1] - 1, 0, this.dimsRAS[3] - 1], this.matRAS);
11289
+ let RAS = this.vox2mm([this.dimsRAS[1] - 1, this.dimsRAS[2] - 1, this.dimsRAS[3] - 1], this.matRAS);
10944
11290
  const positions = [
10945
- left,
10946
- posterior,
10947
- superior,
10948
- right,
10949
- posterior,
10950
- superior,
10951
- right,
10952
- anterior,
10953
- superior,
10954
- left,
10955
- anterior,
10956
- superior,
10957
- left,
10958
- posterior,
10959
- inferior,
10960
- left,
10961
- anterior,
10962
- inferior,
10963
- right,
10964
- anterior,
10965
- inferior,
10966
- right,
10967
- posterior,
10968
- inferior,
10969
- left,
10970
- anterior,
10971
- inferior,
10972
- left,
10973
- anterior,
10974
- superior,
10975
- right,
10976
- anterior,
10977
- superior,
10978
- right,
10979
- anterior,
10980
- inferior,
10981
- left,
10982
- posterior,
10983
- inferior,
10984
- right,
10985
- posterior,
10986
- inferior,
10987
- right,
10988
- posterior,
10989
- superior,
10990
- left,
10991
- posterior,
10992
- superior,
10993
- right,
10994
- posterior,
10995
- inferior,
10996
- right,
10997
- anterior,
10998
- inferior,
10999
- right,
11000
- anterior,
11001
- superior,
11002
- right,
11003
- posterior,
11004
- superior,
11005
- left,
11006
- posterior,
11007
- inferior,
11008
- left,
11009
- posterior,
11010
- superior,
11011
- left,
11012
- anterior,
11013
- superior,
11014
- left,
11015
- anterior,
11016
- inferior
11291
+ ...LPS,
11292
+ ...RPS,
11293
+ ...RAS,
11294
+ ...LAS,
11295
+ ...LPI,
11296
+ ...LAI,
11297
+ ...RAI,
11298
+ ...RPI
11017
11299
  ];
11018
11300
  const textureCoordinates = [
11019
11301
  0,
@@ -11107,30 +11389,30 @@ NVImage.prototype.toNiivueObject3D = function(id, gl) {
11107
11389
  6,
11108
11390
  5,
11109
11391
  4,
11110
- 8,
11111
- 11,
11112
- 10,
11113
- 10,
11114
- 9,
11115
- 8,
11116
- 12,
11117
- 15,
11118
- 14,
11119
- 14,
11120
- 13,
11121
- 12,
11122
- 16,
11123
- 19,
11124
- 18,
11125
- 18,
11126
- 17,
11127
- 16,
11128
- 20,
11129
- 23,
11130
- 22,
11131
- 22,
11132
- 21,
11133
- 20
11392
+ 5,
11393
+ 6,
11394
+ 2,
11395
+ 2,
11396
+ 3,
11397
+ 5,
11398
+ 4,
11399
+ 0,
11400
+ 1,
11401
+ 1,
11402
+ 7,
11403
+ 4,
11404
+ 7,
11405
+ 1,
11406
+ 2,
11407
+ 2,
11408
+ 6,
11409
+ 7,
11410
+ 4,
11411
+ 5,
11412
+ 3,
11413
+ 3,
11414
+ 0,
11415
+ 4
11134
11416
  ];
11135
11417
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
11136
11418
  const textureCoordBuffer = gl.createBuffer();
@@ -11141,40 +11423,10 @@ NVImage.prototype.toNiivueObject3D = function(id, gl) {
11141
11423
  obj3D.extentsMin = extents.min;
11142
11424
  obj3D.extentsMax = extents.max;
11143
11425
  obj3D.furthestVertexFromOrigin = extents.furthestVertexFromOrigin;
11426
+ obj3D.originNegate = clone(extents.origin);
11427
+ negate(obj3D.originNegate, obj3D.originNegate);
11144
11428
  return obj3D;
11145
11429
  };
11146
- const Log = function(logLevel) {
11147
- this.LOGGING_ON = true;
11148
- this.LOGGING_OFF = false;
11149
- this.LOG_PREFIX = "NiiVue:";
11150
- this.logLevel = logLevel;
11151
- };
11152
- Log.prototype.getTimeStamp = function() {
11153
- return `${this.LOG_PREFIX} `;
11154
- };
11155
- Log.prototype.debug = function() {
11156
- if (this.logLevel === this.LOGGING_ON) {
11157
- console.log(this.getTimeStamp(), "DEBUG", ...arguments);
11158
- }
11159
- };
11160
- Log.prototype.info = function() {
11161
- if (this.logLevel === this.LOGGING_ON) {
11162
- console.log(this.getTimeStamp(), "INFO", ...arguments);
11163
- }
11164
- };
11165
- Log.prototype.warn = function() {
11166
- if (this.logLevel === this.LOGGING_ON) {
11167
- console.warn(this.getTimeStamp(), "WARN", ...arguments);
11168
- }
11169
- };
11170
- Log.prototype.error = function() {
11171
- if (this.logLevel === this.LOGGING_ON) {
11172
- console.error(this.getTimeStamp(), "ERROR", ...arguments);
11173
- }
11174
- };
11175
- Log.prototype.setLogLevel = function(logLevel) {
11176
- this.logLevel = logLevel;
11177
- };
11178
11430
  var defaultFontPNG = "data:image/png;base64,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";
11179
11431
  const atlas = {
11180
11432
  type: "msdf",
@@ -12713,20 +12965,25 @@ const log = new Log();
12713
12965
  const Niivue = function(options = {}) {
12714
12966
  this.opts = {};
12715
12967
  this.defaults = {
12716
- textHeight: 0.03,
12968
+ textHeight: 0.06,
12717
12969
  colorbarHeight: 0.05,
12718
12970
  crosshairWidth: 1,
12971
+ show3Dcrosshair: false,
12719
12972
  backColor: [0, 0, 0, 1],
12720
12973
  crosshairColor: [1, 0, 0, 1],
12721
12974
  selectionBoxColor: [1, 1, 1, 0.5],
12722
- clipPlaneColor: [1, 1, 1, 0.5],
12975
+ clipPlaneColor: [0.7, 0, 0.7, 0.5],
12723
12976
  colorBarMargin: 0.05,
12724
12977
  trustCalMinMax: true,
12725
12978
  clipPlaneHotKey: "KeyC",
12726
12979
  viewModeHotKey: "KeyV",
12727
12980
  keyDebounceTime: 50,
12981
+ isNearestInterpolation: false,
12982
+ isAtlasOutline: false,
12728
12983
  isRadiologicalConvention: false,
12729
- logging: false
12984
+ logging: false,
12985
+ loadingText: "waiting for images...",
12986
+ dragAndDropEnabled: true
12730
12987
  };
12731
12988
  this.canvas = null;
12732
12989
  this.gl = null;
@@ -12736,14 +12993,17 @@ const Niivue = function(options = {}) {
12736
12993
  this.sliceShader = null;
12737
12994
  this.lineShader = null;
12738
12995
  this.renderShader = null;
12996
+ this.pickingShader = null;
12739
12997
  this.colorbarShader = null;
12740
12998
  this.fontShader = null;
12741
12999
  this.passThroughShader = null;
13000
+ this.orientShaderAtlasU = null;
12742
13001
  this.orientShaderU = null;
12743
13002
  this.orientShaderI = null;
12744
13003
  this.orientShaderF = null;
12745
13004
  this.orientShaderRGBU = null;
12746
13005
  this.surfaceShader = null;
13006
+ this.crosshairs3D = null;
12747
13007
  this.pickingSurfaceShader = null;
12748
13008
  this.DEFAULT_FONT_GLYPH_SHEET = defaultFontPNG;
12749
13009
  this.DEFAULT_FONT_METRICS = defaultFontMetrics;
@@ -12755,16 +13015,19 @@ const Niivue = function(options = {}) {
12755
13015
  this.sliceTypeRender = 4;
12756
13016
  this.sliceType = this.sliceTypeMultiplanar;
12757
13017
  this.scene = {};
13018
+ this.syncOpts = {};
12758
13019
  this.scene.renderAzimuth = 110;
12759
- this.scene.renderElevation = 15;
13020
+ this.scene.renderElevation = 10;
12760
13021
  this.scene.crosshairPos = [0.5, 0.5, 0.5];
12761
13022
  this.scene.clipPlane = [0, 0, 0, 0];
13023
+ this.scene.clipPlaneDepthAziElev = [2, 0, 0];
12762
13024
  this.scene.mousedown = false;
12763
13025
  this.scene.touchdown = false;
12764
13026
  this.scene.mouseButtonLeft = 0;
12765
13027
  this.scene.mouseButtonRight = 2;
12766
13028
  this.scene.mouseButtonLeftDown = false;
12767
13029
  this.scene.mouseButtonRightDown = false;
13030
+ this.scene.mouseDepthPicker = false;
12768
13031
  this.scene.prevX = 0;
12769
13032
  this.scene.prevY = 0;
12770
13033
  this.scene.currX = 0;
@@ -12785,30 +13048,29 @@ const Niivue = function(options = {}) {
12785
13048
  { leftTopWidthHeight: [1, 0, 0, 1], axCorSag: this.sliceTypeAxial },
12786
13049
  { leftTopWidthHeight: [1, 0, 0, 1], axCorSag: this.sliceTypeAxial }
12787
13050
  ];
12788
- this.backOpacity = 1;
12789
13051
  this.isDragging = false;
12790
13052
  this.dragStart = [0, 0];
12791
13053
  this.dragEnd = [0, 0];
13054
+ this.dragClipPlaneStartDepthAziElev = [0, 0, 0];
12792
13055
  this.lastTwoTouchDistance = 0;
12793
13056
  this.otherNV = null;
12794
13057
  this.volumeObject3D = null;
12795
- this.clipPlaneObject3D = null;
12796
13058
  this.intensityRange$ = new Subject();
12797
13059
  this.scene.location$ = new Subject();
12798
13060
  this.scene.loading$ = new Subject();
12799
- this.loadingText = "waiting for images...";
12800
13061
  this.currentClipPlaneIndex = 0;
12801
13062
  this.lastCalled = new Date().getTime();
12802
13063
  this.multiTouchGesture = false;
12803
13064
  this.gestureInterval = null;
12804
13065
  this.selectedObjectId = -1;
12805
13066
  this.CLIP_PLANE_ID = 1;
12806
- this.VOLUME_ID = 2;
13067
+ this.VOLUME_ID = 254;
12807
13068
  this.DISTANCE_FROM_CAMERA = -0.54;
12808
13069
  this.initialized = false;
12809
13070
  for (let prop in this.defaults) {
12810
13071
  this.opts[prop] = options[prop] === void 0 ? this.defaults[prop] : options[prop];
12811
13072
  }
13073
+ this.loadingText = this.opts.loadingText;
12812
13074
  log.setLogLevel(this.opts.logging);
12813
13075
  this.eventsToSubjects = {
12814
13076
  location: this.scene.location$,
@@ -12852,7 +13114,7 @@ Niivue.prototype.attachToCanvas = async function(canvas) {
12852
13114
  this.gl = this.canvas.getContext("webgl2");
12853
13115
  if (!this.gl) {
12854
13116
  alert("unable to get webgl2 context. Perhaps this browser does not support webgl2");
12855
- console.log("unable to get webgl2 context. Perhaps this browser does not support webgl2");
13117
+ log.warn("unable to get webgl2 context. Perhaps this browser does not support webgl2");
12856
13118
  }
12857
13119
  this.canvas.parentElement.style.backgroundColor = "black";
12858
13120
  this.canvas.style.width = "100%";
@@ -12865,17 +13127,22 @@ Niivue.prototype.attachToCanvas = async function(canvas) {
12865
13127
  this.drawScene();
12866
13128
  return this;
12867
13129
  };
12868
- Niivue.prototype.syncWith = function(otherNV) {
13130
+ Niivue.prototype.syncWith = function(otherNV, syncOpts = { "2d": true, "3d": true }) {
12869
13131
  this.otherNV = otherNV;
13132
+ this.syncOpts = syncOpts;
12870
13133
  };
12871
13134
  Niivue.prototype.sync = function() {
12872
13135
  if (!this.otherNV || typeof this.otherNV === "undefined") {
12873
13136
  return;
12874
13137
  }
12875
13138
  let thisMM = this.frac2mm(this.scene.crosshairPos);
12876
- this.otherNV.scene.crosshairPos = this.otherNV.mm2frac(thisMM);
12877
- this.otherNV.scene.renderAzimuth = this.scene.renderAzimuth;
12878
- this.otherNV.scene.renderElevation = this.scene.renderElevation;
13139
+ if (this.syncOpts["2d"]) {
13140
+ this.otherNV.scene.crosshairPos = this.otherNV.mm2frac(thisMM);
13141
+ }
13142
+ if (this.syncOpts["3d"]) {
13143
+ this.otherNV.scene.renderAzimuth = this.scene.renderAzimuth;
13144
+ this.otherNV.scene.renderElevation = this.scene.renderElevation;
13145
+ }
12879
13146
  this.otherNV.drawScene();
12880
13147
  };
12881
13148
  Niivue.prototype.arrayEquals = function(a, b) {
@@ -12927,6 +13194,7 @@ Niivue.prototype.mouseRightButtonHandler = function(e) {
12927
13194
  let pos = this.getNoPaddingNoBorderCanvasRelativeMousePosition(e, this.gl.canvas);
12928
13195
  this.dragStart[0] = pos.x;
12929
13196
  this.dragStart[1] = pos.y;
13197
+ this.dragClipPlaneStartDepthAziElev = this.scene.clipPlaneDepthAziElev;
12930
13198
  return;
12931
13199
  };
12932
13200
  Niivue.prototype.calculateMinMaxVoxIdx = function(array) {
@@ -12998,8 +13266,8 @@ Niivue.prototype.mouseUpListener = function() {
12998
13266
  this.isDragging = false;
12999
13267
  this.calculateNewRange();
13000
13268
  this.refreshLayers(this.volumes[0], 0, this.volumes.length);
13001
- this.drawScene();
13002
13269
  }
13270
+ this.drawScene();
13003
13271
  };
13004
13272
  Niivue.prototype.checkMultitouch = function(e) {
13005
13273
  if (this.scene.touchdown && !this.multiTouchGesture) {
@@ -13039,8 +13307,13 @@ Niivue.prototype.mouseMoveListener = function(e) {
13039
13307
  }
13040
13308
  };
13041
13309
  Niivue.prototype.resetBriCon = function() {
13042
- this.volumes[0].cal_min = this.volumes[0].global_min;
13043
- this.volumes[0].cal_max = this.volumes[0].global_max;
13310
+ if (this.sliceType === this.sliceTypeRender) {
13311
+ this.scene.mouseDepthPicker = true;
13312
+ this.drawScene();
13313
+ return;
13314
+ }
13315
+ this.volumes[0].cal_min = this.volumes[0].robust_min;
13316
+ this.volumes[0].cal_max = this.volumes[0].robust_max;
13044
13317
  this.refreshLayers(this.volumes[0], 0, this.volumes.length);
13045
13318
  this.drawScene();
13046
13319
  };
@@ -13077,27 +13350,31 @@ Niivue.prototype.keyUpListener = function(e) {
13077
13350
  let now = new Date().getTime();
13078
13351
  let elapsed = now - this.lastCalled;
13079
13352
  if (elapsed > this.opts.keyDebounceTime) {
13080
- this.currentClipPlaneIndex = (this.currentClipPlaneIndex + 1) % 4;
13081
- this.clipPlaneObject3D.isVisible = this.currentClipPlaneIndex;
13353
+ this.currentClipPlaneIndex = (this.currentClipPlaneIndex + 1) % 7;
13082
13354
  switch (this.currentClipPlaneIndex) {
13083
13355
  case 0:
13084
- this.scene.clipPlane = [0, 0, 0, 0];
13085
- this.clipPlaneObject3D.rotation = [0, 0, 0];
13356
+ this.scene.clipPlaneDepthAziElev = [2, 0, 0];
13086
13357
  break;
13087
13358
  case 1:
13088
- this.scene.clipPlane = [1, 0, 0, 0];
13089
- this.clipPlaneObject3D.rotation = [0, 1, 0];
13359
+ this.scene.clipPlaneDepthAziElev = [0, 270, 0];
13090
13360
  break;
13091
13361
  case 2:
13092
- this.scene.clipPlane = [0, 1, 0, 0];
13093
- this.clipPlaneObject3D.rotation = [1, 0, 0];
13362
+ this.scene.clipPlaneDepthAziElev = [0, 90, 0];
13094
13363
  break;
13095
13364
  case 3:
13096
- this.scene.clipPlane = [0, 0, 1, 0];
13097
- this.clipPlaneObject3D.rotation = [0, 0, 1];
13365
+ this.scene.clipPlaneDepthAziElev = [0, 0, 0];
13366
+ break;
13367
+ case 4:
13368
+ this.scene.clipPlaneDepthAziElev = [0, 180, 0];
13369
+ break;
13370
+ case 5:
13371
+ this.scene.clipPlaneDepthAziElev = [0, 0, -90];
13372
+ break;
13373
+ case 6:
13374
+ this.scene.clipPlaneDepthAziElev = [0, 0, 90];
13098
13375
  break;
13099
13376
  }
13100
- this.drawScene();
13377
+ this.clipPlaneUpdate(this.scene.clipPlaneDepthAziElev);
13101
13378
  }
13102
13379
  this.lastCalled = now;
13103
13380
  } else if (e.code === this.opts.viewModeHotKey) {
@@ -13147,6 +13424,9 @@ Niivue.prototype.dragOverListener = function(e) {
13147
13424
  Niivue.prototype.dropListener = async function(e) {
13148
13425
  e.stopPropagation();
13149
13426
  e.preventDefault();
13427
+ if (!this.opts.dragAndDropEnabled) {
13428
+ return;
13429
+ }
13150
13430
  const dt = e.dataTransfer;
13151
13431
  const url = dt.getData("text/uri-list");
13152
13432
  if (url) {
@@ -13169,13 +13449,9 @@ Niivue.prototype.getRadiologicalConvention = function() {
13169
13449
  return this.opts.isRadiologicalConvention;
13170
13450
  };
13171
13451
  Niivue.prototype.addVolume = function(volume) {
13172
- if (this.volumes.length > 1) {
13173
- this.overlays.push(volume);
13174
- } else {
13175
- this.back = volume;
13176
- }
13177
13452
  this.volumes.push(volume);
13178
- this.updateGLVolume();
13453
+ let idx = this.volumes.length === 1 ? 1 : this.volumes.length - 1;
13454
+ this.setVolume(volume, idx);
13179
13455
  };
13180
13456
  Niivue.prototype.getVolumeIndexByID = function(id) {
13181
13457
  let n = this.volumes.length;
@@ -13268,19 +13544,19 @@ Niivue.prototype.sph2cartDeg = function sph2cartDeg(azimuth, elevation) {
13268
13544
  Math.cos(Phi) * Math.sin(Theta),
13269
13545
  Math.sin(Phi)
13270
13546
  ];
13271
- let len = Math.sqrt(ret[0] * ret[0] + ret[1] * ret[1] + ret[2] * ret[2]);
13272
- if (len <= 0)
13547
+ let len2 = Math.sqrt(ret[0] * ret[0] + ret[1] * ret[1] + ret[2] * ret[2]);
13548
+ if (len2 <= 0)
13273
13549
  return ret;
13274
- ret[0] /= len;
13275
- ret[1] /= len;
13276
- ret[2] /= len;
13550
+ ret[0] /= len2;
13551
+ ret[1] /= len2;
13552
+ ret[2] /= len2;
13277
13553
  return ret;
13278
13554
  };
13279
- Niivue.prototype.clipPlaneUpdate = function(azimuthElevation) {
13555
+ Niivue.prototype.clipPlaneUpdate = function(depthAzimuthElevation) {
13280
13556
  if (this.sliceType != this.sliceTypeRender)
13281
13557
  return;
13282
- let v = this.sph2cartDeg(azimuthElevation[0], azimuthElevation[1]);
13283
- this.scene.clipPlane = [v[0], v[1], v[2], azimuthElevation[2]];
13558
+ let v = this.sph2cartDeg(depthAzimuthElevation[1] + 180, depthAzimuthElevation[2]);
13559
+ this.scene.clipPlane = [v[0], v[1], v[2], depthAzimuthElevation[0]];
13284
13560
  this.drawScene();
13285
13561
  };
13286
13562
  Niivue.prototype.setCrosshairColor = function(color) {
@@ -13301,7 +13577,6 @@ Niivue.prototype.setSliceType = function(st) {
13301
13577
  Niivue.prototype.setOpacity = function(volIdx, newOpacity) {
13302
13578
  this.volumes[volIdx].opacity = newOpacity;
13303
13579
  if (volIdx === 0) {
13304
- this.backOpacity = newOpacity;
13305
13580
  this.drawScene();
13306
13581
  return;
13307
13582
  }
@@ -13344,7 +13619,7 @@ Niivue.prototype.overlayRGBA = function(volume) {
13344
13619
  return imgRGBA;
13345
13620
  };
13346
13621
  Niivue.prototype.vox2mm = function(XYZ, mtx) {
13347
- let sform = clone(mtx);
13622
+ let sform = clone$1(mtx);
13348
13623
  transpose(sform, sform);
13349
13624
  let pos = fromValues(XYZ[0], XYZ[1], XYZ[2], 1);
13350
13625
  transformMat4(pos, pos, sform);
@@ -13360,7 +13635,7 @@ Niivue.prototype.loadVolumes = async function(volumeList) {
13360
13635
  this.loadingText = "loading...";
13361
13636
  this.drawScene();
13362
13637
  } else {
13363
- this.loadingText = "waiting for images...";
13638
+ this.loadingText = this.opts.loadingText;
13364
13639
  }
13365
13640
  });
13366
13641
  if (!this.initialized)
@@ -13368,8 +13643,9 @@ Niivue.prototype.loadVolumes = async function(volumeList) {
13368
13643
  this.volumes = [];
13369
13644
  this.gl.clearColor(0, 0, 0, 1);
13370
13645
  this.gl.clear(this.gl.COLOR_BUFFER_BIT);
13371
- this.scene.loading$.next(true);
13646
+ this.scene.loading$.next(false);
13372
13647
  for (let i = 0; i < volumeList.length; i++) {
13648
+ this.scene.loading$.next(true);
13373
13649
  let volume = await NVImage.loadFromUrl(volumeList[i].url, volumeList[i].name, volumeList[i].colorMap, volumeList[i].opacity, this.opts.trustCalMinMax);
13374
13650
  this.scene.loading$.next(false);
13375
13651
  this.volumes.push(volume);
@@ -13524,11 +13800,6 @@ Niivue.prototype.init = async function() {
13524
13800
  this.gl.bufferData(this.gl.ARRAY_BUFFER, clipPlaneVertices, this.gl.STATIC_DRAW);
13525
13801
  this.gl.enableVertexAttribArray(0);
13526
13802
  this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);
13527
- this.clipPlaneObject3D = new NiivueObject3D(this.CLIP_PLANE_ID, vertexBuffer, this.gl.TRIANGLES, 6);
13528
- this.clipPlaneObject3D.position = [0, 0, this.DISTANCE_FROM_CAMERA];
13529
- this.clipPlaneObject3D.isVisible = false;
13530
- this.clipPlaneObject3D.rotationRadians = Math.PI / 2;
13531
- this.objectsToRender3D.push(this.clipPlaneObject3D);
13532
13803
  let cubeStrip = [
13533
13804
  0,
13534
13805
  1,
@@ -13584,7 +13855,7 @@ Niivue.prototype.init = async function() {
13584
13855
  this.volumeObject3D = new NiivueObject3D(this.VOLUME_ID, vbo, this.gl.TRIANGLE_STRIP, 14);
13585
13856
  this.volumeObject3D.glFlags = this.volumeObject3D.BLEND | this.volumeObject3D.CULL_FACE | this.volumeObject3D.CULL_FRONT;
13586
13857
  this.volumeObject3D.position = [0, 0, this.DISTANCE_FROM_CAMERA];
13587
- let pickingShader = new Shader(this.gl, vertVolumePickingShader, fragVolumePickingShader);
13858
+ let pickingShader = new Shader(this.gl, vertRenderShader, fragVolumePickingShader);
13588
13859
  pickingShader.use(this.gl);
13589
13860
  this.gl.uniform1i(pickingShader.uniforms["volume"], 0);
13590
13861
  this.gl.uniform1i(pickingShader.uniforms["colormap"], 1);
@@ -13605,8 +13876,10 @@ Niivue.prototype.init = async function() {
13605
13876
  this.gl.uniform1i(this.renderShader.uniforms["volume"], 0);
13606
13877
  this.gl.uniform1i(this.renderShader.uniforms["colormap"], 1);
13607
13878
  this.gl.uniform1i(this.renderShader.uniforms["overlay"], 2);
13879
+ this.pickingShader = new Shader(this.gl, vertRenderShader, fragVolumePickingShader);
13608
13880
  let volumeRenderShader = new NiivueShader3D(this.renderShader);
13609
13881
  volumeRenderShader.mvpUniformName = "mvpMtx";
13882
+ volumeRenderShader.matRASUniformName = "matRAS";
13610
13883
  volumeRenderShader.rayDirUniformName = "rayDir";
13611
13884
  volumeRenderShader.clipPlaneUniformName = "clipPlane";
13612
13885
  this.volumeObject3D.renderShaders.push(volumeRenderShader);
@@ -13614,17 +13887,17 @@ Niivue.prototype.init = async function() {
13614
13887
  this.colorbarShader.use(this.gl);
13615
13888
  this.gl.uniform1i(this.colorbarShader.uniforms["colormap"], 1);
13616
13889
  this.passThroughShader = new Shader(this.gl, vertPassThroughShader, fragPassThroughShader);
13890
+ this.orientShaderAtlasU = new Shader(this.gl, vertOrientShader, fragOrientShaderU.concat(fragOrientShaderAtlas));
13617
13891
  this.orientShaderU = new Shader(this.gl, vertOrientShader, fragOrientShaderU.concat(fragOrientShader));
13618
13892
  this.orientShaderI = new Shader(this.gl, vertOrientShader, fragOrientShaderI.concat(fragOrientShader));
13619
13893
  this.orientShaderF = new Shader(this.gl, vertOrientShader, fragOrientShaderF.concat(fragOrientShader));
13620
13894
  this.orientShaderRGBU = new Shader(this.gl, vertOrientShader, fragOrientShaderU.concat(fragRGBOrientShader));
13621
- this.pickingSurfaceShader = new Shader(this.gl, vertDepthPickingShader, fragDepthPickingShader);
13895
+ this.pickingSurfaceShader = new Shader(this.gl, vertRenderShader, fragDepthPickingShader);
13622
13896
  this.surfaceShader = new Shader(this.gl, vertSurfaceShader, fragSurfaceShader);
13623
13897
  this.surfaceShader.use(this.gl);
13624
13898
  this.gl.uniform4fv(this.surfaceShader.uniforms["surfaceColor"], this.opts.clipPlaneColor);
13625
13899
  let clipPlaneShader = new NiivueShader3D(this.surfaceShader);
13626
13900
  clipPlaneShader.mvpUniformName = "mvpMtx";
13627
- this.clipPlaneObject3D.renderShaders.push(clipPlaneShader);
13628
13901
  await this.initText();
13629
13902
  this.updateGLVolume();
13630
13903
  this.initialized = true;
@@ -13649,7 +13922,9 @@ Niivue.prototype.refreshLayers = function(overlayItem, layer, numLayers) {
13649
13922
  let img = overlayItem.img;
13650
13923
  let opacity = overlayItem.opacity;
13651
13924
  let outTexture = null;
13652
- let mtx = clone(overlayItem.toRAS);
13925
+ if (this.crosshairs3D !== null)
13926
+ this.crosshairs3D.mm[0] = NaN;
13927
+ let mtx = clone$1(overlayItem.toRAS);
13653
13928
  if (layer === 0) {
13654
13929
  this.volumeObject3D = overlayItem.toNiivueObject3D(this.VOLUME_ID, this.gl);
13655
13930
  this.volumeObject3D.glFlags = this.volumeObject3D.CULL_FACE;
@@ -13667,11 +13942,12 @@ Niivue.prototype.refreshLayers = function(overlayItem, layer, numLayers) {
13667
13942
  this.renderShader.use(this.gl);
13668
13943
  this.gl.uniform3fv(this.renderShader.uniforms["texVox"], vox2);
13669
13944
  this.gl.uniform3fv(this.renderShader.uniforms["volScale"], volScale2);
13670
- let volumeRenderShader = new NiivueShader3D(this.renderShader);
13945
+ let volumeRenderShader = this.renderShader;
13946
+ let pickingShader = this.pickingShader;
13671
13947
  volumeRenderShader.mvpUniformName = "mvpMtx";
13948
+ volumeRenderShader.matRASUniformName = "matRAS";
13672
13949
  volumeRenderShader.rayDirUniformName = "rayDir";
13673
13950
  volumeRenderShader.clipPlaneUniformName = "clipPlane";
13674
- let pickingShader = new Shader(this.gl, vertVolumePickingShader, fragVolumePickingShader);
13675
13951
  pickingShader.use(this.gl);
13676
13952
  this.gl.uniform1i(pickingShader.uniforms["volume"], 0);
13677
13953
  this.gl.uniform1i(pickingShader.uniforms["colormap"], 1);
@@ -13680,11 +13956,13 @@ Niivue.prototype.refreshLayers = function(overlayItem, layer, numLayers) {
13680
13956
  pickingShader.rayDirUniformName = "rayDir";
13681
13957
  pickingShader.clipPlaneUniformName = "clipPlane";
13682
13958
  this.gl.uniform3fv(pickingShader.uniforms["volScale"], volScale2);
13683
- this.volumeObject3D.pickingShader = pickingShader;
13959
+ if (this.volumeObject3D.pickingShader === null)
13960
+ this.volumeObject3D.pickingShader = pickingShader;
13684
13961
  this.volumeObject3D.renderShaders.push(volumeRenderShader);
13962
+ log.debug(this.volumeObject3D);
13685
13963
  } else {
13686
13964
  if (this.back.dims === void 0)
13687
- console.log("Fatal error: Unable to render overlay: background dimensions not defined!");
13965
+ log.error("Fatal error: Unable to render overlay: background dimensions not defined!");
13688
13966
  let f000 = this.mm2frac(overlayItem.mm000);
13689
13967
  let f100 = this.mm2frac(overlayItem.mm100);
13690
13968
  let f010 = this.mm2frac(overlayItem.mm010);
@@ -13716,6 +13994,8 @@ Niivue.prototype.refreshLayers = function(overlayItem, layer, numLayers) {
13716
13994
  this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, 1);
13717
13995
  let orientShader = this.orientShaderU;
13718
13996
  if (hdr.datatypeCode === 2) {
13997
+ if (hdr.intent_code === 1002)
13998
+ orientShader = this.orientShaderAtlasU;
13719
13999
  this.gl.texStorage3D(this.gl.TEXTURE_3D, 1, this.gl.R8UI, hdr.dims[1], hdr.dims[2], hdr.dims[3]);
13720
14000
  this.gl.texSubImage3D(this.gl.TEXTURE_3D, 0, 0, 0, 0, hdr.dims[1], hdr.dims[2], hdr.dims[3], this.gl.RED_INTEGER, this.gl.UNSIGNED_BYTE, img);
13721
14001
  } else if (hdr.datatypeCode === 4) {
@@ -13781,6 +14061,16 @@ Niivue.prototype.refreshLayers = function(overlayItem, layer, numLayers) {
13781
14061
  this.gl.uniform1f(orientShader.uniforms["scl_slope"], hdr.scl_slope);
13782
14062
  this.gl.uniform1f(orientShader.uniforms["opacity"], opacity);
13783
14063
  this.gl.uniformMatrix4fv(orientShader.uniforms["mtx"], false, mtx);
14064
+ if (hdr.intent_code === 1002) {
14065
+ let x = 1 / this.back.dims[1];
14066
+ if (!this.opts.isAtlasOutline)
14067
+ x = -x;
14068
+ this.gl.uniform3fv(orientShader.uniforms["xyzFrac"], [
14069
+ x,
14070
+ 1 / this.back.dims[2],
14071
+ 1 / this.back.dims[3]
14072
+ ]);
14073
+ }
13784
14074
  log.debug("back dims: ", this.back.dims);
13785
14075
  for (let i = 0; i < this.back.dims[3]; i++) {
13786
14076
  let coordZ = 1 / this.back.dims[3] * (i + 0.5);
@@ -13799,12 +14089,15 @@ Niivue.prototype.refreshLayers = function(overlayItem, layer, numLayers) {
13799
14089
  let vox = slicescl.vox;
13800
14090
  let volScale = slicescl.volScale;
13801
14091
  this.gl.uniform1f(this.renderShader.uniforms["overlays"], this.overlays);
14092
+ this.gl.uniform4fv(this.renderShader.uniforms["clipPlaneColor"], this.opts.clipPlaneColor);
13802
14093
  this.gl.uniform1f(this.renderShader.uniforms["backOpacity"], this.volumes[0].opacity);
13803
14094
  this.gl.uniform4fv(this.renderShader.uniforms["clipPlane"], this.scene.clipPlane);
13804
14095
  this.gl.uniform3fv(this.renderShader.uniforms["texVox"], vox);
13805
14096
  this.gl.uniform3fv(this.renderShader.uniforms["volScale"], volScale);
13806
14097
  this.volumeObject3D.pickingShader.use(this.gl);
14098
+ this.gl.uniform1f(this.pickingShader.uniforms["overlays"], this.overlays);
13807
14099
  this.gl.uniform3fv(this.volumeObject3D.pickingShader.uniforms["texVox"], vox);
14100
+ this.updateInterpolation(layer);
13808
14101
  };
13809
14102
  Niivue.prototype.colorMaps = function(sort = true) {
13810
14103
  let cm = [];
@@ -13906,6 +14199,18 @@ Niivue.prototype.mouseClick = function(x, y, posChange = 0, isDelta = true) {
13906
14199
  if (this.sliceType === this.sliceTypeRender) {
13907
14200
  if (posChange === 0)
13908
14201
  return;
14202
+ if (this.scene.clipPlaneDepthAziElev[0] < 1.8) {
14203
+ let depthAziElev = this.scene.clipPlaneDepthAziElev.slice();
14204
+ if (posChange > 0)
14205
+ depthAziElev[0] = Math.min(1.5, depthAziElev[0] + 0.025);
14206
+ if (posChange < 0)
14207
+ depthAziElev[0] = Math.max(-1.5, depthAziElev[0] - 0.025);
14208
+ if (depthAziElev[0] !== this.scene.clipPlaneDepthAziElev[0]) {
14209
+ this.scene.clipPlaneDepthAziElev = depthAziElev;
14210
+ return this.clipPlaneUpdate(this.scene.clipPlaneDepthAziElev);
14211
+ }
14212
+ return;
14213
+ }
13909
14214
  if (posChange > 0)
13910
14215
  this.volScaleMultiplier = Math.min(2, this.volScaleMultiplier * 1.1);
13911
14216
  if (posChange < 0)
@@ -14051,7 +14356,7 @@ Niivue.prototype.drawText = function(xy, str, scale = 1) {
14051
14356
  if (this.opts.textHeight <= 0)
14052
14357
  return;
14053
14358
  this.fontShader.use(this.gl);
14054
- let size = this.opts.textHeight * this.gl.canvas.height * scale;
14359
+ let size = this.opts.textHeight * Math.min(this.gl.canvas.height, this.gl.canvas.width) * scale;
14055
14360
  this.gl.enable(this.gl.BLEND);
14056
14361
  this.gl.uniform2f(this.fontShader.uniforms["canvasWidthHeight"], this.gl.canvas.width, this.gl.canvas.height);
14057
14362
  this.gl.uniform4fv(this.fontShader.uniforms["fontColor"], this.opts.crosshairColor);
@@ -14075,6 +14380,33 @@ Niivue.prototype.drawTextBelow = function(xy, str, scale = 1) {
14075
14380
  xy[0] -= 0.5 * this.textWidth(size, str);
14076
14381
  this.drawText(xy, str, scale);
14077
14382
  };
14383
+ Niivue.prototype.updateInterpolation = function(layer) {
14384
+ let interp = this.gl.LINEAR;
14385
+ if (this.opts.isNearestInterpolation)
14386
+ interp = this.gl.NEAREST;
14387
+ if (layer === 0)
14388
+ this.gl.activeTexture(this.gl.TEXTURE0);
14389
+ else
14390
+ this.gl.activeTexture(this.gl.TEXTURE2);
14391
+ this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MIN_FILTER, interp);
14392
+ this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MAG_FILTER, interp);
14393
+ this.volumes.length;
14394
+ };
14395
+ Niivue.prototype.setAtlasOutline = function(isOutline) {
14396
+ this.opts.isAtlasOutline = isOutline;
14397
+ this.updateGLVolume();
14398
+ this.drawScene();
14399
+ };
14400
+ Niivue.prototype.setInterpolation = function(isNearest) {
14401
+ this.opts.isNearestInterpolation = isNearest;
14402
+ let numLayers = this.volumes.length;
14403
+ if (numLayers < 1)
14404
+ return;
14405
+ this.updateInterpolation(0);
14406
+ if (numLayers > 1)
14407
+ this.updateInterpolation(1);
14408
+ this.drawScene();
14409
+ };
14078
14410
  Niivue.prototype.draw2D = function(leftTopWidthHeight, axCorSag) {
14079
14411
  this.gl.cullFace(this.gl.FRONT);
14080
14412
  this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.cuboidVertexBuffer);
@@ -14098,7 +14430,7 @@ Niivue.prototype.draw2D = function(leftTopWidthHeight, axCorSag) {
14098
14430
  ];
14099
14431
  let isMirrorLR = this.opts.isRadiologicalConvention && axCorSag < this.sliceTypeSagittal;
14100
14432
  this.sliceShader.use(this.gl);
14101
- this.gl.uniform1f(this.sliceShader.uniforms["opacity"], this.backOpacity);
14433
+ this.gl.uniform1f(this.sliceShader.uniforms["opacity"], this.volumes[0].opacity);
14102
14434
  this.gl.uniform1i(this.sliceShader.uniforms["axCorSag"], axCorSag);
14103
14435
  this.gl.uniform1f(this.sliceShader.uniforms["slice"], crossXYZ[2]);
14104
14436
  this.gl.uniform2fv(this.sliceShader.uniforms["canvasWidthHeight"], [
@@ -14158,7 +14490,7 @@ Niivue.prototype.calculateMvpMatrix = function(object3D) {
14158
14490
  }
14159
14491
  let whratio = this.gl.canvas.clientWidth / this.gl.canvas.clientHeight;
14160
14492
  let projectionMatrix = create$2();
14161
- let scale = 0.7 * object3D.furthestVertexFromOrigin * 1 / this.volScaleMultiplier;
14493
+ let scale = 0.7 * this.volumeObject3D.furthestVertexFromOrigin * 1 / this.volScaleMultiplier;
14162
14494
  if (whratio < 1)
14163
14495
  ortho(projectionMatrix, -scale, scale, -scale / whratio, scale / whratio, 0.01, scale * 8);
14164
14496
  else
@@ -14167,20 +14499,34 @@ Niivue.prototype.calculateMvpMatrix = function(object3D) {
14167
14499
  modelMatrix[0] = -1;
14168
14500
  let translateVec3 = fromValues$1(0, 0, -scale * 1.8);
14169
14501
  translate(modelMatrix, modelMatrix, translateVec3);
14502
+ translate(modelMatrix, modelMatrix, this.volumeObject3D.position);
14170
14503
  rotateX(modelMatrix, modelMatrix, deg2rad(270 - this.scene.renderElevation));
14171
14504
  rotateZ(modelMatrix, modelMatrix, deg2rad(this.scene.renderAzimuth - 180));
14505
+ translate(modelMatrix, modelMatrix, this.volumeObject3D.originNegate);
14172
14506
  let modelViewProjectionMatrix = create$2();
14173
14507
  multiply$1(modelViewProjectionMatrix, projectionMatrix, modelMatrix);
14174
14508
  return modelViewProjectionMatrix;
14175
14509
  };
14176
- Niivue.prototype.calculateRayDirection = function(mvpMatrix) {
14510
+ Niivue.prototype.calculateRayDirection = function() {
14511
+ function deg2rad(deg) {
14512
+ return deg * (Math.PI / 180);
14513
+ }
14514
+ const modelMatrix = create$2();
14515
+ modelMatrix[0] = -1;
14516
+ rotateX(modelMatrix, modelMatrix, deg2rad(270 - this.scene.renderElevation));
14517
+ rotateZ(modelMatrix, modelMatrix, deg2rad(this.scene.renderAzimuth - 180));
14518
+ let oblique = clone$1(this.back.obliqueRAS);
14519
+ multiply$1(modelMatrix, modelMatrix, oblique);
14520
+ let projectionMatrix = fromValues$2(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1);
14521
+ let mvpMatrix = create$2();
14522
+ multiply$1(mvpMatrix, projectionMatrix, modelMatrix);
14177
14523
  var inv = create$2();
14178
14524
  invert(inv, mvpMatrix);
14179
14525
  var rayDir4 = fromValues(0, 0, -1, 1);
14180
14526
  transformMat4(rayDir4, rayDir4, inv);
14181
14527
  let rayDir = fromValues$1(rayDir4[0], rayDir4[1], rayDir4[2]);
14182
14528
  normalize(rayDir, rayDir);
14183
- const tiny = 1e-5;
14529
+ const tiny = 5e-5;
14184
14530
  if (Math.abs(rayDir[0]) < tiny)
14185
14531
  rayDir[0] = tiny;
14186
14532
  if (Math.abs(rayDir[1]) < tiny)
@@ -14192,57 +14538,84 @@ Niivue.prototype.calculateRayDirection = function(mvpMatrix) {
14192
14538
  Niivue.prototype.draw3D = function() {
14193
14539
  this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);
14194
14540
  this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
14195
- let m = null;
14196
- for (const object3D of this.objectsToRender3D) {
14197
- if (!object3D.isVisible) {
14198
- continue;
14199
- }
14200
- let pickingShader = object3D.pickingShader ? object3D.pickingShader : this.pickingSurfaceShader;
14201
- pickingShader.use(this.gl);
14202
- if (object3D.glFlags & object3D.CULL_FACE) {
14203
- this.gl.enable(this.gl.CULL_FACE);
14204
- if (object3D.glFlags & object3D.CULL_FRONT) {
14205
- this.gl.cullFace(this.gl.FRONT);
14541
+ const mvpMatrix = this.calculateMvpMatrix(this.volumeObject3D);
14542
+ const rayDir = this.calculateRayDirection();
14543
+ if (this.scene.mouseDepthPicker) {
14544
+ this.scene.mouseDepthPicker = false;
14545
+ for (const object3D of this.objectsToRender3D) {
14546
+ if (!object3D.isVisible || !object3D.isPickable) {
14547
+ continue;
14548
+ }
14549
+ let pickingShader = object3D.pickingShader ? object3D.pickingShader : this.pickingSurfaceShader;
14550
+ pickingShader.use(this.gl);
14551
+ if (object3D.glFlags & object3D.CULL_FACE) {
14552
+ this.gl.enable(this.gl.CULL_FACE);
14553
+ if (object3D.glFlags & object3D.CULL_FRONT) {
14554
+ this.gl.cullFace(this.gl.FRONT);
14555
+ } else {
14556
+ this.gl.cullFace(this.gl.FRONT);
14557
+ }
14206
14558
  } else {
14207
- this.gl.cullFace(this.gl.BACK);
14559
+ this.gl.disable(this.gl.CULL_FACE);
14208
14560
  }
14209
- } else {
14210
- this.gl.disable(this.gl.CULL_FACE);
14211
- }
14212
- m = this.calculateMvpMatrix(object3D);
14213
- this.gl.uniformMatrix4fv(pickingShader.uniforms["mvpMtx"], false, m);
14214
- if (pickingShader.rayDirUniformName) {
14215
- let rayDir = this.calculateRayDirection(m);
14216
- this.gl.uniform3fv(pickingShader.uniforms[pickingShader.rayDirUniformName], rayDir);
14217
- }
14218
- if (pickingShader.clipPlaneUniformName) {
14219
- this.gl.uniform4fv(pickingShader.uniforms["clipPlane"], this.scene.clipPlane);
14561
+ this.gl.uniformMatrix4fv(pickingShader.uniforms["mvpMtx"], false, mvpMatrix);
14562
+ if (pickingShader.rayDirUniformName) {
14563
+ let rayDir2 = this.calculateRayDirection();
14564
+ this.gl.uniform3fv(pickingShader.uniforms[pickingShader.rayDirUniformName], rayDir2);
14565
+ }
14566
+ if (pickingShader.clipPlaneUniformName) {
14567
+ this.gl.uniform4fv(pickingShader.uniforms["clipPlane"], this.scene.clipPlane);
14568
+ }
14569
+ this.gl.uniform1i(pickingShader.uniforms["id"], object3D.id);
14570
+ this.gl.enableVertexAttribArray(0);
14571
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, object3D.vertexBuffer);
14572
+ this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);
14573
+ if (object3D.textureCoordinateBuffer) {
14574
+ this.gl.enableVertexAttribArray(1);
14575
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, object3D.textureCoordinateBuffer);
14576
+ this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0);
14577
+ } else {
14578
+ this.gl.disableVertexAttribArray(1);
14579
+ }
14580
+ if (object3D.indexBuffer) {
14581
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, object3D.indexBuffer);
14582
+ }
14583
+ if (object3D.glFlags & object3D.CULL_FACE) {
14584
+ this.gl.enable(this.gl.CULL_FACE);
14585
+ if (object3D.glFlags & object3D.CULL_FRONT) {
14586
+ this.gl.cullFace(this.gl.FRONT);
14587
+ } else {
14588
+ this.gl.cullFace(this.gl.FRONT);
14589
+ }
14590
+ } else {
14591
+ this.gl.disable(this.gl.CULL_FACE);
14592
+ }
14593
+ if (object3D.mode === this.gl.TRIANGLE_STRIP) {
14594
+ continue;
14595
+ }
14596
+ this.gl.drawElements(object3D.mode, object3D.indexCount, this.gl.UNSIGNED_SHORT, 0);
14220
14597
  }
14221
- this.gl.uniform1i(pickingShader.uniforms["id"], object3D.id);
14598
+ const pixelX = this.mousePos[0] * this.gl.canvas.width / this.gl.canvas.clientWidth;
14599
+ const pixelY = this.gl.canvas.height - this.mousePos[1] * this.gl.canvas.height / this.gl.canvas.clientHeight - 1;
14600
+ const rgbaPixel = new Uint8Array(4);
14601
+ this.gl.readPixels(pixelX, pixelY, 1, 1, this.gl.RGBA, this.gl.UNSIGNED_BYTE, rgbaPixel);
14222
14602
  this.gl.enableVertexAttribArray(0);
14223
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, object3D.vertexBuffer);
14603
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.cuboidVertexBuffer);
14224
14604
  this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);
14225
- if (object3D.textureCoordinateBuffer) {
14226
- this.gl.enableVertexAttribArray(1);
14227
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, object3D.textureCoordinateBuffer);
14228
- this.gl.vertexAttribPointer(1, 3, this.gl.FLOAT, false, 0, 0);
14605
+ this.selectedObjectId = rgbaPixel[3];
14606
+ if (this.selectedObjectId === this.VOLUME_ID) {
14607
+ this.scene.crosshairPos = new Float32Array(rgbaPixel.slice(0, 3)).map((x) => x / 255);
14229
14608
  }
14230
- if (object3D.indexBuffer) {
14231
- this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, object3D.indexBuffer);
14609
+ if (rgbaPixel[3] === 253) {
14610
+ let clipXYZ = new Float32Array(rgbaPixel.slice(0, 3)).map((x) => x / 255);
14611
+ console.log(this.scene.clipPlaneDepthAziElev[0], "User clicked on the clip plane at " + clipXYZ);
14612
+ this.scene.clipPlaneDepthAziElev[0] = this.scene.clipPlaneDepthAziElev[0] - 0.1;
14613
+ if (this.scene.clipPlaneDepthAziElev[0] <= -0.4)
14614
+ this.scene.clipPlaneDepthAziElev[0] = 0.4;
14615
+ this.clipPlaneUpdate(this.scene.clipPlaneDepthAziElev);
14232
14616
  }
14233
- this.gl.drawElements(object3D.mode, object3D.indexCount, this.gl.UNSIGNED_SHORT, 0);
14234
- break;
14235
- }
14236
- const pixelX = this.mousePos[0] * this.gl.canvas.width / this.gl.canvas.clientWidth;
14237
- const pixelY = this.gl.canvas.height - this.mousePos[1] * this.gl.canvas.height / this.gl.canvas.clientHeight - 1;
14238
- const rgbaPixel = new Uint8Array(4);
14239
- this.gl.readPixels(pixelX, pixelY, 1, 1, this.gl.RGBA, this.gl.UNSIGNED_BYTE, rgbaPixel);
14240
- this.selectedObjectId = rgbaPixel[3];
14241
- if (this.selectedObjectId === this.VOLUME_ID) {
14242
- this.scene.crosshairPos = new Float32Array(rgbaPixel.slice(0, 3)).map((x) => x / 255);
14243
14617
  }
14244
14618
  this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
14245
- this.gl.clearColor(0.2, 0, 0, 1);
14246
14619
  for (const object3D of this.objectsToRender3D) {
14247
14620
  if (!object3D.isVisible) {
14248
14621
  continue;
@@ -14258,7 +14631,7 @@ Niivue.prototype.draw3D = function() {
14258
14631
  if (object3D.indexBuffer) {
14259
14632
  this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, object3D.indexBuffer);
14260
14633
  }
14261
- if (object3D.glFlags & object3D.BLEND) {
14634
+ if (object3D.BLEND) {
14262
14635
  this.gl.enable(this.gl.BLEND);
14263
14636
  this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
14264
14637
  } else {
@@ -14274,12 +14647,13 @@ Niivue.prototype.draw3D = function() {
14274
14647
  } else {
14275
14648
  this.gl.disable(this.gl.CULL_FACE);
14276
14649
  }
14277
- m = this.calculateMvpMatrix(object3D);
14278
- let rayDir = this.calculateRayDirection(m);
14279
14650
  for (const shader of object3D.renderShaders) {
14280
14651
  shader.use(this.gl);
14281
14652
  if (shader.mvpUniformName) {
14282
- this.gl.uniformMatrix4fv(shader.uniforms[shader.mvpUniformName], false, m);
14653
+ this.gl.uniformMatrix4fv(shader.uniforms[shader.mvpUniformName], false, mvpMatrix);
14654
+ }
14655
+ if (shader.matRASUniformName) {
14656
+ this.gl.uniformMatrix4fv(shader.uniforms[shader.matRASUniformName], false, this.back.matRAS);
14283
14657
  }
14284
14658
  if (shader.rayDirUniformName) {
14285
14659
  this.gl.uniform3fv(shader.uniforms[shader.rayDirUniformName], rayDir);
@@ -14289,12 +14663,76 @@ Niivue.prototype.draw3D = function() {
14289
14663
  }
14290
14664
  this.gl.drawElements(object3D.mode, object3D.indexCount, this.gl.UNSIGNED_SHORT, 0);
14291
14665
  }
14292
- break;
14293
14666
  }
14667
+ this.drawCrosshairs3D(true, 1);
14668
+ this.drawCrosshairs3D(false, 0.35);
14294
14669
  let posString = "azimuth: " + this.scene.renderAzimuth.toFixed(0) + " elevation: " + this.scene.renderElevation.toFixed(0);
14295
14670
  this.sync();
14296
14671
  return posString;
14297
14672
  };
14673
+ Niivue.prototype.drawCrosshairs3D = function(isDepthTest = true, alpha = 1) {
14674
+ if (!this.opts.show3Dcrosshair) {
14675
+ return;
14676
+ }
14677
+ let gl = this.gl;
14678
+ let mm = this.frac2mm(this.scene.crosshairPos);
14679
+ if (this.crosshairs3D === null || this.crosshairs3D.mm[0] !== mm[0] || this.crosshairs3D.mm[1] !== mm[1] || this.crosshairs3D.mm[2] !== mm[2]) {
14680
+ if (this.crosshairs3D !== null) {
14681
+ gl.deleteBuffer(this.crosshairs3D.indexBuffer);
14682
+ gl.deleteBuffer(this.crosshairs3D.vertexBuffer);
14683
+ }
14684
+ let radius = Math.min(Math.min(this.back.pixDims[1], this.back.pixDims[2]), this.back.pixDims[3]);
14685
+ this.crosshairs3D = NiivueObject3D.generateCrosshairs(this.gl, 1, mm, this.volumeObject3D.extentsMin, this.volumeObject3D.extentsMax, radius);
14686
+ this.crosshairs3D.isPickable = false;
14687
+ this.crosshairs3D.minExtent = this.volumeObject3D.minExtent;
14688
+ this.crosshairs3D.maxExtent = this.volumeObject3D.maxExtent;
14689
+ this.crosshairs3D.mm = mm;
14690
+ this.crosshairs3D.originNegate = this.volumeObject3D.originNegate;
14691
+ this.crosshairs3D.furthestVertexFromOrigin = this.volumeObject3D.furthestVertexFromOrigin;
14692
+ }
14693
+ let crosshairsShader = new NiivueShader3D(this.surfaceShader);
14694
+ crosshairsShader.mvpUniformName = "mvpMtx";
14695
+ this.crosshairs3D.renderShaders.push(crosshairsShader);
14696
+ {
14697
+ const numComponents = 3;
14698
+ const type = gl.FLOAT;
14699
+ const normalize2 = false;
14700
+ const stride = 0;
14701
+ const offset = 0;
14702
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.crosshairs3D.vertexBuffer);
14703
+ gl.vertexAttribPointer(this.surfaceShader.uniforms["pos"], numComponents, type, normalize2, stride, offset);
14704
+ gl.enableVertexAttribArray(this.surfaceShader.uniforms["pos"]);
14705
+ }
14706
+ crosshairsShader.use(this.gl);
14707
+ let m = this.calculateMvpMatrix(this.crosshairs3D);
14708
+ gl.uniformMatrix4fv(crosshairsShader.uniforms["mvpMtx"], false, m);
14709
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.crosshairs3D.indexBuffer);
14710
+ gl.enable(gl.DEPTH_TEST);
14711
+ let color = [...this.opts.crosshairColor];
14712
+ if (isDepthTest) {
14713
+ gl.disable(gl.BLEND);
14714
+ gl.depthFunc(gl.GREATER);
14715
+ color[3] = alpha;
14716
+ } else {
14717
+ gl.enable(gl.BLEND);
14718
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
14719
+ gl.depthFunc(gl.ALWAYS);
14720
+ color[3] = alpha;
14721
+ }
14722
+ gl.uniform4fv(crosshairsShader.uniforms["surfaceColor"], color);
14723
+ {
14724
+ const vertexCount = this.crosshairs3D.indexCount;
14725
+ const type = gl.UNSIGNED_SHORT;
14726
+ const offset = 0;
14727
+ gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);
14728
+ }
14729
+ gl.enable(gl.BLEND);
14730
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
14731
+ gl.depthFunc(gl.ALWAYS);
14732
+ this.gl.enableVertexAttribArray(0);
14733
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.cuboidVertexBuffer);
14734
+ this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);
14735
+ };
14298
14736
  Niivue.prototype.mm2frac = function(mm, volIdx = 0) {
14299
14737
  let mm4 = fromValues(mm[0], mm[1], mm[2], 1);
14300
14738
  let d = this.volumes[volIdx].hdr.dims;
@@ -14304,7 +14742,7 @@ Niivue.prototype.mm2frac = function(mm, volIdx = 0) {
14304
14742
  }
14305
14743
  if (d[1] < 1 || d[2] < 1 || d[3] < 1)
14306
14744
  return frac;
14307
- let sform = clone(this.volumes[volIdx].matRAS);
14745
+ let sform = clone$1(this.volumes[volIdx].matRAS);
14308
14746
  transpose(sform, sform);
14309
14747
  invert(sform, sform);
14310
14748
  transformMat4(mm4, mm4, sform);
@@ -14331,8 +14769,8 @@ Niivue.prototype.frac2vox = function(frac, volIdx = 0) {
14331
14769
  };
14332
14770
  Niivue.prototype.frac2mm = function(frac, volIdx = 0) {
14333
14771
  let pos = fromValues(frac[0], frac[1], frac[2], 1);
14334
- let dim = fromValues(this.volumes[volIdx].hdr.dims[1], this.volumes[volIdx].hdr.dims[2], this.volumes[volIdx].hdr.dims[3], 1);
14335
- let sform = clone(this.volumes[volIdx].matRAS);
14772
+ let dim = fromValues(this.volumes[volIdx].dimsRAS[1], this.volumes[volIdx].dimsRAS[2], this.volumes[volIdx].dimsRAS[3], 1);
14773
+ let sform = clone$1(this.volumes[volIdx].matRAS);
14336
14774
  transpose(sform, sform);
14337
14775
  mul(pos, pos, dim);
14338
14776
  let shim = fromValues(-0.5, -0.5, -0.5, 0);
@@ -14410,8 +14848,25 @@ Niivue.prototype.drawScene = function() {
14410
14848
  this.drawLoadingText(this.loadingText);
14411
14849
  return;
14412
14850
  }
14413
- if (this.sliceType === this.sliceTypeRender)
14851
+ if (this.sliceType === this.sliceTypeRender) {
14852
+ if (this.isDragging && this.scene.clipPlaneDepthAziElev[0] < 1.8) {
14853
+ let x = this.dragStart[0] - this.dragEnd[0];
14854
+ let y = this.dragStart[1] - this.dragEnd[1];
14855
+ let depthAziElev = this.dragClipPlaneStartDepthAziElev.slice();
14856
+ depthAziElev[1] -= x;
14857
+ depthAziElev[1] = depthAziElev[1] % 360;
14858
+ depthAziElev[2] += y;
14859
+ if (depthAziElev[2] > 90)
14860
+ depthAziElev[2] = 90;
14861
+ if (depthAziElev[2] < -90)
14862
+ depthAziElev[2] = -90;
14863
+ if (depthAziElev[1] !== this.scene.clipPlaneDepthAziElev[1] || depthAziElev[2] !== this.scene.clipPlaneDepthAziElev[2]) {
14864
+ this.scene.clipPlaneDepthAziElev = depthAziElev;
14865
+ return this.clipPlaneUpdate(this.scene.clipPlaneDepthAziElev);
14866
+ }
14867
+ }
14414
14868
  return this.draw3D();
14869
+ }
14415
14870
  let { volScale } = this.sliceScale();
14416
14871
  this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);
14417
14872
  this.numScreenSlices = 0;