3dtiles-inspector 0.2.2 → 0.2.3

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.
@@ -67954,6 +67954,15 @@ function clientPointToNdc(point, domRect) {
67954
67954
  y: 1 - (point.y - domRect.top) / domRect.height * 2
67955
67955
  };
67956
67956
  }
67957
+ function getClientSelectionQuad(start, end) {
67958
+ const clientRect = getClientSelectionRect(start, end);
67959
+ return [
67960
+ new Vector2(clientRect.minX, clientRect.minY),
67961
+ new Vector2(clientRect.maxX, clientRect.minY),
67962
+ new Vector2(clientRect.maxX, clientRect.maxY),
67963
+ new Vector2(clientRect.minX, clientRect.maxY)
67964
+ ];
67965
+ }
67957
67966
  function getNdcSelectionRect(clientRect, domRect) {
67958
67967
  const topLeft = clientPointToNdc(
67959
67968
  new Vector2(clientRect.minX, clientRect.minY),
@@ -67970,6 +67979,19 @@ function getNdcSelectionRect(clientRect, domRect) {
67970
67979
  maxY: Math.max(topLeft.y, bottomRight.y)
67971
67980
  };
67972
67981
  }
67982
+ function getNdcSelectionQuad(clientPoints, domRect) {
67983
+ return clientPoints.map((point) => clientPointToNdc(point, domRect));
67984
+ }
67985
+ function getNdcBounds(points) {
67986
+ const xs2 = points.map((point) => point.x);
67987
+ const ys2 = points.map((point) => point.y);
67988
+ return {
67989
+ maxX: Math.max(...xs2),
67990
+ maxY: Math.max(...ys2),
67991
+ minX: Math.min(...xs2),
67992
+ minY: Math.min(...ys2)
67993
+ };
67994
+ }
67973
67995
  function updateOverlayRect(overlayEl, rectEl, clientRect) {
67974
67996
  if (!overlayEl || !rectEl) {
67975
67997
  return;
@@ -68151,10 +68173,10 @@ function createFarPlaneData({
68151
68173
  width
68152
68174
  };
68153
68175
  }
68154
- function createFrustumData(camera, rect, depthRange) {
68176
+ function createFrustumDataFromQuad(camera, quad, depthRange) {
68155
68177
  const { farDepth, nearDepth } = normalizeDepthRange(camera, depthRange);
68156
- const centerX = (rect.minX + rect.maxX) * 0.5;
68157
- const centerY = (rect.minY + rect.maxY) * 0.5;
68178
+ const centerX = quad.reduce((total, point) => total + point.x, 0) / quad.length;
68179
+ const centerY = quad.reduce((total, point) => total + point.y, 0) / quad.length;
68158
68180
  const nearCenter = createPointAtViewDepth(
68159
68181
  camera,
68160
68182
  centerX,
@@ -68181,55 +68203,13 @@ function createFrustumData(camera, rect, depthRange) {
68181
68203
  const insidePoint = selectionForward.clone().multiplyScalar((nearDistance + farDistance) * 0.5).add(camera.position);
68182
68204
  plane.setFromNormalAndCoplanarPoint(selectionForward, farCenter);
68183
68205
  const farClipPlane = plane.clone();
68184
- const farTopLeft = createPointOnPlane(
68185
- camera,
68186
- rect.minX,
68187
- rect.maxY,
68188
- farClipPlane
68189
- );
68190
- const farTopRight = createPointOnPlane(
68191
- camera,
68192
- rect.maxX,
68193
- rect.maxY,
68194
- farClipPlane
68195
- );
68196
- const farBottomRight = createPointOnPlane(
68197
- camera,
68198
- rect.maxX,
68199
- rect.minY,
68200
- farClipPlane
68201
- );
68202
- const farBottomLeft = createPointOnPlane(
68203
- camera,
68204
- rect.minX,
68205
- rect.minY,
68206
- farClipPlane
68206
+ const [farTopLeft, farTopRight, farBottomRight, farBottomLeft] = quad.map(
68207
+ (point) => createPointOnPlane(camera, point.x, point.y, farClipPlane)
68207
68208
  );
68208
68209
  plane.setFromNormalAndCoplanarPoint(selectionForward, nearCenter);
68209
68210
  const nearPlane = plane.clone();
68210
- const nearTopLeft = createPointOnPlane(
68211
- camera,
68212
- rect.minX,
68213
- rect.maxY,
68214
- nearPlane
68215
- );
68216
- const nearTopRight = createPointOnPlane(
68217
- camera,
68218
- rect.maxX,
68219
- rect.maxY,
68220
- nearPlane
68221
- );
68222
- const nearBottomRight = createPointOnPlane(
68223
- camera,
68224
- rect.maxX,
68225
- rect.minY,
68226
- nearPlane
68227
- );
68228
- const nearBottomLeft = createPointOnPlane(
68229
- camera,
68230
- rect.minX,
68231
- rect.minY,
68232
- nearPlane
68211
+ const [nearTopLeft, nearTopRight, nearBottomRight, nearBottomLeft] = quad.map(
68212
+ (point) => createPointOnPlane(camera, point.x, point.y, nearPlane)
68233
68213
  );
68234
68214
  if (!farTopLeft || !farTopRight || !farBottomRight || !farBottomLeft || !nearTopLeft || !nearTopRight || !nearBottomRight || !nearBottomLeft) {
68235
68215
  return null;
@@ -68306,8 +68286,21 @@ function createFrustumData(camera, rect, depthRange) {
68306
68286
  selectionForward: selectionForward.toArray()
68307
68287
  };
68308
68288
  }
68289
+ function createFrustumData(camera, rect, depthRange) {
68290
+ return createFrustumDataFromQuad(
68291
+ camera,
68292
+ [
68293
+ { x: rect.minX, y: rect.maxY },
68294
+ { x: rect.maxX, y: rect.maxY },
68295
+ { x: rect.maxX, y: rect.minY },
68296
+ { x: rect.minX, y: rect.minY }
68297
+ ],
68298
+ depthRange
68299
+ );
68300
+ }
68309
68301
  function createSelectionData({
68310
68302
  camera,
68303
+ clientPoints,
68311
68304
  domElement,
68312
68305
  end,
68313
68306
  getDepthRange,
@@ -68317,19 +68310,27 @@ function createSelectionData({
68317
68310
  if (domRect.width <= 0 || domRect.height <= 0) {
68318
68311
  return null;
68319
68312
  }
68320
- const clientRect = getClientSelectionRect(start, end);
68313
+ const hasClientQuad = Array.isArray(clientPoints) && clientPoints.length === 4;
68314
+ const points = hasClientQuad ? clientPoints : getClientSelectionQuad(start, end);
68315
+ const clientRect = {
68316
+ maxX: Math.max(...points.map((point) => point.x)),
68317
+ maxY: Math.max(...points.map((point) => point.y)),
68318
+ minX: Math.min(...points.map((point) => point.x)),
68319
+ minY: Math.min(...points.map((point) => point.y))
68320
+ };
68321
68321
  const width = clientRect.maxX - clientRect.minX;
68322
68322
  const height = clientRect.maxY - clientRect.minY;
68323
68323
  if (width * width + height * height < SCREEN_SELECTION_MIN_DRAG_DISTANCE_SQ) {
68324
68324
  return null;
68325
68325
  }
68326
- const rect = getNdcSelectionRect(clientRect, domRect);
68326
+ const quad = getNdcSelectionQuad(points, domRect);
68327
+ const rect = hasClientQuad ? getNdcBounds(quad) : getNdcSelectionRect(clientRect, domRect);
68327
68328
  camera.updateProjectionMatrix();
68328
68329
  camera.updateMatrixWorld(true);
68329
68330
  cameraPosition.copy(camera.position);
68330
68331
  const depthRange = normalizeDepthRange(camera, getDepthRange());
68331
68332
  const viewProjectionMatrix = new Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse).toArray();
68332
- const frustum = createFrustumData(camera, rect, depthRange);
68333
+ const frustum = hasClientQuad ? createFrustumDataFromQuad(camera, quad, depthRange) : createFrustumData(camera, rect, depthRange);
68333
68334
  if (!frustum) {
68334
68335
  return null;
68335
68336
  }
@@ -68687,6 +68688,8 @@ function createScreenSelectionPointerTracker({
68687
68688
  camera,
68688
68689
  domElement,
68689
68690
  getDepthRange,
68691
+ onOverlayClear,
68692
+ onOverlayUpdate,
68690
68693
  onSelectionCreated,
68691
68694
  overlayEl,
68692
68695
  rectEl
@@ -68695,8 +68698,18 @@ function createScreenSelectionPointerTracker({
68695
68698
  let drag = null;
68696
68699
  function clearDrag() {
68697
68700
  drag = null;
68701
+ onOverlayClear?.();
68698
68702
  clearOverlay(overlayEl, rectEl);
68699
68703
  }
68704
+ function updateDragOverlay() {
68705
+ const clientRect = {
68706
+ ...getClientSelectionRect(drag.start, drag.current)
68707
+ };
68708
+ if (onOverlayUpdate?.(clientRect) === true) {
68709
+ return;
68710
+ }
68711
+ updateOverlayRect(overlayEl, rectEl, clientRect);
68712
+ }
68700
68713
  function setActive(nextActive) {
68701
68714
  active = !!nextActive;
68702
68715
  if (!active) {
@@ -68715,11 +68728,7 @@ function createScreenSelectionPointerTracker({
68715
68728
  start: dragStart.clone(),
68716
68729
  current: dragCurrent.clone()
68717
68730
  };
68718
- updateOverlayRect(
68719
- overlayEl,
68720
- rectEl,
68721
- getClientSelectionRect(drag.start, drag.current)
68722
- );
68731
+ updateDragOverlay();
68723
68732
  domElement.setPointerCapture?.(event.pointerId);
68724
68733
  event.preventDefault();
68725
68734
  event.stopPropagation();
@@ -68731,11 +68740,7 @@ function createScreenSelectionPointerTracker({
68731
68740
  }
68732
68741
  const domRect = domElement.getBoundingClientRect();
68733
68742
  getClampedClientPoint(event, domRect, drag.current);
68734
- updateOverlayRect(
68735
- overlayEl,
68736
- rectEl,
68737
- getClientSelectionRect(drag.start, drag.current)
68738
- );
68743
+ updateDragOverlay();
68739
68744
  event.preventDefault();
68740
68745
  event.stopPropagation();
68741
68746
  return true;
@@ -68744,6 +68749,9 @@ function createScreenSelectionPointerTracker({
68744
68749
  if (!active || !drag || event.pointerId !== drag.pointerId) {
68745
68750
  return false;
68746
68751
  }
68752
+ const clientRect = {
68753
+ ...getClientSelectionRect(drag.start, drag.current)
68754
+ };
68747
68755
  const selection = createSelectionData({
68748
68756
  camera,
68749
68757
  domElement,
@@ -68753,7 +68761,7 @@ function createScreenSelectionPointerTracker({
68753
68761
  });
68754
68762
  domElement.releasePointerCapture?.(event.pointerId);
68755
68763
  clearDrag();
68756
- onSelectionCreated(selection);
68764
+ onSelectionCreated(selection, clientRect);
68757
68765
  event.preventDefault();
68758
68766
  event.stopPropagation();
68759
68767
  return true;
@@ -68832,6 +68840,56 @@ function getScreenSelectionPayload(selection) {
68832
68840
  viewProjectionMatrix: selection.viewProjectionMatrix.slice()
68833
68841
  };
68834
68842
  }
68843
+ function setScreenSelectionShape(selection, {
68844
+ cameraPosition: sourceCameraPosition,
68845
+ depthRange,
68846
+ farPlane,
68847
+ planeMatrices,
68848
+ rect,
68849
+ selectionForward: sourceSelectionForward,
68850
+ viewProjectionMatrix
68851
+ }, currentTransformMatrix) {
68852
+ if (!selection) {
68853
+ return;
68854
+ }
68855
+ const previousFarDepth = Number(selection.depthRange?.farDepth);
68856
+ const copiedPlaneMatrices = planeMatrices.map((matrix) => matrix.slice());
68857
+ const referenceTransformMatrix = copyMatrix4Array(currentTransformMatrix);
68858
+ selection.basePlaneMatrices = copiedPlaneMatrices.map(
68859
+ (matrix) => matrix.slice()
68860
+ );
68861
+ selection.cameraPosition = copyVectorArray(sourceCameraPosition);
68862
+ selection.currentTransformMatrix = referenceTransformMatrix.slice();
68863
+ selection.depthRange = copyDepthRange(depthRange);
68864
+ selection.farPlane = copyFarPlane(farPlane);
68865
+ selection.planeMatrices = copiedPlaneMatrices;
68866
+ selection.referenceTransformMatrix = referenceTransformMatrix;
68867
+ selection.rect = copyRect(rect);
68868
+ selection.selectionForward = copyVectorArray(sourceSelectionForward, [
68869
+ 0,
68870
+ 0,
68871
+ -1
68872
+ ]);
68873
+ selection.viewProjectionMatrix = viewProjectionMatrix.slice();
68874
+ updateScreenSelectionWorldState(selection, currentTransformMatrix);
68875
+ if (!Number.isFinite(previousFarDepth)) {
68876
+ return;
68877
+ }
68878
+ const nextFarDepth = Math.min(
68879
+ selection.depthRange.maxFarDepth,
68880
+ Math.max(
68881
+ selection.depthRange.nearDepth + SCREEN_SELECTION_MIN_DEPTH_RANGE,
68882
+ previousFarDepth
68883
+ )
68884
+ );
68885
+ if (Math.abs(nextFarDepth - selection.depthRange.farDepth) > 1e-9) {
68886
+ setScreenSelectionFarDepth(
68887
+ selection,
68888
+ nextFarDepth,
68889
+ currentTransformMatrix
68890
+ );
68891
+ }
68892
+ }
68835
68893
  function updateScreenSelectionWorldState(selection, currentTransformMatrix, active = selection?.farHandle?.visible) {
68836
68894
  if (!selection) {
68837
68895
  return;
@@ -68876,6 +68934,313 @@ var init_screenSelection = __esm({
68876
68934
  }
68877
68935
  });
68878
68936
 
68937
+ // src/viewer/screenSelection/editOverlay.js
68938
+ function clampValue(value, min, max) {
68939
+ return Math.min(max, Math.max(min, value));
68940
+ }
68941
+ function copyClientPoint(point) {
68942
+ return {
68943
+ x: Number(point?.x) || 0,
68944
+ y: Number(point?.y) || 0
68945
+ };
68946
+ }
68947
+ function copyClientPoints(points) {
68948
+ return points.map(copyClientPoint);
68949
+ }
68950
+ function getClientPointsBounds(points) {
68951
+ const xs2 = points.map((point) => point.x);
68952
+ const ys2 = points.map((point) => point.y);
68953
+ return {
68954
+ maxX: Math.max(...xs2),
68955
+ maxY: Math.max(...ys2),
68956
+ minX: Math.min(...xs2),
68957
+ minY: Math.min(...ys2)
68958
+ };
68959
+ }
68960
+ function getClientRectPoints(rect) {
68961
+ return [
68962
+ { x: Number(rect?.minX) || 0, y: Number(rect?.minY) || 0 },
68963
+ { x: Number(rect?.maxX) || 0, y: Number(rect?.minY) || 0 },
68964
+ { x: Number(rect?.maxX) || 0, y: Number(rect?.maxY) || 0 },
68965
+ { x: Number(rect?.minX) || 0, y: Number(rect?.maxY) || 0 }
68966
+ ];
68967
+ }
68968
+ function clampClientPoint(point, domRect) {
68969
+ return {
68970
+ x: clampValue(point.x, domRect.left, domRect.right),
68971
+ y: clampValue(point.y, domRect.top, domRect.bottom)
68972
+ };
68973
+ }
68974
+ function clampClientPoints(points, domElement) {
68975
+ const domRect = domElement.getBoundingClientRect();
68976
+ return points.map((point) => clampClientPoint(point, domRect));
68977
+ }
68978
+ function getPointTurnCross(a2, b5, c2) {
68979
+ return (b5.x - a2.x) * (c2.y - b5.y) - (b5.y - a2.y) * (c2.x - b5.x);
68980
+ }
68981
+ function isConvexClientQuad(points) {
68982
+ if (!Array.isArray(points) || points.length !== 4) {
68983
+ return false;
68984
+ }
68985
+ let turnSign = 0;
68986
+ for (let index = 0; index < points.length; index++) {
68987
+ const cross = getPointTurnCross(
68988
+ points[index],
68989
+ points[(index + 1) % points.length],
68990
+ points[(index + 2) % points.length]
68991
+ );
68992
+ if (Math.abs(cross) <= SCREEN_EDIT_MIN_CONVEX_CROSS_ABS) {
68993
+ return false;
68994
+ }
68995
+ const nextSign = Math.sign(cross);
68996
+ if (turnSign === 0) {
68997
+ turnSign = nextSign;
68998
+ } else if (nextSign !== turnSign) {
68999
+ return false;
69000
+ }
69001
+ }
69002
+ return true;
69003
+ }
69004
+ function getPartPoint(points, part) {
69005
+ const indices = SCREEN_EDIT_PART_POINT_INDICES[part] || [];
69006
+ if (indices.length === 0) {
69007
+ return { x: 0, y: 0 };
69008
+ }
69009
+ const x5 = indices.reduce((total, index) => total + points[index].x, 0) / indices.length;
69010
+ const y6 = indices.reduce((total, index) => total + points[index].y, 0) / indices.length;
69011
+ return { x: x5, y: y6 };
69012
+ }
69013
+ function getPartAngle(points, part) {
69014
+ const indices = SCREEN_EDIT_PART_POINT_INDICES[part] || [];
69015
+ if (indices.length !== 2) {
69016
+ return null;
69017
+ }
69018
+ const start = points[indices[0]];
69019
+ const end = points[indices[1]];
69020
+ return Math.atan2(end.y - start.y, end.x - start.x);
69021
+ }
69022
+ function getPartLength(points, part) {
69023
+ const indices = SCREEN_EDIT_PART_POINT_INDICES[part] || [];
69024
+ if (indices.length !== 2) {
69025
+ return null;
69026
+ }
69027
+ const start = points[indices[0]];
69028
+ const end = points[indices[1]];
69029
+ return Math.hypot(end.x - start.x, end.y - start.y);
69030
+ }
69031
+ function interpolatePoint(a2, b5, t2) {
69032
+ return {
69033
+ x: a2.x + (b5.x - a2.x) * t2,
69034
+ y: a2.y + (b5.y - a2.y) * t2
69035
+ };
69036
+ }
69037
+ function updateScreenEditGrid(grid, localPoints, visible) {
69038
+ if (!grid) {
69039
+ return;
69040
+ }
69041
+ grid.replaceChildren();
69042
+ grid.hidden = !visible;
69043
+ if (!visible) {
69044
+ return;
69045
+ }
69046
+ const [topLeft, topRight, bottomRight, bottomLeft] = localPoints;
69047
+ for (let index = 1; index < SCREEN_EDIT_GRID_DIVISIONS; index++) {
69048
+ const t2 = index / SCREEN_EDIT_GRID_DIVISIONS;
69049
+ const top = interpolatePoint(topLeft, topRight, t2);
69050
+ const bottom = interpolatePoint(bottomLeft, bottomRight, t2);
69051
+ const left = interpolatePoint(topLeft, bottomLeft, t2);
69052
+ const right = interpolatePoint(topRight, bottomRight, t2);
69053
+ const verticalLine = document.createElementNS(
69054
+ "http://www.w3.org/2000/svg",
69055
+ "line"
69056
+ );
69057
+ const horizontalLine = document.createElementNS(
69058
+ "http://www.w3.org/2000/svg",
69059
+ "line"
69060
+ );
69061
+ verticalLine.setAttribute("x1", String(top.x));
69062
+ verticalLine.setAttribute("y1", String(top.y));
69063
+ verticalLine.setAttribute("x2", String(bottom.x));
69064
+ verticalLine.setAttribute("y2", String(bottom.y));
69065
+ horizontalLine.setAttribute("x1", String(left.x));
69066
+ horizontalLine.setAttribute("y1", String(left.y));
69067
+ horizontalLine.setAttribute("x2", String(right.x));
69068
+ horizontalLine.setAttribute("y2", String(right.y));
69069
+ grid.append(verticalLine, horizontalLine);
69070
+ }
69071
+ }
69072
+ function ensureEditableRectHandles(rectEl) {
69073
+ if (!rectEl || rectEl.dataset.editHandlesReady === "true") {
69074
+ return;
69075
+ }
69076
+ const svg2 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
69077
+ const polygon = document.createElementNS(
69078
+ "http://www.w3.org/2000/svg",
69079
+ "polygon"
69080
+ );
69081
+ const grid = document.createElementNS("http://www.w3.org/2000/svg", "g");
69082
+ svg2.classList.add("screen-selection-edit-svg");
69083
+ grid.classList.add("screen-selection-edit-grid");
69084
+ polygon.classList.add("screen-selection-edit-polygon");
69085
+ svg2.append(polygon, grid);
69086
+ rectEl.appendChild(svg2);
69087
+ SCREEN_EDIT_HANDLE_PARTS.forEach((part) => {
69088
+ const handle = document.createElement("span");
69089
+ handle.classList.add(
69090
+ "screen-selection-edit-handle",
69091
+ `screen-selection-edit-${part}`
69092
+ );
69093
+ handle.dataset.editPart = part;
69094
+ rectEl.appendChild(handle);
69095
+ });
69096
+ rectEl.dataset.editHandlesReady = "true";
69097
+ }
69098
+ function pointSegmentDistanceSq(point, start, end) {
69099
+ const dx = end.x - start.x;
69100
+ const dy = end.y - start.y;
69101
+ const lengthSq = dx * dx + dy * dy;
69102
+ if (lengthSq <= 1e-12) {
69103
+ const px2 = point.x - start.x;
69104
+ const py2 = point.y - start.y;
69105
+ return px2 * px2 + py2 * py2;
69106
+ }
69107
+ const t2 = clampValue(
69108
+ ((point.x - start.x) * dx + (point.y - start.y) * dy) / lengthSq,
69109
+ 0,
69110
+ 1
69111
+ );
69112
+ const x5 = start.x + dx * t2;
69113
+ const y6 = start.y + dy * t2;
69114
+ const px = point.x - x5;
69115
+ const py = point.y - y6;
69116
+ return px * px + py * py;
69117
+ }
69118
+ function createScreenEditOverlay({ overlayEl, rectEl }) {
69119
+ let activePart = null;
69120
+ function applyActivePart() {
69121
+ SCREEN_EDIT_HANDLE_PARTS.forEach((part) => {
69122
+ const handle = rectEl?.querySelector(`[data-edit-part="${part}"]`);
69123
+ handle?.classList.toggle("active", part === activePart);
69124
+ });
69125
+ }
69126
+ function render(clientPoints, { showGrid = false } = {}) {
69127
+ ensureEditableRectHandles(rectEl);
69128
+ rectEl?.classList.add("editable");
69129
+ rectEl?.classList.toggle("drawing", showGrid);
69130
+ const bounds = getClientPointsBounds(clientPoints);
69131
+ updateOverlayRect(overlayEl, rectEl, bounds);
69132
+ const width = Math.max(1, bounds.maxX - bounds.minX);
69133
+ const height = Math.max(1, bounds.maxY - bounds.minY);
69134
+ const localPoints = clientPoints.map((point) => ({
69135
+ x: point.x - bounds.minX,
69136
+ y: point.y - bounds.minY
69137
+ }));
69138
+ const svg2 = rectEl?.querySelector(".screen-selection-edit-svg");
69139
+ const polygon = rectEl?.querySelector(".screen-selection-edit-polygon");
69140
+ const grid = rectEl?.querySelector(".screen-selection-edit-grid");
69141
+ svg2?.setAttribute("viewBox", `0 0 ${width} ${height}`);
69142
+ polygon?.setAttribute(
69143
+ "points",
69144
+ localPoints.map((point) => `${point.x},${point.y}`).join(" ")
69145
+ );
69146
+ updateScreenEditGrid(grid, localPoints, showGrid);
69147
+ SCREEN_EDIT_HANDLE_PARTS.forEach((part) => {
69148
+ const point = getPartPoint(localPoints, part);
69149
+ const handle = rectEl?.querySelector(`[data-edit-part="${part}"]`);
69150
+ if (!handle) {
69151
+ return;
69152
+ }
69153
+ handle.style.left = `${point.x}px`;
69154
+ handle.style.top = `${point.y}px`;
69155
+ const angle = getPartAngle(localPoints, part);
69156
+ const length = getPartLength(localPoints, part);
69157
+ if (length != null) {
69158
+ const maxVisualLength = Math.max(0, length - 2);
69159
+ const visualLength = Math.max(
69160
+ 0,
69161
+ Math.min(SCREEN_EDIT_EDGE_HANDLE_MAX_LENGTH, maxVisualLength)
69162
+ );
69163
+ const activeScaleX = visualLength > 0 ? Math.min(
69164
+ SCREEN_EDIT_EDGE_HANDLE_ACTIVE_SCALE_X,
69165
+ Math.max(1, maxVisualLength / visualLength)
69166
+ ) : 1;
69167
+ handle.style.width = `${visualLength}px`;
69168
+ handle.style.height = `${length <= SCREEN_EDIT_EDGE_HANDLE_MIN_LENGTH ? 2 : 4}px`;
69169
+ handle.style.setProperty(
69170
+ "--screen-selection-edit-active-scale-x",
69171
+ String(activeScaleX)
69172
+ );
69173
+ handle.style.setProperty(
69174
+ "--screen-selection-edit-active-scale-y",
69175
+ String(SCREEN_EDIT_EDGE_HANDLE_ACTIVE_SCALE_Y)
69176
+ );
69177
+ } else {
69178
+ handle.style.width = "";
69179
+ handle.style.height = "";
69180
+ handle.style.removeProperty("--screen-selection-edit-active-scale-x");
69181
+ handle.style.removeProperty("--screen-selection-edit-active-scale-y");
69182
+ }
69183
+ handle.style.transform = angle == null ? "translate(-50%, -50%)" : `translate(-50%, -50%) rotate(${angle}rad)`;
69184
+ });
69185
+ applyActivePart();
69186
+ }
69187
+ function clear() {
69188
+ activePart = null;
69189
+ rectEl?.classList.remove("drawing", "editable");
69190
+ applyActivePart();
69191
+ }
69192
+ function setActivePart(part) {
69193
+ activePart = SCREEN_EDIT_HANDLE_PARTS.includes(part) ? part : null;
69194
+ applyActivePart();
69195
+ }
69196
+ return {
69197
+ clear,
69198
+ render,
69199
+ setActivePart
69200
+ };
69201
+ }
69202
+ var SCREEN_EDIT_EDGE_HIT_SIZE, SCREEN_EDIT_CORNER_HIT_SIZE, SCREEN_EDIT_EDGE_HANDLE_MAX_LENGTH, SCREEN_EDIT_EDGE_HANDLE_MIN_LENGTH, SCREEN_EDIT_EDGE_HANDLE_ACTIVE_SCALE_X, SCREEN_EDIT_EDGE_HANDLE_ACTIVE_SCALE_Y, SCREEN_EDIT_GRID_DIVISIONS, SCREEN_EDIT_MIN_CONVEX_CROSS_ABS, SCREEN_EDIT_HANDLE_PARTS, SCREEN_EDIT_CORNER_PARTS, SCREEN_EDIT_EDGE_PARTS, SCREEN_EDIT_PART_POINT_INDICES;
69203
+ var init_editOverlay = __esm({
69204
+ "src/viewer/screenSelection/editOverlay.js"() {
69205
+ init_geometry();
69206
+ SCREEN_EDIT_EDGE_HIT_SIZE = 8;
69207
+ SCREEN_EDIT_CORNER_HIT_SIZE = 16;
69208
+ SCREEN_EDIT_EDGE_HANDLE_MAX_LENGTH = 26;
69209
+ SCREEN_EDIT_EDGE_HANDLE_MIN_LENGTH = 6;
69210
+ SCREEN_EDIT_EDGE_HANDLE_ACTIVE_SCALE_X = 1.5;
69211
+ SCREEN_EDIT_EDGE_HANDLE_ACTIVE_SCALE_Y = 1.5;
69212
+ SCREEN_EDIT_GRID_DIVISIONS = 8;
69213
+ SCREEN_EDIT_MIN_CONVEX_CROSS_ABS = 1e-3;
69214
+ SCREEN_EDIT_HANDLE_PARTS = [
69215
+ "top-left",
69216
+ "top",
69217
+ "top-right",
69218
+ "right",
69219
+ "bottom-right",
69220
+ "bottom",
69221
+ "bottom-left",
69222
+ "left"
69223
+ ];
69224
+ SCREEN_EDIT_CORNER_PARTS = [
69225
+ "top-left",
69226
+ "top-right",
69227
+ "bottom-right",
69228
+ "bottom-left"
69229
+ ];
69230
+ SCREEN_EDIT_EDGE_PARTS = ["top", "right", "bottom", "left"];
69231
+ SCREEN_EDIT_PART_POINT_INDICES = {
69232
+ "bottom-left": [3],
69233
+ "bottom-right": [2],
69234
+ bottom: [2, 3],
69235
+ left: [3, 0],
69236
+ right: [1, 2],
69237
+ top: [0, 1],
69238
+ "top-left": [0],
69239
+ "top-right": [1]
69240
+ };
69241
+ }
69242
+ });
69243
+
68879
69244
  // src/viewer/dom/cropUi.js
68880
69245
  function updateCropControls({
68881
69246
  activeScreenSelectionId,
@@ -68993,9 +69358,13 @@ function createCropController({
68993
69358
  let nextSelectionId = 1;
68994
69359
  let activeSelectionId = null;
68995
69360
  let pendingMode = false;
69361
+ let pendingScreenEdit = null;
69362
+ let pendingEditDrag = null;
69363
+ let editCursor = "";
68996
69364
  let hasGaussianSplats = false;
68997
69365
  const sphere = new Sphere();
68998
69366
  const cameraForward2 = new Vector3();
69367
+ const screenEditOverlay = createScreenEditOverlay({ overlayEl, rectEl });
68999
69368
  function getActiveSelection() {
69000
69369
  if (activeSelectionId == null) {
69001
69370
  return null;
@@ -69011,6 +69380,115 @@ function createCropController({
69011
69380
  }))
69012
69381
  ];
69013
69382
  }
69383
+ function setEditCursor(cursor) {
69384
+ const nextCursor = cursor || "";
69385
+ if (editCursor === nextCursor) {
69386
+ return;
69387
+ }
69388
+ domElement.style.cursor = nextCursor;
69389
+ editCursor = nextCursor;
69390
+ }
69391
+ function clearEditCursor() {
69392
+ setEditCursor("");
69393
+ }
69394
+ function getActivePendingEdit() {
69395
+ if (!pendingScreenEdit || activeSelectionId !== pendingScreenEdit.selectionId) {
69396
+ return null;
69397
+ }
69398
+ const match = pendingSelections.find(
69399
+ (selection) => selection.id === pendingScreenEdit.selectionId
69400
+ );
69401
+ return match ? pendingScreenEdit : null;
69402
+ }
69403
+ function clearScreenEditOverlay() {
69404
+ screenEditOverlay.clear();
69405
+ clearEditCursor();
69406
+ }
69407
+ function syncPendingEditOverlay() {
69408
+ const edit = getActivePendingEdit();
69409
+ if (!edit) {
69410
+ clearScreenEditOverlay();
69411
+ if (!pendingMode) {
69412
+ clearOverlay(overlayEl, rectEl);
69413
+ }
69414
+ return;
69415
+ }
69416
+ screenEditOverlay.render(edit.clientPoints, { showGrid: false });
69417
+ }
69418
+ function createCameraPoseSnapshot() {
69419
+ camera.updateMatrixWorld(true);
69420
+ return {
69421
+ position: camera.position.toArray(),
69422
+ projectionMatrix: camera.projectionMatrix.toArray(),
69423
+ quaternion: camera.quaternion.toArray()
69424
+ };
69425
+ }
69426
+ function projectionChanged(source, target) {
69427
+ if (!Array.isArray(source) || !Array.isArray(target)) {
69428
+ return true;
69429
+ }
69430
+ return source.some(
69431
+ (value, index) => Math.abs(value - target[index]) > CAMERA_PROJECTION_EPSILON
69432
+ );
69433
+ }
69434
+ function cameraPoseChanged(cameraPose) {
69435
+ if (!cameraPose) {
69436
+ return true;
69437
+ }
69438
+ camera.updateMatrixWorld(true);
69439
+ const dx = camera.position.x - cameraPose.position[0];
69440
+ const dy = camera.position.y - cameraPose.position[1];
69441
+ const dz = camera.position.z - cameraPose.position[2];
69442
+ if (dx * dx + dy * dy + dz * dz > CAMERA_POSITION_EPSILON_SQ) {
69443
+ return true;
69444
+ }
69445
+ const quaternion = cameraPose.quaternion;
69446
+ const quaternionDot = Math.abs(
69447
+ camera.quaternion.x * quaternion[0] + camera.quaternion.y * quaternion[1] + camera.quaternion.z * quaternion[2] + camera.quaternion.w * quaternion[3]
69448
+ );
69449
+ if (1 - Math.min(1, quaternionDot) > CAMERA_QUATERNION_EPSILON) {
69450
+ return true;
69451
+ }
69452
+ return projectionChanged(
69453
+ camera.projectionMatrix.toArray(),
69454
+ cameraPose.projectionMatrix
69455
+ );
69456
+ }
69457
+ function clearPendingScreenEdit() {
69458
+ pendingScreenEdit = null;
69459
+ pendingEditDrag = null;
69460
+ syncPendingEditOverlay();
69461
+ }
69462
+ function freezePendingScreenEdit(showStatus = false) {
69463
+ const hadEdit = !!pendingScreenEdit;
69464
+ if (!hadEdit) {
69465
+ return false;
69466
+ }
69467
+ clearPendingScreenEdit();
69468
+ if (showStatus) {
69469
+ setStatus(
69470
+ "Screen selection shape fixed after camera movement. Drag the 3D far plane, then Confirm or Cancel."
69471
+ );
69472
+ }
69473
+ return true;
69474
+ }
69475
+ function freezePendingScreenEditIfCameraChanged() {
69476
+ if (!pendingScreenEdit || pendingEditDrag) {
69477
+ return false;
69478
+ }
69479
+ if (!cameraPoseChanged(pendingScreenEdit.cameraPose)) {
69480
+ return false;
69481
+ }
69482
+ return freezePendingScreenEdit(true);
69483
+ }
69484
+ function createPendingScreenEdit(selection, clientRect) {
69485
+ pendingScreenEdit = {
69486
+ cameraPose: createCameraPoseSnapshot(),
69487
+ clientPoints: clampClientPoints(getClientRectPoints(clientRect), domElement),
69488
+ selectionId: selection.id
69489
+ };
69490
+ syncPendingEditOverlay();
69491
+ }
69014
69492
  function syncWorldState() {
69015
69493
  const transform = getCurrentRootTransformArray();
69016
69494
  getEntries().forEach(({ selection }) => {
@@ -69090,10 +69568,171 @@ function createCropController({
69090
69568
  camera,
69091
69569
  domElement,
69092
69570
  getDepthRange,
69571
+ onOverlayClear: clearScreenEditOverlay,
69572
+ onOverlayUpdate: (clientRect) => {
69573
+ screenEditOverlay.render(getClientRectPoints(clientRect), {
69574
+ showGrid: true
69575
+ });
69576
+ return true;
69577
+ },
69093
69578
  onSelectionCreated: handleSelectionCreated,
69094
69579
  overlayEl,
69095
69580
  rectEl
69096
69581
  });
69582
+ function createEditHit(part) {
69583
+ return { cursor: "grab", part };
69584
+ }
69585
+ function getPendingEditHit(event) {
69586
+ if (freezePendingScreenEditIfCameraChanged()) {
69587
+ return null;
69588
+ }
69589
+ const edit = getActivePendingEdit();
69590
+ if (!edit) {
69591
+ return null;
69592
+ }
69593
+ const pointer = { x: event.clientX, y: event.clientY };
69594
+ for (const part of SCREEN_EDIT_CORNER_PARTS) {
69595
+ const point = getPartPoint(edit.clientPoints, part);
69596
+ const dx = pointer.x - point.x;
69597
+ const dy = pointer.y - point.y;
69598
+ if (dx * dx + dy * dy <= SCREEN_EDIT_CORNER_HIT_SIZE ** 2) {
69599
+ return createEditHit(part);
69600
+ }
69601
+ }
69602
+ for (const part of SCREEN_EDIT_EDGE_PARTS) {
69603
+ const [startIndex, endIndex] = SCREEN_EDIT_PART_POINT_INDICES[part];
69604
+ if (pointSegmentDistanceSq(
69605
+ pointer,
69606
+ edit.clientPoints[startIndex],
69607
+ edit.clientPoints[endIndex]
69608
+ ) <= SCREEN_EDIT_EDGE_HIT_SIZE ** 2) {
69609
+ return createEditHit(part);
69610
+ }
69611
+ }
69612
+ return null;
69613
+ }
69614
+ function getPendingEditDragPoints(event) {
69615
+ const { part, startClientX, startClientY, startPoints } = pendingEditDrag;
69616
+ const domRect = domElement.getBoundingClientRect();
69617
+ const indices = SCREEN_EDIT_PART_POINT_INDICES[part] || [];
69618
+ let dx = event.clientX - startClientX;
69619
+ let dy = event.clientY - startClientY;
69620
+ indices.forEach((index) => {
69621
+ const point = startPoints[index];
69622
+ dx = Math.max(dx, domRect.left - point.x);
69623
+ dx = Math.min(dx, domRect.right - point.x);
69624
+ dy = Math.max(dy, domRect.top - point.y);
69625
+ dy = Math.min(dy, domRect.bottom - point.y);
69626
+ });
69627
+ return startPoints.map(
69628
+ (point, index) => indices.includes(index) ? {
69629
+ x: point.x + dx,
69630
+ y: point.y + dy
69631
+ } : copyClientPoint(point)
69632
+ );
69633
+ }
69634
+ function updatePendingEditSelection(clientPoints) {
69635
+ const edit = getActivePendingEdit();
69636
+ if (!edit) {
69637
+ return false;
69638
+ }
69639
+ const match = findSelection(edit.selectionId);
69640
+ if (!match) {
69641
+ return false;
69642
+ }
69643
+ if (!isConvexClientQuad(clientPoints)) {
69644
+ return false;
69645
+ }
69646
+ const selectionData = createSelectionData({
69647
+ camera,
69648
+ clientPoints,
69649
+ domElement,
69650
+ getDepthRange
69651
+ });
69652
+ if (!selectionData) {
69653
+ return false;
69654
+ }
69655
+ edit.clientPoints = copyClientPoints(clientPoints);
69656
+ setScreenSelectionShape(
69657
+ match.selection,
69658
+ selectionData,
69659
+ getCurrentRootTransformArray()
69660
+ );
69661
+ syncPendingEditOverlay();
69662
+ syncTransformControlsState();
69663
+ return true;
69664
+ }
69665
+ function handlePendingEditPointerDown(event) {
69666
+ if (event.button !== 0) {
69667
+ return false;
69668
+ }
69669
+ const hit = getPendingEditHit(event);
69670
+ if (!hit) {
69671
+ return false;
69672
+ }
69673
+ pendingEditDrag = {
69674
+ part: hit.part,
69675
+ pointerId: event.pointerId,
69676
+ startClientX: event.clientX,
69677
+ startClientY: event.clientY,
69678
+ startPoints: copyClientPoints(pendingScreenEdit.clientPoints),
69679
+ updated: false
69680
+ };
69681
+ domElement.setPointerCapture?.(event.pointerId);
69682
+ screenEditOverlay.setActivePart(hit.part);
69683
+ setEditCursor("grabbing");
69684
+ event.preventDefault();
69685
+ event.stopPropagation();
69686
+ return true;
69687
+ }
69688
+ function handlePendingEditPointerMove(event) {
69689
+ if (pendingEditDrag) {
69690
+ if (event.pointerId !== pendingEditDrag.pointerId) {
69691
+ return false;
69692
+ }
69693
+ pendingEditDrag.updated = updatePendingEditSelection(getPendingEditDragPoints(event)) || pendingEditDrag.updated;
69694
+ event.preventDefault();
69695
+ event.stopPropagation();
69696
+ return true;
69697
+ }
69698
+ if (event.buttons) {
69699
+ return false;
69700
+ }
69701
+ const hit = getPendingEditHit(event);
69702
+ screenEditOverlay.setActivePart(hit?.part);
69703
+ setEditCursor(hit?.cursor || "");
69704
+ return false;
69705
+ }
69706
+ function handlePendingEditPointerUp(event) {
69707
+ if (!pendingEditDrag || event.pointerId !== pendingEditDrag.pointerId) {
69708
+ return false;
69709
+ }
69710
+ domElement.releasePointerCapture?.(event.pointerId);
69711
+ const updated = pendingEditDrag.updated;
69712
+ pendingEditDrag = null;
69713
+ const hit = getPendingEditHit(event);
69714
+ screenEditOverlay.setActivePart(hit?.part);
69715
+ setEditCursor(hit?.cursor || "");
69716
+ setStatus(
69717
+ updated ? "Updated screen selection convex quadrilateral." : "Screen selection must stay convex.",
69718
+ !updated
69719
+ );
69720
+ event.preventDefault();
69721
+ event.stopPropagation();
69722
+ return true;
69723
+ }
69724
+ function handlePendingEditPointerCancel(event) {
69725
+ if (!pendingEditDrag || event.pointerId !== pendingEditDrag.pointerId) {
69726
+ return false;
69727
+ }
69728
+ domElement.releasePointerCapture?.(event.pointerId);
69729
+ pendingEditDrag = null;
69730
+ screenEditOverlay.setActivePart(null);
69731
+ clearEditCursor();
69732
+ event.preventDefault();
69733
+ event.stopPropagation();
69734
+ return true;
69735
+ }
69097
69736
  function setMode(active) {
69098
69737
  pendingMode = active && hasGaussianSplats && pendingSelections.length === 0;
69099
69738
  pointerTracker.setActive(pendingMode);
@@ -69106,6 +69745,7 @@ function createCropController({
69106
69745
  }
69107
69746
  cameraController.enabled = !transformControls.dragging;
69108
69747
  syncTransformControlsState();
69748
+ syncPendingEditOverlay();
69109
69749
  refreshUi();
69110
69750
  }
69111
69751
  function cancelMode() {
@@ -69114,7 +69754,7 @@ function createCropController({
69114
69754
  }
69115
69755
  setMode(false);
69116
69756
  }
69117
- function handleSelectionCreated(selectionData) {
69757
+ function handleSelectionCreated(selectionData, clientRect) {
69118
69758
  if (pendingSelections.length > 0) {
69119
69759
  setMode(false);
69120
69760
  setStatus(
@@ -69136,12 +69776,13 @@ function createCropController({
69136
69776
  pendingSelections.push(selection);
69137
69777
  activeSelectionId = selection.id;
69138
69778
  setMode(false);
69779
+ createPendingScreenEdit(selection, clientRect);
69139
69780
  syncEditSdfs();
69140
69781
  syncFarHandles();
69141
69782
  syncTransformControlsState();
69142
69783
  refreshUi();
69143
69784
  setStatus(
69144
- "Added screen exclude selection. Drag the 3D far plane, then Confirm or Cancel before drawing another."
69785
+ "Added screen exclude selection. Drag corner points or edges into a convex quadrilateral before moving the camera, then adjust the 3D far plane and Confirm or Cancel."
69145
69786
  );
69146
69787
  }
69147
69788
  function toggle() {
@@ -69173,6 +69814,7 @@ function createCropController({
69173
69814
  }
69174
69815
  const count = pendingSelections.length;
69175
69816
  selections.push(...pendingSelections);
69817
+ clearPendingScreenEdit();
69176
69818
  pendingSelections = [];
69177
69819
  activeSelectionId = null;
69178
69820
  setMode(false);
@@ -69193,6 +69835,7 @@ function createCropController({
69193
69835
  )) {
69194
69836
  activeSelectionId = null;
69195
69837
  }
69838
+ clearPendingScreenEdit();
69196
69839
  pendingSelections.forEach(disposeScreenSelection);
69197
69840
  pendingSelections = [];
69198
69841
  syncEditSdfs();
@@ -69259,10 +69902,12 @@ function createCropController({
69259
69902
  setTransformMode(null);
69260
69903
  syncEditSdfs();
69261
69904
  syncFarHandles();
69905
+ syncPendingEditOverlay();
69262
69906
  refreshUi();
69263
69907
  syncTransformControlsState();
69908
+ const canEditPendingRect = !wasActive && !!getActivePendingEdit();
69264
69909
  setStatus(
69265
- wasActive ? "Screen selection deactivated." : "Drag the 3D far plane handle to adjust screen selection depth."
69910
+ wasActive ? "Screen selection deactivated." : canEditPendingRect ? "Drag corner points or edges into a convex quadrilateral before moving the camera, or drag the 3D far plane to adjust depth." : "Drag the 3D far plane handle to adjust screen selection depth."
69266
69911
  );
69267
69912
  }
69268
69913
  function removeFromList(list, selectionId) {
@@ -69283,6 +69928,9 @@ function createCropController({
69283
69928
  if (Number(selectionId) === activeSelectionId) {
69284
69929
  activeSelectionId = null;
69285
69930
  }
69931
+ if (Number(selectionId) === pendingScreenEdit?.selectionId) {
69932
+ clearPendingScreenEdit();
69933
+ }
69286
69934
  syncEditSdfs();
69287
69935
  syncFarHandles();
69288
69936
  refreshUi();
@@ -69300,6 +69948,7 @@ function createCropController({
69300
69948
  selections = [];
69301
69949
  pendingSelections = [];
69302
69950
  activeSelectionId = null;
69951
+ clearPendingScreenEdit();
69303
69952
  syncEditSdfs();
69304
69953
  syncFarHandles();
69305
69954
  refreshUi();
@@ -69313,6 +69962,7 @@ function createCropController({
69313
69962
  activeSelectionId = null;
69314
69963
  syncEditSdfs();
69315
69964
  syncFarHandles();
69965
+ syncPendingEditOverlay();
69316
69966
  cancelMode();
69317
69967
  refreshUi();
69318
69968
  }
@@ -69323,8 +69973,44 @@ function createCropController({
69323
69973
  activeSelectionId = null;
69324
69974
  syncEditSdfs();
69325
69975
  syncFarHandles();
69976
+ syncPendingEditOverlay();
69326
69977
  refreshUi();
69327
69978
  }
69979
+ function shouldCapturePointerDown(event) {
69980
+ return event.button === 0 && (pendingMode || getPendingEditHit(event) !== null);
69981
+ }
69982
+ function handlePointerDown(event) {
69983
+ if (pointerTracker.handlePointerDown(event)) {
69984
+ return true;
69985
+ }
69986
+ return handlePendingEditPointerDown(event);
69987
+ }
69988
+ function handlePointerMove(event) {
69989
+ if (pointerTracker.handlePointerMove(event)) {
69990
+ return true;
69991
+ }
69992
+ return handlePendingEditPointerMove(event);
69993
+ }
69994
+ function handlePointerUp(event) {
69995
+ if (pointerTracker.handlePointerUp(event)) {
69996
+ return true;
69997
+ }
69998
+ return handlePendingEditPointerUp(event);
69999
+ }
70000
+ function handlePointerCancel(event) {
70001
+ if (pointerTracker.handlePointerCancel(event)) {
70002
+ return true;
70003
+ }
70004
+ return handlePendingEditPointerCancel(event);
70005
+ }
70006
+ cameraController.addEventListener(
70007
+ "update",
70008
+ freezePendingScreenEditIfCameraChanged
70009
+ );
70010
+ cameraController.addEventListener(
70011
+ "finish",
70012
+ freezePendingScreenEditIfCameraChanged
70013
+ );
69328
70014
  return {
69329
70015
  cancel,
69330
70016
  cancelMode,
@@ -69334,25 +70020,32 @@ function createCropController({
69334
70020
  getActiveSelection,
69335
70021
  getPayload,
69336
70022
  getPendingMode: () => pendingMode,
69337
- handlePointerCancel: pointerTracker.handlePointerCancel,
69338
- handlePointerDown: pointerTracker.handlePointerDown,
69339
- handlePointerMove: pointerTracker.handlePointerMove,
69340
- handlePointerUp: pointerTracker.handlePointerUp,
70023
+ handlePointerCancel,
70024
+ handlePointerDown,
70025
+ handlePointerMove,
70026
+ handlePointerUp,
69341
70027
  handleSelectionRemove,
69342
70028
  handleSelectionSelect,
69343
70029
  handleTransformControlObjectChange,
69344
70030
  hasPendingSelections: () => pendingSelections.length > 0,
69345
70031
  notifyTransformModeChanged,
69346
70032
  setHasGaussianSplats,
70033
+ shouldCapturePointerDown,
69347
70034
  syncWorldState,
69348
70035
  toggle
69349
70036
  };
69350
70037
  }
70038
+ var CAMERA_POSITION_EPSILON_SQ, CAMERA_QUATERNION_EPSILON, CAMERA_PROJECTION_EPSILON;
69351
70039
  var init_cropController = __esm({
69352
70040
  "src/viewer/screenSelection/cropController.js"() {
69353
70041
  init_three_module();
69354
70042
  init_screenSelection();
70043
+ init_geometry();
70044
+ init_editOverlay();
69355
70045
  init_cropUi();
70046
+ CAMERA_POSITION_EPSILON_SQ = 1e-12;
70047
+ CAMERA_QUATERNION_EPSILON = 1e-10;
70048
+ CAMERA_PROJECTION_EPSILON = 1e-10;
69356
70049
  }
69357
70050
  });
69358
70051
 
@@ -69961,7 +70654,7 @@ var require_app = __commonJS({
69961
70654
  savedControlDisabledStates = null;
69962
70655
  }
69963
70656
  cameraController.setPointerDownFilter((event) => {
69964
- return !(cropController?.getPendingMode() && event.button === 0);
70657
+ return !(cropController?.shouldCapturePointerDown(event) ?? false);
69965
70658
  });
69966
70659
  var { transformControls, transformControlsHelper } = createViewerTransformControls({
69967
70660
  camera,