@d5techs/3dgs-lib 1.4.81 → 1.4.83
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/3dgs-lib.cjs +253 -499
- package/dist/3dgs-lib.cjs.map +1 -1
- package/dist/3dgs-lib.js +253 -499
- package/dist/3dgs-lib.js.map +1 -1
- package/dist/editor/SelectionVolumeRenderer.d.ts +10 -10
- package/package.json +1 -1
package/dist/3dgs-lib.js
CHANGED
|
@@ -17575,12 +17575,11 @@ class SphereSelection {
|
|
|
17575
17575
|
this.parent = parent;
|
|
17576
17576
|
this.callbacks = callbacks;
|
|
17577
17577
|
this.toolbar = document.createElement("div");
|
|
17578
|
-
this.toolbar.className = "select-toolbar";
|
|
17578
|
+
this.toolbar.className = "volume-select-toolbar";
|
|
17579
17579
|
this.toolbar.style.cssText = `
|
|
17580
|
-
position:absolute; bottom:
|
|
17581
|
-
|
|
17582
|
-
padding:
|
|
17583
|
-
background:rgba(30,30,30,0.92);
|
|
17580
|
+
position:absolute; bottom:90px; left:50%; transform:translateX(-50%);
|
|
17581
|
+
display:none; z-index:20; background:rgba(30,30,30,0.92);
|
|
17582
|
+
border-radius:8px; padding:6px 10px; gap:6px;
|
|
17584
17583
|
align-items:center; font-size:13px; color:#ddd;
|
|
17585
17584
|
backdrop-filter:blur(6px); user-select:none; white-space:nowrap;
|
|
17586
17585
|
box-shadow:0 2px 12px rgba(0,0,0,0.4);
|
|
@@ -17591,15 +17590,15 @@ class SphereSelection {
|
|
|
17591
17590
|
const btn = document.createElement("button");
|
|
17592
17591
|
btn.textContent = label2;
|
|
17593
17592
|
btn.style.cssText = `
|
|
17594
|
-
|
|
17595
|
-
background:#
|
|
17593
|
+
padding:4px 12px; border:1px solid #555; border-radius:4px;
|
|
17594
|
+
background:#333; color:#ddd; cursor:pointer; font-size:13px;
|
|
17596
17595
|
transition: background 0.15s;
|
|
17597
17596
|
`;
|
|
17598
17597
|
btn.addEventListener("mouseenter", () => {
|
|
17599
17598
|
btn.style.background = "#555";
|
|
17600
17599
|
});
|
|
17601
17600
|
btn.addEventListener("mouseleave", () => {
|
|
17602
|
-
btn.style.background = "#
|
|
17601
|
+
btn.style.background = "#333";
|
|
17603
17602
|
});
|
|
17604
17603
|
btn.addEventListener("pointerdown", (e) => {
|
|
17605
17604
|
e.stopPropagation();
|
|
@@ -17611,27 +17610,27 @@ class SphereSelection {
|
|
|
17611
17610
|
const addBtn = mkBtn("Add", "add");
|
|
17612
17611
|
const removeBtn = mkBtn("Remove", "remove");
|
|
17613
17612
|
const inputWrap = document.createElement("span");
|
|
17614
|
-
inputWrap.style.cssText = "display:inline-flex; align-items:center; gap:
|
|
17615
|
-
const label = document.createElement("span");
|
|
17616
|
-
label.textContent = "Radius";
|
|
17617
|
-
label.style.cssText = "color:#888; font-size:11px;";
|
|
17613
|
+
inputWrap.style.cssText = "display:inline-flex; align-items:center; gap:2px;";
|
|
17618
17614
|
const input = document.createElement("input");
|
|
17619
17615
|
input.type = "number";
|
|
17620
|
-
input.min = "
|
|
17621
|
-
input.step = "
|
|
17622
|
-
input.value = this._radius
|
|
17616
|
+
input.min = "1";
|
|
17617
|
+
input.step = "1";
|
|
17618
|
+
input.value = String(this._radius);
|
|
17623
17619
|
input.style.cssText = `
|
|
17624
|
-
width:
|
|
17620
|
+
width:40px; padding:3px 4px; border:1px solid #555; border-radius:4px;
|
|
17625
17621
|
background:#222; color:#ddd; font-size:12px; text-align:center;
|
|
17626
17622
|
`;
|
|
17623
|
+
const label = document.createElement("span");
|
|
17624
|
+
label.textContent = "Radius";
|
|
17625
|
+
label.style.cssText = "color:#888; font-size:11px;";
|
|
17627
17626
|
input.addEventListener("change", () => {
|
|
17628
|
-
const v = Math.max(
|
|
17629
|
-
input.value = v
|
|
17627
|
+
const v = Math.max(1, Math.round(parseFloat(input.value) || 1));
|
|
17628
|
+
input.value = String(v);
|
|
17630
17629
|
this._radius = v;
|
|
17631
17630
|
this.callbacks.onRadiusChanged(v);
|
|
17632
17631
|
});
|
|
17633
|
-
inputWrap.appendChild(label);
|
|
17634
17632
|
inputWrap.appendChild(input);
|
|
17633
|
+
inputWrap.appendChild(label);
|
|
17635
17634
|
this.radiusInput = input;
|
|
17636
17635
|
this.toolbar.appendChild(setBtn);
|
|
17637
17636
|
this.toolbar.appendChild(addBtn);
|
|
@@ -17643,8 +17642,8 @@ class SphereSelection {
|
|
|
17643
17642
|
return this._radius;
|
|
17644
17643
|
}
|
|
17645
17644
|
setRadius(radius) {
|
|
17646
|
-
this._radius = radius;
|
|
17647
|
-
this.radiusInput.value =
|
|
17645
|
+
this._radius = Math.round(radius);
|
|
17646
|
+
this.radiusInput.value = String(this._radius);
|
|
17648
17647
|
}
|
|
17649
17648
|
activate() {
|
|
17650
17649
|
this.toolbar.style.display = "flex";
|
|
@@ -17667,12 +17666,11 @@ class BoxSelection {
|
|
|
17667
17666
|
this.parent = parent;
|
|
17668
17667
|
this.callbacks = callbacks;
|
|
17669
17668
|
this.toolbar = document.createElement("div");
|
|
17670
|
-
this.toolbar.className = "select-toolbar";
|
|
17669
|
+
this.toolbar.className = "volume-select-toolbar";
|
|
17671
17670
|
this.toolbar.style.cssText = `
|
|
17672
|
-
position:absolute; bottom:
|
|
17673
|
-
|
|
17674
|
-
padding:
|
|
17675
|
-
background:rgba(30,30,30,0.92);
|
|
17671
|
+
position:absolute; bottom:90px; left:50%; transform:translateX(-50%);
|
|
17672
|
+
display:none; z-index:20; background:rgba(30,30,30,0.92);
|
|
17673
|
+
border-radius:8px; padding:6px 10px; gap:6px;
|
|
17676
17674
|
align-items:center; font-size:13px; color:#ddd;
|
|
17677
17675
|
backdrop-filter:blur(6px); user-select:none; white-space:nowrap;
|
|
17678
17676
|
box-shadow:0 2px 12px rgba(0,0,0,0.4);
|
|
@@ -17683,15 +17681,15 @@ class BoxSelection {
|
|
|
17683
17681
|
const btn = document.createElement("button");
|
|
17684
17682
|
btn.textContent = label;
|
|
17685
17683
|
btn.style.cssText = `
|
|
17686
|
-
|
|
17687
|
-
background:#
|
|
17684
|
+
padding:4px 12px; border:1px solid #555; border-radius:4px;
|
|
17685
|
+
background:#333; color:#ddd; cursor:pointer; font-size:13px;
|
|
17688
17686
|
transition: background 0.15s;
|
|
17689
17687
|
`;
|
|
17690
17688
|
btn.addEventListener("mouseenter", () => {
|
|
17691
17689
|
btn.style.background = "#555";
|
|
17692
17690
|
});
|
|
17693
17691
|
btn.addEventListener("mouseleave", () => {
|
|
17694
|
-
btn.style.background = "#
|
|
17692
|
+
btn.style.background = "#333";
|
|
17695
17693
|
});
|
|
17696
17694
|
btn.addEventListener("pointerdown", (e) => {
|
|
17697
17695
|
e.stopPropagation();
|
|
@@ -17701,26 +17699,26 @@ class BoxSelection {
|
|
|
17701
17699
|
};
|
|
17702
17700
|
const mkInput = (placeholder, initial, onChange) => {
|
|
17703
17701
|
const wrap = document.createElement("span");
|
|
17704
|
-
wrap.style.cssText = "display:inline-flex; align-items:center; gap:
|
|
17705
|
-
const label = document.createElement("span");
|
|
17706
|
-
label.textContent = placeholder;
|
|
17707
|
-
label.style.cssText = "color:#888; font-size:11px;";
|
|
17702
|
+
wrap.style.cssText = "display:inline-flex; align-items:center; gap:2px;";
|
|
17708
17703
|
const input = document.createElement("input");
|
|
17709
17704
|
input.type = "number";
|
|
17710
|
-
input.min = "
|
|
17711
|
-
input.step = "
|
|
17712
|
-
input.value =
|
|
17705
|
+
input.min = "1";
|
|
17706
|
+
input.step = "1";
|
|
17707
|
+
input.value = String(Math.round(initial));
|
|
17713
17708
|
input.style.cssText = `
|
|
17714
|
-
width:
|
|
17709
|
+
width:40px; padding:3px 4px; border:1px solid #555; border-radius:4px;
|
|
17715
17710
|
background:#222; color:#ddd; font-size:12px; text-align:center;
|
|
17716
17711
|
`;
|
|
17712
|
+
const label = document.createElement("span");
|
|
17713
|
+
label.textContent = placeholder;
|
|
17714
|
+
label.style.cssText = "color:#888; font-size:11px;";
|
|
17717
17715
|
input.addEventListener("change", () => {
|
|
17718
|
-
const v = Math.max(
|
|
17719
|
-
input.value = v
|
|
17716
|
+
const v = Math.max(1, Math.round(parseFloat(input.value) || 1));
|
|
17717
|
+
input.value = String(v);
|
|
17720
17718
|
onChange(v);
|
|
17721
17719
|
});
|
|
17722
|
-
wrap.appendChild(label);
|
|
17723
17720
|
wrap.appendChild(input);
|
|
17721
|
+
wrap.appendChild(label);
|
|
17724
17722
|
return { wrap, input };
|
|
17725
17723
|
};
|
|
17726
17724
|
const setBtn = mkBtn("Set", "set");
|
|
@@ -17759,12 +17757,12 @@ class BoxSelection {
|
|
|
17759
17757
|
return this._lenZ;
|
|
17760
17758
|
}
|
|
17761
17759
|
setDimensions(lenX, lenY, lenZ) {
|
|
17762
|
-
this._lenX = lenX;
|
|
17763
|
-
this._lenY = lenY;
|
|
17764
|
-
this._lenZ = lenZ;
|
|
17765
|
-
this.inputX.value =
|
|
17766
|
-
this.inputY.value =
|
|
17767
|
-
this.inputZ.value =
|
|
17760
|
+
this._lenX = Math.round(lenX);
|
|
17761
|
+
this._lenY = Math.round(lenY);
|
|
17762
|
+
this._lenZ = Math.round(lenZ);
|
|
17763
|
+
this.inputX.value = String(this._lenX);
|
|
17764
|
+
this.inputY.value = String(this._lenY);
|
|
17765
|
+
this.inputZ.value = String(this._lenZ);
|
|
17768
17766
|
}
|
|
17769
17767
|
activate() {
|
|
17770
17768
|
this.toolbar.style.display = "flex";
|
|
@@ -17877,311 +17875,29 @@ function exportEditedPLY(positions, scales, rotations, colors, opacities, shCoef
|
|
|
17877
17875
|
}
|
|
17878
17876
|
return buffer;
|
|
17879
17877
|
}
|
|
17880
|
-
const
|
|
17881
|
-
|
|
17882
|
-
|
|
17883
|
-
|
|
17884
|
-
0.5,
|
|
17885
|
-
-0.5,
|
|
17886
|
-
0.5,
|
|
17887
|
-
0.5,
|
|
17888
|
-
0.5,
|
|
17889
|
-
0.5,
|
|
17890
|
-
-0.5,
|
|
17891
|
-
-0.5,
|
|
17892
|
-
0.5,
|
|
17893
|
-
0.5,
|
|
17894
|
-
0.5,
|
|
17895
|
-
0.5,
|
|
17896
|
-
-0.5,
|
|
17897
|
-
0.5,
|
|
17898
|
-
0.5,
|
|
17899
|
-
0.5,
|
|
17900
|
-
-0.5,
|
|
17901
|
-
-0.5,
|
|
17902
|
-
-0.5,
|
|
17903
|
-
-0.5,
|
|
17904
|
-
-0.5,
|
|
17905
|
-
-0.5,
|
|
17906
|
-
0.5,
|
|
17907
|
-
-0.5,
|
|
17908
|
-
0.5,
|
|
17909
|
-
-0.5,
|
|
17910
|
-
-0.5,
|
|
17911
|
-
-0.5,
|
|
17912
|
-
0.5,
|
|
17913
|
-
-0.5,
|
|
17914
|
-
0.5,
|
|
17915
|
-
0.5,
|
|
17916
|
-
-0.5,
|
|
17917
|
-
-0.5,
|
|
17918
|
-
0.5,
|
|
17919
|
-
0.5,
|
|
17920
|
-
0.5,
|
|
17921
|
-
0.5,
|
|
17922
|
-
0.5,
|
|
17923
|
-
0.5,
|
|
17924
|
-
0.5,
|
|
17925
|
-
-0.5,
|
|
17926
|
-
-0.5,
|
|
17927
|
-
0.5,
|
|
17928
|
-
0.5,
|
|
17929
|
-
0.5,
|
|
17930
|
-
0.5,
|
|
17931
|
-
-0.5,
|
|
17932
|
-
-0.5,
|
|
17933
|
-
0.5,
|
|
17934
|
-
-0.5,
|
|
17935
|
-
-0.5,
|
|
17936
|
-
-0.5,
|
|
17937
|
-
-0.5,
|
|
17938
|
-
0.5,
|
|
17939
|
-
-0.5,
|
|
17940
|
-
-0.5,
|
|
17941
|
-
0.5,
|
|
17942
|
-
-0.5,
|
|
17943
|
-
0.5,
|
|
17944
|
-
-0.5,
|
|
17945
|
-
-0.5,
|
|
17946
|
-
-0.5,
|
|
17947
|
-
0.5,
|
|
17948
|
-
-0.5,
|
|
17949
|
-
0.5,
|
|
17950
|
-
-0.5,
|
|
17951
|
-
-0.5,
|
|
17952
|
-
0.5,
|
|
17953
|
-
0.5,
|
|
17954
|
-
-0.5,
|
|
17955
|
-
0.5,
|
|
17956
|
-
0.5,
|
|
17957
|
-
-0.5,
|
|
17958
|
-
-0.5,
|
|
17959
|
-
0.5,
|
|
17960
|
-
0.5,
|
|
17961
|
-
-0.5,
|
|
17962
|
-
0.5,
|
|
17963
|
-
-0.5,
|
|
17964
|
-
0.5,
|
|
17965
|
-
0.5,
|
|
17966
|
-
0.5,
|
|
17967
|
-
-0.5,
|
|
17968
|
-
0.5,
|
|
17969
|
-
0.5,
|
|
17970
|
-
0.5,
|
|
17971
|
-
-0.5,
|
|
17972
|
-
-0.5,
|
|
17973
|
-
-0.5,
|
|
17974
|
-
-0.5,
|
|
17975
|
-
-0.5,
|
|
17976
|
-
0.5,
|
|
17977
|
-
-0.5,
|
|
17978
|
-
0.5,
|
|
17979
|
-
0.5,
|
|
17980
|
-
-0.5,
|
|
17981
|
-
-0.5,
|
|
17982
|
-
-0.5,
|
|
17983
|
-
-0.5,
|
|
17984
|
-
0.5,
|
|
17985
|
-
0.5,
|
|
17986
|
-
-0.5,
|
|
17987
|
-
0.5,
|
|
17988
|
-
-0.5
|
|
17989
|
-
]);
|
|
17990
|
-
const COMMON_WGSL = (
|
|
17991
|
-
/* wgsl */
|
|
17992
|
-
`
|
|
17993
|
-
struct Uniforms {
|
|
17994
|
-
viewProjMatrix: mat4x4<f32>,
|
|
17995
|
-
modelMatrix: mat4x4<f32>,
|
|
17996
|
-
nearOrigin: vec4<f32>,
|
|
17997
|
-
nearX: vec4<f32>,
|
|
17998
|
-
nearY: vec4<f32>,
|
|
17999
|
-
farOrigin: vec4<f32>,
|
|
18000
|
-
farX: vec4<f32>,
|
|
18001
|
-
farY: vec4<f32>,
|
|
18002
|
-
targetSize: vec4<f32>,
|
|
18003
|
-
shapeP0: vec4<f32>,
|
|
18004
|
-
shapeP1: vec4<f32>,
|
|
18005
|
-
}
|
|
18006
|
-
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
18007
|
-
|
|
18008
|
-
struct VO { @builtin(position) position: vec4<f32> }
|
|
18009
|
-
struct FO {
|
|
18010
|
-
@location(0) color: vec4<f32>,
|
|
18011
|
-
@builtin(frag_depth) depth: f32,
|
|
18012
|
-
}
|
|
18013
|
-
|
|
18014
|
-
@vertex fn vs(@location(0) pos: vec3<f32>) -> VO {
|
|
18015
|
-
var o: VO;
|
|
18016
|
-
o.position = u.viewProjMatrix * u.modelMatrix * vec4(pos, 1.0);
|
|
18017
|
-
return o;
|
|
18018
|
-
}
|
|
18019
|
-
|
|
18020
|
-
fn interleavedGradientNoise(p: vec2<f32>) -> f32 {
|
|
18021
|
-
return fract(52.9829189 * fract(dot(p, vec2(0.06711056, 0.00583715))));
|
|
18022
|
-
}
|
|
18023
|
-
|
|
18024
|
-
fn writeDepth(alpha: f32, fc: vec2<f32>) -> bool {
|
|
18025
|
-
return alpha > interleavedGradientNoise(fc);
|
|
18026
|
-
}
|
|
18027
|
-
|
|
18028
|
-
fn calcDepth(wp: vec3<f32>) -> f32 {
|
|
18029
|
-
let v = u.viewProjMatrix * vec4(wp, 1.0);
|
|
18030
|
-
return clamp(v.z / v.w, 0.0, 1.0);
|
|
18031
|
-
}
|
|
18032
|
-
|
|
18033
|
-
fn reconstructRay(fragPos: vec4<f32>) -> array<vec3<f32>, 2> {
|
|
18034
|
-
let clip = vec2(fragPos.x / u.targetSize.x, 1.0 - fragPos.y / u.targetSize.y);
|
|
18035
|
-
let wNear = u.nearOrigin.xyz + u.nearX.xyz * clip.x + u.nearY.xyz * clip.y;
|
|
18036
|
-
let wFar = u.farOrigin.xyz + u.farX.xyz * clip.x + u.farY.xyz * clip.y;
|
|
18037
|
-
return array(wNear, normalize(wFar - wNear));
|
|
18038
|
-
}
|
|
18039
|
-
`
|
|
18040
|
-
);
|
|
18041
|
-
const BOX_FRAG_WGSL = (
|
|
18042
|
-
/* wgsl */
|
|
18043
|
-
`
|
|
18044
|
-
fn intersectBox(pos: vec3<f32>, dir: vec3<f32>, cen: vec3<f32>, halfLen: vec3<f32>) -> vec4<f32> {
|
|
18045
|
-
let vx = select(0.0, 1.0, dir.x != 0.0);
|
|
18046
|
-
let vy = select(0.0, 1.0, dir.y != 0.0);
|
|
18047
|
-
let vz = select(0.0, 1.0, dir.z != 0.0);
|
|
18048
|
-
let valid = vec3<f32>(vx, vy, vz);
|
|
18049
|
-
let m = vec3<f32>(
|
|
18050
|
-
select(0.0, sign(dir.x) / abs(dir.x), dir.x != 0.0),
|
|
18051
|
-
select(0.0, sign(dir.y) / abs(dir.y), dir.y != 0.0),
|
|
18052
|
-
select(0.0, sign(dir.z) / abs(dir.z), dir.z != 0.0),
|
|
18053
|
-
);
|
|
18054
|
-
let n = m * (pos - cen);
|
|
18055
|
-
let k = abs(m) * halfLen;
|
|
18056
|
-
var v0 = -n - k;
|
|
18057
|
-
var v1 = -n + k;
|
|
18058
|
-
v0 = mix(vec3(-1e10), v0, valid);
|
|
18059
|
-
v1 = mix(vec3( 1e10), v1, valid);
|
|
18060
|
-
|
|
18061
|
-
var axis0: i32; var axis1: i32;
|
|
18062
|
-
if v0.x > v0.y { axis0 = select(2, 0, v0.x > v0.z); }
|
|
18063
|
-
else { axis0 = select(2, 1, v0.y > v0.z); }
|
|
18064
|
-
if v1.x < v1.y { axis1 = select(2, 0, v1.x < v1.z); }
|
|
18065
|
-
else { axis1 = select(2, 1, v1.y < v1.z); }
|
|
18066
|
-
|
|
18067
|
-
let t0 = select(select(v0.z, v0.y, axis0==1), v0.x, axis0==0);
|
|
18068
|
-
let t1 = select(select(v1.z, v1.y, axis1==1), v1.x, axis1==0);
|
|
18069
|
-
if t0 > t1 || t1 < 0.0 { return vec4(-1.0); }
|
|
18070
|
-
return vec4(t0, t1, f32(axis0), f32(axis1));
|
|
18071
|
-
}
|
|
18072
|
-
|
|
18073
|
-
fn strips(pos: vec3<f32>, axis: i32) -> bool {
|
|
18074
|
-
let f = fract(pos * 2.0 + vec3(0.015));
|
|
18075
|
-
let b = f < vec3(0.03);
|
|
18076
|
-
if axis == 0 { return b.y || b.z; }
|
|
18077
|
-
if axis == 1 { return b.x || b.z; }
|
|
18078
|
-
return b.x || b.y;
|
|
18079
|
-
}
|
|
18080
|
-
|
|
18081
|
-
@fragment fn fs(i: VO) -> FO {
|
|
18082
|
-
var o: FO;
|
|
18083
|
-
o.color = vec4(0.0);
|
|
18084
|
-
o.depth = 1.0;
|
|
18085
|
-
|
|
18086
|
-
let ray = reconstructRay(i.position);
|
|
18087
|
-
let hit = intersectBox(ray[0], ray[1], u.shapeP0.xyz, u.shapeP1.xyz);
|
|
18088
|
-
if hit.x < 0.0 { discard; return o; }
|
|
18089
|
-
|
|
18090
|
-
let t0 = hit.x; let t1 = hit.y;
|
|
18091
|
-
let a0 = i32(hit.z); let a1 = i32(hit.w);
|
|
18092
|
-
let frontPos = ray[0] + ray[1] * t0;
|
|
18093
|
-
let backPos = ray[0] + ray[1] * t1;
|
|
18094
|
-
let front = t0 > 0.0 && strips(frontPos - u.shapeP0.xyz, a0);
|
|
18095
|
-
let back = strips(backPos - u.shapeP0.xyz, a1);
|
|
18096
|
-
|
|
18097
|
-
if front {
|
|
18098
|
-
o.color = vec4(1.0, 1.0, 1.0, 0.6);
|
|
18099
|
-
o.depth = select(1.0, calcDepth(frontPos), writeDepth(0.6, i.position.xy));
|
|
18100
|
-
return o;
|
|
18101
|
-
}
|
|
18102
|
-
if back {
|
|
18103
|
-
o.color = vec4(0.0, 0.0, 0.0, 0.6);
|
|
18104
|
-
o.depth = select(1.0, calcDepth(backPos), writeDepth(0.6, i.position.xy));
|
|
18105
|
-
return o;
|
|
18106
|
-
}
|
|
18107
|
-
discard;
|
|
18108
|
-
return o;
|
|
18109
|
-
}
|
|
18110
|
-
`
|
|
18111
|
-
);
|
|
18112
|
-
const SPHERE_FRAG_WGSL = (
|
|
18113
|
-
/* wgsl */
|
|
18114
|
-
`
|
|
18115
|
-
fn intersectSphere(pos: vec3<f32>, dir: vec3<f32>, sph: vec4<f32>) -> vec2<f32> {
|
|
18116
|
-
let L = sph.xyz - pos;
|
|
18117
|
-
let tca = dot(L, dir);
|
|
18118
|
-
let d2 = sph.w * sph.w - (dot(L, L) - tca * tca);
|
|
18119
|
-
if d2 <= 0.0 { return vec2(-1.0); }
|
|
18120
|
-
let thc = sqrt(d2);
|
|
18121
|
-
let t0 = tca - thc;
|
|
18122
|
-
let t1 = tca + thc;
|
|
18123
|
-
if t1 <= 0.0 { return vec2(-1.0); }
|
|
18124
|
-
return vec2(t0, t1);
|
|
18125
|
-
}
|
|
18126
|
-
|
|
18127
|
-
fn calcAzimuthElev(dir: vec3<f32>) -> vec2<f32> {
|
|
18128
|
-
let azimuth = atan2(dir.z, dir.x);
|
|
18129
|
-
let elev = asin(clamp(dir.y, -1.0, 1.0));
|
|
18130
|
-
return vec2(azimuth, elev) * 180.0 / 3.14159265;
|
|
18131
|
-
}
|
|
18132
|
-
|
|
18133
|
-
fn sphereStrips(lp: vec3<f32>, radius: f32) -> bool {
|
|
18134
|
-
let ae = calcAzimuthElev(normalize(lp));
|
|
18135
|
-
let spacing = 180.0 / (2.0 * 3.14159265 * radius);
|
|
18136
|
-
let sz = 0.03;
|
|
18137
|
-
return fract(ae.x / spacing) < sz || fract(ae.y / spacing) < sz;
|
|
18138
|
-
}
|
|
18139
|
-
|
|
18140
|
-
@fragment fn fs(i: VO) -> FO {
|
|
18141
|
-
var o: FO;
|
|
18142
|
-
o.color = vec4(0.0);
|
|
18143
|
-
o.depth = 1.0;
|
|
18144
|
-
|
|
18145
|
-
let sph = u.shapeP0;
|
|
18146
|
-
let ray = reconstructRay(i.position);
|
|
18147
|
-
let hit = intersectSphere(ray[0], ray[1], sph);
|
|
18148
|
-
if hit.x < 0.0 && hit.y < 0.0 { discard; return o; }
|
|
18149
|
-
|
|
18150
|
-
let t0 = hit.x; let t1 = hit.y;
|
|
18151
|
-
let frontPos = ray[0] + ray[1] * t0;
|
|
18152
|
-
let backPos = ray[0] + ray[1] * t1;
|
|
18153
|
-
let front = t0 > 0.0 && sphereStrips(frontPos - sph.xyz, sph.w);
|
|
18154
|
-
let back = sphereStrips(backPos - sph.xyz, sph.w);
|
|
18155
|
-
|
|
18156
|
-
if front {
|
|
18157
|
-
o.color = vec4(1.0, 1.0, 1.0, 0.6);
|
|
18158
|
-
o.depth = select(1.0, calcDepth(frontPos), writeDepth(0.6, i.position.xy));
|
|
18159
|
-
return o;
|
|
18160
|
-
}
|
|
18161
|
-
if back {
|
|
18162
|
-
o.color = vec4(0.0, 0.0, 0.0, 0.6);
|
|
18163
|
-
o.depth = select(1.0, calcDepth(backPos), writeDepth(0.6, i.position.xy));
|
|
18164
|
-
return o;
|
|
18165
|
-
}
|
|
18166
|
-
discard;
|
|
18167
|
-
return o;
|
|
18168
|
-
}
|
|
18169
|
-
`
|
|
18170
|
-
);
|
|
18171
|
-
const UNIFORM_SIZE = 272;
|
|
17878
|
+
const SEG = 64;
|
|
17879
|
+
const LAT_COUNT = 8;
|
|
17880
|
+
const LON_COUNT = 12;
|
|
17881
|
+
const BOX_GRID_SUBDIV = 4;
|
|
18172
17882
|
class SelectionVolumeRenderer {
|
|
18173
17883
|
constructor(renderer, camera) {
|
|
18174
17884
|
__publicField(this, "renderer");
|
|
18175
17885
|
__publicField(this, "camera");
|
|
18176
|
-
__publicField(this, "
|
|
18177
|
-
__publicField(this, "
|
|
17886
|
+
__publicField(this, "frontPipeline", null);
|
|
17887
|
+
__publicField(this, "behindPipeline", null);
|
|
18178
17888
|
__publicField(this, "uniformBuffer", null);
|
|
18179
17889
|
__publicField(this, "bindGroup", null);
|
|
18180
17890
|
__publicField(this, "vertexBuffer", null);
|
|
18181
17891
|
__publicField(this, "_volume", { type: null, center: [0, 0, 0], dimensions: [2, 2, 2] });
|
|
17892
|
+
__publicField(this, "vertexCount", 0);
|
|
17893
|
+
__publicField(this, "frontColor", [0.4, 0.9, 1]);
|
|
18182
17894
|
this.renderer = renderer;
|
|
18183
17895
|
this.camera = camera;
|
|
18184
|
-
this.
|
|
17896
|
+
this.createPipelines();
|
|
17897
|
+
this.vertexBuffer = this.renderer.device.createBuffer({
|
|
17898
|
+
size: 65536,
|
|
17899
|
+
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
|
|
17900
|
+
});
|
|
18185
17901
|
}
|
|
18186
17902
|
get volume() {
|
|
18187
17903
|
return this._volume;
|
|
@@ -18197,187 +17913,225 @@ class SelectionVolumeRenderer {
|
|
|
18197
17913
|
setDimensions(a, b, c) {
|
|
18198
17914
|
this._volume.dimensions = [a, b, c];
|
|
18199
17915
|
}
|
|
18200
|
-
|
|
17916
|
+
createPipelines() {
|
|
18201
17917
|
const device = this.renderer.device;
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
|
|
17918
|
+
const shaderCode = (
|
|
17919
|
+
/* wgsl */
|
|
17920
|
+
`
|
|
17921
|
+
struct Uniforms {
|
|
17922
|
+
viewMatrix: mat4x4<f32>,
|
|
17923
|
+
projMatrix: mat4x4<f32>,
|
|
17924
|
+
modelMatrix: mat4x4<f32>,
|
|
17925
|
+
}
|
|
17926
|
+
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
17927
|
+
|
|
17928
|
+
struct VI { @location(0) position: vec3<f32>, @location(1) color: vec3<f32> }
|
|
17929
|
+
struct VO { @builtin(position) position: vec4<f32>, @location(0) color: vec3<f32> }
|
|
17930
|
+
|
|
17931
|
+
@vertex fn vs(i: VI) -> VO {
|
|
17932
|
+
var o: VO;
|
|
17933
|
+
let worldPos = uniforms.modelMatrix * vec4(i.position, 1.0);
|
|
17934
|
+
let viewPos = uniforms.viewMatrix * worldPos;
|
|
17935
|
+
o.position = uniforms.projMatrix * viewPos;
|
|
17936
|
+
o.color = i.color;
|
|
17937
|
+
return o;
|
|
17938
|
+
}
|
|
17939
|
+
@fragment fn fs(i: VO) -> @location(0) vec4<f32> {
|
|
17940
|
+
return vec4(i.color, 0.7);
|
|
17941
|
+
}
|
|
17942
|
+
@fragment fn fsBehind(i: VO) -> @location(0) vec4<f32> {
|
|
17943
|
+
return vec4(i.color * 0.35, 0.2);
|
|
17944
|
+
}
|
|
17945
|
+
`
|
|
17946
|
+
);
|
|
17947
|
+
const sm = device.createShaderModule({ code: shaderCode });
|
|
17948
|
+
this.uniformBuffer = device.createBuffer({ size: 192, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
|
|
18211
17949
|
const bgl = device.createBindGroupLayout({
|
|
18212
|
-
entries: [{
|
|
18213
|
-
binding: 0,
|
|
18214
|
-
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
18215
|
-
buffer: { type: "uniform" }
|
|
18216
|
-
}]
|
|
18217
|
-
});
|
|
18218
|
-
this.bindGroup = device.createBindGroup({
|
|
18219
|
-
layout: bgl,
|
|
18220
|
-
entries: [{ binding: 0, resource: { buffer: this.uniformBuffer } }]
|
|
17950
|
+
entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } }]
|
|
18221
17951
|
});
|
|
17952
|
+
this.bindGroup = device.createBindGroup({ layout: bgl, entries: [{ binding: 0, resource: { buffer: this.uniformBuffer } }] });
|
|
18222
17953
|
const layout = device.createPipelineLayout({ bindGroupLayouts: [bgl] });
|
|
18223
|
-
const
|
|
18224
|
-
module:
|
|
17954
|
+
const vertexState = {
|
|
17955
|
+
module: sm,
|
|
18225
17956
|
entryPoint: "vs",
|
|
18226
17957
|
buffers: [{
|
|
18227
|
-
arrayStride:
|
|
18228
|
-
attributes: [
|
|
17958
|
+
arrayStride: 24,
|
|
17959
|
+
attributes: [
|
|
17960
|
+
{ shaderLocation: 0, offset: 0, format: "float32x3" },
|
|
17961
|
+
{ shaderLocation: 1, offset: 12, format: "float32x3" }
|
|
17962
|
+
]
|
|
18229
17963
|
}]
|
|
18230
|
-
}
|
|
18231
|
-
const
|
|
17964
|
+
};
|
|
17965
|
+
const blendState = {
|
|
18232
17966
|
color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha", operation: "add" },
|
|
18233
17967
|
alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" }
|
|
18234
17968
|
};
|
|
18235
|
-
|
|
18236
|
-
format: this.renderer.depthFormat,
|
|
18237
|
-
depthWriteEnabled: true,
|
|
18238
|
-
depthCompare: "less-equal"
|
|
18239
|
-
};
|
|
18240
|
-
const boxMod = device.createShaderModule({ code: COMMON_WGSL + BOX_FRAG_WGSL });
|
|
18241
|
-
this.boxPipeline = device.createRenderPipeline({
|
|
17969
|
+
this.frontPipeline = device.createRenderPipeline({
|
|
18242
17970
|
layout,
|
|
18243
|
-
vertex:
|
|
17971
|
+
vertex: vertexState,
|
|
18244
17972
|
fragment: {
|
|
18245
|
-
module:
|
|
17973
|
+
module: sm,
|
|
18246
17974
|
entryPoint: "fs",
|
|
18247
|
-
targets: [{ format: this.renderer.format, blend }]
|
|
17975
|
+
targets: [{ format: this.renderer.format, blend: blendState }]
|
|
18248
17976
|
},
|
|
18249
|
-
primitive: { topology: "
|
|
18250
|
-
depthStencil
|
|
17977
|
+
primitive: { topology: "line-list", cullMode: "none" },
|
|
17978
|
+
depthStencil: { format: this.renderer.depthFormat, depthWriteEnabled: false, depthCompare: "less-equal" }
|
|
18251
17979
|
});
|
|
18252
|
-
|
|
18253
|
-
this.spherePipeline = device.createRenderPipeline({
|
|
17980
|
+
this.behindPipeline = device.createRenderPipeline({
|
|
18254
17981
|
layout,
|
|
18255
|
-
vertex:
|
|
17982
|
+
vertex: vertexState,
|
|
18256
17983
|
fragment: {
|
|
18257
|
-
module:
|
|
18258
|
-
entryPoint: "
|
|
18259
|
-
targets: [{ format: this.renderer.format, blend }]
|
|
17984
|
+
module: sm,
|
|
17985
|
+
entryPoint: "fsBehind",
|
|
17986
|
+
targets: [{ format: this.renderer.format, blend: blendState }]
|
|
18260
17987
|
},
|
|
18261
|
-
primitive: { topology: "
|
|
18262
|
-
depthStencil
|
|
17988
|
+
primitive: { topology: "line-list", cullMode: "none" },
|
|
17989
|
+
depthStencil: { format: this.renderer.depthFormat, depthWriteEnabled: false, depthCompare: "greater" }
|
|
18263
17990
|
});
|
|
18264
17991
|
}
|
|
18265
|
-
//
|
|
18266
|
-
|
|
18267
|
-
const
|
|
18268
|
-
const
|
|
18269
|
-
const
|
|
18270
|
-
const
|
|
18271
|
-
const
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
const
|
|
18275
|
-
const
|
|
18276
|
-
const
|
|
18277
|
-
|
|
18278
|
-
|
|
18279
|
-
|
|
18280
|
-
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
|
|
18285
|
-
|
|
18286
|
-
|
|
18287
|
-
|
|
18288
|
-
|
|
18289
|
-
|
|
18290
|
-
|
|
18291
|
-
|
|
18292
|
-
|
|
18293
|
-
|
|
18294
|
-
|
|
18295
|
-
|
|
18296
|
-
|
|
18297
|
-
|
|
18298
|
-
|
|
18299
|
-
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
|
|
17992
|
+
// ========== Box: 12 edges + grid lines on all 6 faces ==========
|
|
17993
|
+
generateBoxVertices(color) {
|
|
17994
|
+
const [lx, ly, lz] = this._volume.dimensions;
|
|
17995
|
+
const hx = lx / 2, hy = ly / 2, hz = lz / 2;
|
|
17996
|
+
const [r, g, b] = color;
|
|
17997
|
+
const v = [];
|
|
17998
|
+
const line = (x12, y12, z12, x2, y2, z2) => {
|
|
17999
|
+
v.push(x12, y12, z12, r, g, b, x2, y2, z2, r, g, b);
|
|
18000
|
+
};
|
|
18001
|
+
const x0 = -hx, x1 = hx;
|
|
18002
|
+
const y0 = -hy, y1 = hy;
|
|
18003
|
+
const z0 = -hz, z1 = hz;
|
|
18004
|
+
line(x0, y0, z0, x1, y0, z0);
|
|
18005
|
+
line(x1, y0, z0, x1, y0, z1);
|
|
18006
|
+
line(x1, y0, z1, x0, y0, z1);
|
|
18007
|
+
line(x0, y0, z1, x0, y0, z0);
|
|
18008
|
+
line(x0, y1, z0, x1, y1, z0);
|
|
18009
|
+
line(x1, y1, z0, x1, y1, z1);
|
|
18010
|
+
line(x1, y1, z1, x0, y1, z1);
|
|
18011
|
+
line(x0, y1, z1, x0, y1, z0);
|
|
18012
|
+
line(x0, y0, z0, x0, y1, z0);
|
|
18013
|
+
line(x1, y0, z0, x1, y1, z0);
|
|
18014
|
+
line(x1, y0, z1, x1, y1, z1);
|
|
18015
|
+
line(x0, y0, z1, x0, y1, z1);
|
|
18016
|
+
const n = BOX_GRID_SUBDIV;
|
|
18017
|
+
for (let i = 1; i < n; i++) {
|
|
18018
|
+
const t = i / n;
|
|
18019
|
+
const px = x0 + (x1 - x0) * t;
|
|
18020
|
+
const pz = z0 + (z1 - z0) * t;
|
|
18021
|
+
line(px, y0, z0, px, y0, z1);
|
|
18022
|
+
line(px, y1, z0, px, y1, z1);
|
|
18023
|
+
line(x0, y0, pz, x1, y0, pz);
|
|
18024
|
+
line(x0, y1, pz, x1, y1, pz);
|
|
18025
|
+
}
|
|
18026
|
+
for (let i = 1; i < n; i++) {
|
|
18027
|
+
const t = i / n;
|
|
18028
|
+
const px = x0 + (x1 - x0) * t;
|
|
18029
|
+
const py = y0 + (y1 - y0) * t;
|
|
18030
|
+
line(px, y0, z0, px, y1, z0);
|
|
18031
|
+
line(px, y0, z1, px, y1, z1);
|
|
18032
|
+
line(x0, py, z0, x1, py, z0);
|
|
18033
|
+
line(x0, py, z1, x1, py, z1);
|
|
18034
|
+
}
|
|
18035
|
+
for (let i = 1; i < n; i++) {
|
|
18036
|
+
const t = i / n;
|
|
18037
|
+
const py = y0 + (y1 - y0) * t;
|
|
18038
|
+
const pz = z0 + (z1 - z0) * t;
|
|
18039
|
+
line(x0, py, z0, x0, py, z1);
|
|
18040
|
+
line(x1, py, z0, x1, py, z1);
|
|
18041
|
+
line(x0, y0, pz, x0, y1, pz);
|
|
18042
|
+
line(x1, y0, pz, x1, y1, pz);
|
|
18043
|
+
}
|
|
18044
|
+
return new Float32Array(v);
|
|
18045
|
+
}
|
|
18046
|
+
// ========== Sphere: latitude + longitude rings ==========
|
|
18047
|
+
generateSphereVertices(color) {
|
|
18048
|
+
const radius = this._volume.dimensions[0];
|
|
18049
|
+
const [r, g, b] = color;
|
|
18050
|
+
const v = [];
|
|
18051
|
+
const addRing = (centerY, ringRadius) => {
|
|
18052
|
+
for (let i = 0; i < SEG; i++) {
|
|
18053
|
+
const a0 = i / SEG * Math.PI * 2;
|
|
18054
|
+
const a1 = (i + 1) / SEG * Math.PI * 2;
|
|
18055
|
+
v.push(
|
|
18056
|
+
Math.cos(a0) * ringRadius,
|
|
18057
|
+
centerY,
|
|
18058
|
+
Math.sin(a0) * ringRadius,
|
|
18059
|
+
r,
|
|
18060
|
+
g,
|
|
18061
|
+
b,
|
|
18062
|
+
Math.cos(a1) * ringRadius,
|
|
18063
|
+
centerY,
|
|
18064
|
+
Math.sin(a1) * ringRadius,
|
|
18065
|
+
r,
|
|
18066
|
+
g,
|
|
18067
|
+
b
|
|
18068
|
+
);
|
|
18069
|
+
}
|
|
18070
|
+
};
|
|
18071
|
+
for (let i = 0; i <= LAT_COUNT; i++) {
|
|
18072
|
+
const phi = -Math.PI / 2 + i / LAT_COUNT * Math.PI;
|
|
18073
|
+
const y = Math.sin(phi) * radius;
|
|
18074
|
+
const ringR = Math.cos(phi) * radius;
|
|
18075
|
+
if (ringR < 1e-3) continue;
|
|
18076
|
+
addRing(y, ringR);
|
|
18077
|
+
}
|
|
18078
|
+
for (let j = 0; j < LON_COUNT; j++) {
|
|
18079
|
+
const theta = j / LON_COUNT * Math.PI;
|
|
18080
|
+
for (let i = 0; i < SEG; i++) {
|
|
18081
|
+
const phi0 = i / SEG * Math.PI * 2;
|
|
18082
|
+
const phi1 = (i + 1) / SEG * Math.PI * 2;
|
|
18083
|
+
v.push(
|
|
18084
|
+
Math.sin(phi0) * Math.sin(theta) * radius,
|
|
18085
|
+
Math.cos(phi0) * radius,
|
|
18086
|
+
Math.sin(phi0) * Math.cos(theta) * radius,
|
|
18087
|
+
r,
|
|
18088
|
+
g,
|
|
18089
|
+
b,
|
|
18090
|
+
Math.sin(phi1) * Math.sin(theta) * radius,
|
|
18091
|
+
Math.cos(phi1) * radius,
|
|
18092
|
+
Math.sin(phi1) * Math.cos(theta) * radius,
|
|
18093
|
+
r,
|
|
18094
|
+
g,
|
|
18095
|
+
b
|
|
18096
|
+
);
|
|
18097
|
+
}
|
|
18098
|
+
}
|
|
18099
|
+
return new Float32Array(v);
|
|
18303
18100
|
}
|
|
18304
18101
|
render(pass) {
|
|
18305
|
-
|
|
18306
|
-
if (!vol.type || !this.uniformBuffer || !this.vertexBuffer || !this.bindGroup) return;
|
|
18307
|
-
const pipeline = vol.type === "box" ? this.boxPipeline : this.spherePipeline;
|
|
18308
|
-
if (!pipeline) return;
|
|
18102
|
+
if (!this._volume.type || !this.frontPipeline || !this.behindPipeline || !this.bindGroup || !this.vertexBuffer || !this.uniformBuffer) return;
|
|
18309
18103
|
const device = this.renderer.device;
|
|
18310
|
-
const
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
|
|
18326
|
-
|
|
18327
|
-
|
|
18328
|
-
|
|
18329
|
-
|
|
18330
|
-
|
|
18331
|
-
}
|
|
18332
|
-
|
|
18333
|
-
|
|
18334
|
-
|
|
18335
|
-
|
|
18336
|
-
|
|
18337
|
-
|
|
18338
|
-
uniforms[21] = r2;
|
|
18339
|
-
uniforms[22] = 0;
|
|
18340
|
-
uniforms[23] = 0;
|
|
18341
|
-
uniforms[24] = 0;
|
|
18342
|
-
uniforms[25] = 0;
|
|
18343
|
-
uniforms[26] = r2;
|
|
18344
|
-
uniforms[27] = 0;
|
|
18345
|
-
uniforms[28] = cx;
|
|
18346
|
-
uniforms[29] = cy;
|
|
18347
|
-
uniforms[30] = cz;
|
|
18348
|
-
uniforms[31] = 1;
|
|
18349
|
-
}
|
|
18350
|
-
const frustumBuf = new Float32Array(24);
|
|
18351
|
-
this.computeFrustumUniforms(frustumBuf);
|
|
18352
|
-
uniforms.set(frustumBuf, 32);
|
|
18353
|
-
uniforms[56] = this.renderer.width;
|
|
18354
|
-
uniforms[57] = this.renderer.height;
|
|
18355
|
-
uniforms[58] = 0;
|
|
18356
|
-
uniforms[59] = 0;
|
|
18357
|
-
if (vol.type === "box") {
|
|
18358
|
-
uniforms[60] = cx;
|
|
18359
|
-
uniforms[61] = cy;
|
|
18360
|
-
uniforms[62] = cz;
|
|
18361
|
-
uniforms[63] = 0;
|
|
18362
|
-
uniforms[64] = vol.dimensions[0] * 0.5;
|
|
18363
|
-
uniforms[65] = vol.dimensions[1] * 0.5;
|
|
18364
|
-
uniforms[66] = vol.dimensions[2] * 0.5;
|
|
18365
|
-
uniforms[67] = 0;
|
|
18366
|
-
} else {
|
|
18367
|
-
uniforms[60] = cx;
|
|
18368
|
-
uniforms[61] = cy;
|
|
18369
|
-
uniforms[62] = cz;
|
|
18370
|
-
uniforms[63] = vol.dimensions[0];
|
|
18371
|
-
uniforms[64] = 0;
|
|
18372
|
-
uniforms[65] = 0;
|
|
18373
|
-
uniforms[66] = 0;
|
|
18374
|
-
uniforms[67] = 0;
|
|
18375
|
-
}
|
|
18376
|
-
device.queue.writeBuffer(this.uniformBuffer, 0, uniforms.buffer);
|
|
18377
|
-
pass.setPipeline(pipeline);
|
|
18104
|
+
const [cx, cy, cz] = this._volume.center;
|
|
18105
|
+
const modelMatrix = new Float32Array(16);
|
|
18106
|
+
modelMatrix[0] = 1;
|
|
18107
|
+
modelMatrix[5] = 1;
|
|
18108
|
+
modelMatrix[10] = 1;
|
|
18109
|
+
modelMatrix[15] = 1;
|
|
18110
|
+
modelMatrix[12] = cx;
|
|
18111
|
+
modelMatrix[13] = cy;
|
|
18112
|
+
modelMatrix[14] = cz;
|
|
18113
|
+
const uniforms = new Float32Array(48);
|
|
18114
|
+
uniforms.set(this.camera.viewMatrix, 0);
|
|
18115
|
+
uniforms.set(this.camera.projectionMatrix, 16);
|
|
18116
|
+
uniforms.set(modelMatrix, 32);
|
|
18117
|
+
device.queue.writeBuffer(this.uniformBuffer, 0, uniforms);
|
|
18118
|
+
const frontVerts = this._volume.type === "box" ? this.generateBoxVertices(this.frontColor) : this.generateSphereVertices(this.frontColor);
|
|
18119
|
+
this.vertexCount = frontVerts.length / 6;
|
|
18120
|
+
if (this.vertexCount === 0) return;
|
|
18121
|
+
const needed = this.vertexCount * 24;
|
|
18122
|
+
if (needed > this.vertexBuffer.size) {
|
|
18123
|
+
this.vertexBuffer.destroy();
|
|
18124
|
+
this.vertexBuffer = device.createBuffer({ size: needed, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
|
|
18125
|
+
}
|
|
18126
|
+
device.queue.writeBuffer(this.vertexBuffer, 0, frontVerts.buffer);
|
|
18127
|
+
pass.setPipeline(this.frontPipeline);
|
|
18128
|
+
pass.setBindGroup(0, this.bindGroup);
|
|
18129
|
+
pass.setVertexBuffer(0, this.vertexBuffer);
|
|
18130
|
+
pass.draw(this.vertexCount);
|
|
18131
|
+
pass.setPipeline(this.behindPipeline);
|
|
18378
18132
|
pass.setBindGroup(0, this.bindGroup);
|
|
18379
18133
|
pass.setVertexBuffer(0, this.vertexBuffer);
|
|
18380
|
-
pass.draw(
|
|
18134
|
+
pass.draw(this.vertexCount);
|
|
18381
18135
|
}
|
|
18382
18136
|
destroy() {
|
|
18383
18137
|
var _a2, _b2;
|
|
@@ -18385,8 +18139,8 @@ class SelectionVolumeRenderer {
|
|
|
18385
18139
|
(_b2 = this.uniformBuffer) == null ? void 0 : _b2.destroy();
|
|
18386
18140
|
this.vertexBuffer = null;
|
|
18387
18141
|
this.uniformBuffer = null;
|
|
18388
|
-
this.
|
|
18389
|
-
this.
|
|
18142
|
+
this.frontPipeline = null;
|
|
18143
|
+
this.behindPipeline = null;
|
|
18390
18144
|
this.bindGroup = null;
|
|
18391
18145
|
}
|
|
18392
18146
|
}
|