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