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