@d5techs/3dgs-lib 1.4.76 → 1.4.77

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.js CHANGED
@@ -17577,7 +17577,7 @@ class SphereSelection {
17577
17577
  this.toolbar = document.createElement("div");
17578
17578
  this.toolbar.className = "volume-select-toolbar";
17579
17579
  this.toolbar.style.cssText = `
17580
- position:absolute; bottom:12px; left:50%; transform:translateX(-50%);
17580
+ position:absolute; bottom:90px; left:50%; transform:translateX(-50%);
17581
17581
  display:none; z-index:20; background:rgba(30,30,30,0.92);
17582
17582
  border-radius:8px; padding:6px 10px; gap:6px;
17583
17583
  align-items:center; font-size:13px; color:#ddd;
@@ -17668,7 +17668,7 @@ class BoxSelection {
17668
17668
  this.toolbar = document.createElement("div");
17669
17669
  this.toolbar.className = "volume-select-toolbar";
17670
17670
  this.toolbar.style.cssText = `
17671
- position:absolute; bottom:12px; left:50%; transform:translateX(-50%);
17671
+ position:absolute; bottom:90px; left:50%; transform:translateX(-50%);
17672
17672
  display:none; z-index:20; background:rgba(30,30,30,0.92);
17673
17673
  border-radius:8px; padding:6px 10px; gap:6px;
17674
17674
  align-items:center; font-size:13px; color:#ddd;
@@ -18152,9 +18152,17 @@ class SplatEditor {
18152
18152
  this.toolOverlay.style.display = name && !isVolumeTool ? "block" : "none";
18153
18153
  if (isVolumeTool && this.volumeRenderer) {
18154
18154
  const volType = name;
18155
- const center = this.getModelCenter();
18156
- const dims = volType === "box" ? [this.boxTool.lenX, this.boxTool.lenY, this.boxTool.lenZ] : [this.sphereTool.radius, 0, 0];
18157
- this.volumeRenderer.setVolume(volType, center, dims);
18155
+ const bounds = this.getModelBounds();
18156
+ const defaultSize = Math.max(bounds.size[0], bounds.size[1], bounds.size[2]) * 0.3;
18157
+ const safeSize = Math.max(defaultSize, 0.5);
18158
+ if (volType === "box") {
18159
+ this.boxTool.setDimensions(safeSize, safeSize, safeSize);
18160
+ this.volumeRenderer.setVolume("box", bounds.center, [safeSize, safeSize, safeSize]);
18161
+ } else {
18162
+ const r = safeSize / 2;
18163
+ this.sphereTool.setRadius(r);
18164
+ this.volumeRenderer.setVolume("sphere", bounds.center, [r, 0, 0]);
18165
+ }
18158
18166
  (_b2 = (_a2 = this.callbacks).onVolumeToolActivated) == null ? void 0 : _b2.call(_a2, this.volumeRenderer.volume);
18159
18167
  } else {
18160
18168
  if (this.volumeRenderer) this.volumeRenderer.setVolume(null);
@@ -18571,24 +18579,36 @@ class SplatEditor {
18571
18579
  };
18572
18580
  }
18573
18581
  /**
18574
- * 获取模型包围盒中心(世界空间)
18582
+ * 获取模型世界空间包围盒(中心 + 尺寸)
18575
18583
  */
18576
- getModelCenter() {
18584
+ getModelBounds() {
18577
18585
  const cpuPos = this.gsRenderer.getCPUPositions();
18578
- if (!cpuPos || cpuPos.length === 0) return [0, 0, 0];
18586
+ if (!cpuPos || cpuPos.length === 0) return { center: [0, 0, 0], size: [2, 2, 2] };
18579
18587
  const modelMat = this.gsRenderer.getModelMatrix();
18580
18588
  const count = this.splatState.count;
18581
- let sx = 0, sy = 0, sz = 0, n = 0;
18582
- const step = Math.max(1, Math.floor(count / 1e3));
18589
+ let minX = Infinity, minY = Infinity, minZ = Infinity;
18590
+ let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
18591
+ const step = Math.max(1, Math.floor(count / 2e3));
18583
18592
  for (let i = 0; i < count; i += step) {
18584
18593
  const i3 = i * 3;
18585
18594
  const lx = cpuPos[i3], ly = cpuPos[i3 + 1], lz = cpuPos[i3 + 2];
18586
- sx += modelMat[0] * lx + modelMat[4] * ly + modelMat[8] * lz + modelMat[12];
18587
- sy += modelMat[1] * lx + modelMat[5] * ly + modelMat[9] * lz + modelMat[13];
18588
- sz += modelMat[2] * lx + modelMat[6] * ly + modelMat[10] * lz + modelMat[14];
18589
- n++;
18595
+ const wx = modelMat[0] * lx + modelMat[4] * ly + modelMat[8] * lz + modelMat[12];
18596
+ const wy = modelMat[1] * lx + modelMat[5] * ly + modelMat[9] * lz + modelMat[13];
18597
+ const wz = modelMat[2] * lx + modelMat[6] * ly + modelMat[10] * lz + modelMat[14];
18598
+ if (wx < minX) minX = wx;
18599
+ if (wx > maxX) maxX = wx;
18600
+ if (wy < minY) minY = wy;
18601
+ if (wy > maxY) maxY = wy;
18602
+ if (wz < minZ) minZ = wz;
18603
+ if (wz > maxZ) maxZ = wz;
18590
18604
  }
18591
- return n > 0 ? [sx / n, sy / n, sz / n] : [0, 0, 0];
18605
+ return {
18606
+ center: [(minX + maxX) / 2, (minY + maxY) / 2, (minZ + maxZ) / 2],
18607
+ size: [maxX - minX, maxY - minY, maxZ - minZ]
18608
+ };
18609
+ }
18610
+ getModelCenter() {
18611
+ return this.getModelBounds().center;
18592
18612
  }
18593
18613
  /**
18594
18614
  * 根据屏幕像素坐标,找到最近的可见 splat 并返回其世界坐标及深度换算系数