vim-web 0.3.44-dev.18 → 0.3.44-dev.19

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.
@@ -50664,7 +50664,7 @@ void main() {
50664
50664
  }
50665
50665
  init(duration) {
50666
50666
  this.cancel();
50667
- this._duration = duration;
50667
+ this._duration = Math.max(duration, 0.01);
50668
50668
  this._clock.start();
50669
50669
  }
50670
50670
  cancel() {
@@ -50985,6 +50985,7 @@ void main() {
50985
50985
  * @returns {CameraMovement} The camera movement api.
50986
50986
  */
50987
50987
  lerp(duration = 1, force = false) {
50988
+ if (duration <= 0) return this.snap(force);
50988
50989
  this.stop();
50989
50990
  this._force = force;
50990
50991
  this._lerp.init(duration);
@@ -51886,10 +51887,10 @@ void main() {
51886
51887
  });
51887
51888
  __publicField(this, "onMouseUp", (event) => {
51888
51889
  event.stopImmediatePropagation();
51890
+ event.preventDefault();
51889
51891
  const btn = this.getButton(event);
51890
51892
  if (btn === this._buttonDown) return;
51891
51893
  this._viewer.gizmos.rectangle.visible = false;
51892
- event.preventDefault();
51893
51894
  if (!this._buttonDown) return;
51894
51895
  if (this.inputs.pointerActive === "rect" && this._hasMouseMoved && !this._hasCameraMoved) {
51895
51896
  this.onRectEnd();
@@ -51906,6 +51907,7 @@ void main() {
51906
51907
  this.inputs.pointerOverride = void 0;
51907
51908
  });
51908
51909
  __publicField(this, "onDoubleClick", (event) => {
51910
+ console.log("Double click");
51909
51911
  event.stopImmediatePropagation();
51910
51912
  this.onMouseClick(
51911
51913
  new Vector2(event.offsetX, event.offsetY),
@@ -55469,6 +55471,7 @@ void main() {
55469
55471
  __publicField(this, "_color");
55470
55472
  __publicField(this, "_highlightColor");
55471
55473
  __publicField(this, "_materials");
55474
+ __publicField(this, "_camera");
55472
55475
  __publicField(this, "_camSub");
55473
55476
  this._materials = [matAlways, matBehind];
55474
55477
  this._forward = new Vector3();
@@ -55481,15 +55484,18 @@ void main() {
55481
55484
  this.quaternion.setFromUnitVectors(new Vector3(0, -1, 0), this._forward);
55482
55485
  }
55483
55486
  trackCamera(camera2) {
55484
- const rescale = () => {
55485
- const size = camera2.frustrumSizeAt(this.position);
55486
- this.scale.set(size.x * 3e-3, size.x * 3e-3, size.x * 3e-3);
55487
- };
55488
- this._camSub = camera2.onMoved.subscribe(() => rescale());
55489
- rescale();
55487
+ this._camera = camera2;
55488
+ this.update();
55489
+ this._camSub = camera2.onMoved.subscribe(() => this.update());
55490
+ }
55491
+ update() {
55492
+ if (!this._camera) return;
55493
+ const size = this._camera.frustrumSizeAt(this.position);
55494
+ this.scale.set(size.x * 3e-3, size.x * 3e-3, size.x * 3e-3);
55490
55495
  }
55491
55496
  setPosition(position) {
55492
55497
  this.position.copy(position);
55498
+ this.update();
55493
55499
  }
55494
55500
  get forward() {
55495
55501
  return this._forward;
@@ -57627,6 +57633,36 @@ void main() {
57627
57633
  }
57628
57634
  return Math.min(Math.max(value, min2), max2);
57629
57635
  }
57636
+ class CaptureStateMachine {
57637
+ constructor(canvas) {
57638
+ __publicField(this, "_canvas");
57639
+ __publicField(this, "state");
57640
+ __publicField(this, "id");
57641
+ this._canvas = canvas;
57642
+ this.state = "none";
57643
+ this.id = -1;
57644
+ }
57645
+ onPointerDown(event) {
57646
+ if (this.state === "captured") {
57647
+ this._canvas.releasePointerCapture(this.id);
57648
+ }
57649
+ this.id = event.pointerId;
57650
+ this.state = "captured";
57651
+ }
57652
+ onPointerMove(event) {
57653
+ if (this.state === "capture") {
57654
+ this._canvas.setPointerCapture(this.id);
57655
+ this.state = "captured";
57656
+ }
57657
+ }
57658
+ onPointerUp(event) {
57659
+ if (this.state === "captured") {
57660
+ this._canvas.releasePointerCapture(this.id);
57661
+ this.state = "none";
57662
+ this.id = -1;
57663
+ }
57664
+ }
57665
+ }
57630
57666
  class InputMouse extends InputHandler {
57631
57667
  constructor(canvas, rpc, selection, camera2) {
57632
57668
  super();
@@ -57635,45 +57671,47 @@ void main() {
57635
57671
  __publicField(this, "_lastMouseDownPosition", new Vector2(0, 0));
57636
57672
  __publicField(this, "_selection");
57637
57673
  __publicField(this, "_camera");
57674
+ __publicField(this, "_capture");
57638
57675
  this._canvas = canvas;
57639
57676
  this._rpc = rpc;
57640
57677
  this._selection = selection;
57641
57678
  this._camera = camera2;
57679
+ this._capture = new CaptureStateMachine(canvas);
57642
57680
  }
57643
57681
  register() {
57644
57682
  this.reg(this._canvas, "pointerdown", (e) => {
57645
- this.handlePointerDown(e);
57683
+ this.onPointerDown(e);
57646
57684
  });
57647
57685
  this.reg(this._canvas, "pointerup", (e) => {
57648
- this.handlePointerUp(e);
57686
+ this.onPointerUp(e);
57649
57687
  });
57650
57688
  this.reg(this._canvas, "pointermove", (e) => {
57651
- this.handlePointerMove(e);
57689
+ this.onPointerMove(e);
57652
57690
  });
57653
57691
  this.reg(this._canvas, "wheel", (e) => {
57654
- this.handleMouseScroll(e);
57692
+ this.onMouseScroll(e);
57655
57693
  });
57656
57694
  this.reg(this._canvas, "dblclick", (e) => {
57657
- this.handleDoubleClick(e);
57695
+ this.onDoubleClick(e);
57658
57696
  });
57659
57697
  }
57660
57698
  dispose() {
57661
57699
  this.unregister();
57662
57700
  }
57663
- handlePointerDown(event) {
57701
+ onPointerDown(event) {
57664
57702
  if (event.pointerType !== "mouse") return;
57665
57703
  const pos = this.relativePosition(event);
57666
57704
  this._rpc.RPCMouseButtonEvent(pos, event.button, true);
57667
57705
  this._lastMouseDownPosition = pos;
57668
- this._canvas.setPointerCapture(event.pointerId);
57706
+ this._capture.onPointerDown(event);
57669
57707
  event.preventDefault();
57670
57708
  }
57671
- handlePointerUp(event) {
57709
+ onPointerUp(event) {
57672
57710
  if (event.pointerType !== "mouse") return;
57673
57711
  const pos = this.relativePosition(event);
57674
57712
  this._rpc.RPCMouseButtonEvent(pos, event.button, false);
57675
57713
  this.handleMouseClick(event);
57676
- this._canvas.releasePointerCapture(event.pointerId);
57714
+ this._capture.onPointerUp(event);
57677
57715
  event.preventDefault();
57678
57716
  }
57679
57717
  async handleMouseClick(event) {
@@ -57693,21 +57731,24 @@ void main() {
57693
57731
  this._selection.select(hit.vim, hit.nodeIndex);
57694
57732
  }
57695
57733
  }
57696
- handlePointerMove(event) {
57734
+ onPointerMove(event) {
57697
57735
  if (event.pointerType !== "mouse") return;
57698
57736
  this._canvas.focus();
57737
+ this._capture.onPointerMove(event);
57699
57738
  const pos = this.relativePosition(event);
57700
57739
  this._rpc.RPCMouseMoveEvent(pos);
57701
57740
  }
57702
- async handleDoubleClick(event) {
57741
+ async onDoubleClick(event) {
57703
57742
  const pos = this.relativePosition(event);
57704
57743
  const hit = await this._selection.hitTest(pos);
57705
57744
  if (hit) {
57706
57745
  this._camera.frameVim(hit.vim, [hit.nodeIndex], 1);
57746
+ } else {
57747
+ this._camera.frameAll(1);
57707
57748
  }
57708
57749
  event.preventDefault();
57709
57750
  }
57710
- handleMouseScroll(event) {
57751
+ onMouseScroll(event) {
57711
57752
  this._rpc.RPCMouseScrollEvent(Math.sign(event.deltaY));
57712
57753
  event.preventDefault();
57713
57754
  }
@@ -59687,15 +59728,19 @@ void main() {
59687
59728
  switch (event.key) {
59688
59729
  case "Escape":
59689
59730
  this._selection.clear();
59731
+ event.preventDefault();
59690
59732
  break;
59691
59733
  case "f":
59692
59734
  this.frameContext();
59735
+ event.preventDefault();
59693
59736
  break;
59694
59737
  case "Home":
59695
59738
  this._camera.restoreSavedPosition();
59739
+ event.preventDefault();
59696
59740
  break;
59697
59741
  case " ":
59698
59742
  this._inputs.mode = this._inputs.mode === InputMode.Orbit ? InputMode.Free : InputMode.Orbit;
59743
+ event.preventDefault();
59699
59744
  break;
59700
59745
  }
59701
59746
  }
@@ -61235,11 +61280,15 @@ Averrage Date/Second ${avgDataRatePS} kb
61235
61280
  * Handles camera initialization when connection is established
61236
61281
  */
61237
61282
  onConnect() {
61283
+ this.set(new Vector3(-1e3, 1e3, 1e3), new Vector3(0, 0, 0), 0);
61238
61284
  this.restoreLastPosition();
61239
61285
  }
61240
61286
  onCameraPose(pose) {
61241
61287
  this._lastPosition = pose;
61242
61288
  }
61289
+ set(position, target, blendTime = this._defaultBlendTime) {
61290
+ this._rpc.RPCSetCameraPosition(new Segment(position, target), blendTime);
61291
+ }
61243
61292
  /**
61244
61293
  * Pauses or resumes rendering
61245
61294
  * @param value - True to pause rendering, false to resume
@@ -61253,6 +61302,7 @@ Averrage Date/Second ${avgDataRatePS} kb
61253
61302
  * @returns Promise that resolves when the framing animation is complete
61254
61303
  */
61255
61304
  async frameAll(blendTime = this._defaultBlendTime) {
61305
+ console.log("Camera.frameAll");
61256
61306
  const segment = await this._rpc.RPCFrameAll(blendTime);
61257
61307
  this._savedPosition = this._savedPosition ?? segment;
61258
61308
  return segment;
@@ -61263,6 +61313,7 @@ Averrage Date/Second ${avgDataRatePS} kb
61263
61313
  * @param blendTime - Duration of the camera animation in seconds (defaults to 0.5)
61264
61314
  */
61265
61315
  async frameBox(box, blendTime = this._defaultBlendTime) {
61316
+ console.log("Camera.frameAll");
61266
61317
  const segment = await this._rpc.RPCFrameBox(box, blendTime);
61267
61318
  this._savedPosition = this._savedPosition ?? segment;
61268
61319
  return segment;
@@ -74959,7 +75010,7 @@ Averrage Date/Second ${avgDataRatePS} kb
74959
75010
  if (!this._settings.isolation.enable) return;
74960
75011
  this._isolation = objects ?? [];
74961
75012
  this._apply(source);
74962
- this._camera.frameVisibleObjects.call();
75013
+ this._camera.frameScene.call();
74963
75014
  }
74964
75015
  /**
74965
75016
  * Toggles isolation by using the current selection.
@@ -74974,7 +75025,7 @@ Averrage Date/Second ${avgDataRatePS} kb
74974
75025
  if (!this._settings.isolation.enable) return;
74975
75026
  this._isolation = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74976
75027
  this._apply(source);
74977
- this._camera.frameVisibleObjects.call();
75028
+ this._camera.frameScene.call();
74978
75029
  this._viewer.selection.clear();
74979
75030
  }
74980
75031
  /**
@@ -75074,140 +75125,6 @@ Averrage Date/Second ${avgDataRatePS} kb
75074
75125
  return objects;
75075
75126
  }
75076
75127
  }
75077
- function useStateRef(initialValue) {
75078
- const [value, setValue] = React2.useState(initialValue);
75079
- const ref = React2.useRef(initialValue);
75080
- const event = React2.useRef(new distExports.SimpleEventDispatcher());
75081
- const validate = React2.useRef((value2) => value2);
75082
- const confirm = React2.useRef((value2) => value2);
75083
- const set2 = (value2) => {
75084
- const finalValue = validate.current(value2) ?? value2;
75085
- if (finalValue === void 0) return;
75086
- if (finalValue === ref.current) return;
75087
- ref.current = finalValue;
75088
- setValue(finalValue);
75089
- event.current.dispatch(finalValue);
75090
- };
75091
- return {
75092
- get() {
75093
- return ref.current;
75094
- },
75095
- set: set2,
75096
- confirm() {
75097
- set2(confirm.current(ref.current));
75098
- },
75099
- useOnChange(on) {
75100
- React2.useEffect(() => {
75101
- return event.current.subscribe(on);
75102
- }, []);
75103
- },
75104
- useMemo(on, deps) {
75105
- return React2.useMemo(() => on(value), [...deps || [], value]);
75106
- },
75107
- useValidate(on) {
75108
- React2.useEffect(() => {
75109
- validate.current = on;
75110
- }, []);
75111
- },
75112
- useConfirm(on) {
75113
- React2.useEffect(() => {
75114
- confirm.current = on;
75115
- }, []);
75116
- }
75117
- };
75118
- }
75119
- function useActionRef(action) {
75120
- const ref = React2.useRef(action);
75121
- return {
75122
- call() {
75123
- ref == null ? void 0 : ref.current();
75124
- },
75125
- set(func) {
75126
- ref.current = func;
75127
- }
75128
- };
75129
- }
75130
- function useArgActionRef(action) {
75131
- const ref = React2.useRef(action);
75132
- return {
75133
- call(arg) {
75134
- ref == null ? void 0 : ref.current(arg);
75135
- },
75136
- set(func) {
75137
- ref.current = func;
75138
- }
75139
- };
75140
- }
75141
- function useFuncRef(func) {
75142
- const ref = React2.useRef(func);
75143
- return {
75144
- call() {
75145
- return ref == null ? void 0 : ref.current();
75146
- },
75147
- set(func2) {
75148
- ref.current = func2;
75149
- }
75150
- };
75151
- }
75152
- function useCamera(viewer) {
75153
- const autoCamera2 = useStateRef(false);
75154
- autoCamera2.useOnChange((v) => {
75155
- if (v) {
75156
- frameSelection2.call();
75157
- }
75158
- });
75159
- React2.useEffect(() => {
75160
- viewer.selection.onValueChanged.sub(() => {
75161
- if (autoCamera2.get()) {
75162
- frameSelection2.call();
75163
- }
75164
- });
75165
- }, []);
75166
- const reset = useActionRef(() => viewer.camera.lerp(1).reset());
75167
- const frameSelection2 = useActionRef(() => {
75168
- if (viewer.selection.count === 0) {
75169
- frameVisibleObjects.call();
75170
- return;
75171
- }
75172
- const box = viewer.selection.getBoundingBox();
75173
- if (!box) {
75174
- return;
75175
- }
75176
- box.intersect(viewer.gizmos.sectionBox.box);
75177
- if (box.isEmpty()) {
75178
- return;
75179
- }
75180
- viewer.camera.lerp(1).frame(box);
75181
- });
75182
- const frameVisibleObjects = useActionRef(() => {
75183
- const movement = viewer.camera.lerp(1);
75184
- const box = getVisibleBoundingBox(viewer);
75185
- movement.frame(box);
75186
- });
75187
- return {
75188
- autoCamera: autoCamera2,
75189
- reset,
75190
- frameSelection: frameSelection2,
75191
- frameVisibleObjects
75192
- };
75193
- }
75194
- function getVisibleBoundingBox(viewer, source) {
75195
- let box;
75196
- const vimBoxUnion = (vim) => {
75197
- for (const obj of vim.getObjects()) {
75198
- if (!obj.visible) continue;
75199
- const b = obj.getBoundingBox();
75200
- if (!b) continue;
75201
- box = box ? box.union(b) : b == null ? void 0 : b.clone();
75202
- }
75203
- };
75204
- {
75205
- for (const vim of viewer.vims) {
75206
- vimBoxUnion(vim);
75207
- }
75208
- }
75209
- return box;
75210
- }
75211
75128
  function createContainer(element) {
75212
75129
  let root = element;
75213
75130
  if (root === void 0) {
@@ -75919,6 +75836,92 @@ Averrage Date/Second ${avgDataRatePS} kb
75919
75836
  r.max.z += b2.max.z;
75920
75837
  return r;
75921
75838
  }
75839
+ function useStateRef(initialValue) {
75840
+ const [value, setValue] = React2.useState(initialValue);
75841
+ const ref = React2.useRef(initialValue);
75842
+ const event = React2.useRef(new distExports.SimpleEventDispatcher());
75843
+ const validate = React2.useRef((value2) => value2);
75844
+ const confirm = React2.useRef((value2) => value2);
75845
+ const set2 = (value2) => {
75846
+ const finalValue = validate.current(value2) ?? value2;
75847
+ if (finalValue === void 0) return;
75848
+ if (finalValue === ref.current) return;
75849
+ ref.current = finalValue;
75850
+ setValue(finalValue);
75851
+ event.current.dispatch(finalValue);
75852
+ };
75853
+ return {
75854
+ get() {
75855
+ return ref.current;
75856
+ },
75857
+ set: set2,
75858
+ confirm() {
75859
+ set2(confirm.current(ref.current));
75860
+ },
75861
+ useOnChange(on) {
75862
+ React2.useEffect(() => {
75863
+ return event.current.subscribe(on);
75864
+ }, []);
75865
+ },
75866
+ useMemo(on, deps) {
75867
+ return React2.useMemo(() => on(value), [...deps || [], value]);
75868
+ },
75869
+ useValidate(on) {
75870
+ React2.useEffect(() => {
75871
+ validate.current = on;
75872
+ }, []);
75873
+ },
75874
+ useConfirm(on) {
75875
+ React2.useEffect(() => {
75876
+ confirm.current = on;
75877
+ }, []);
75878
+ }
75879
+ };
75880
+ }
75881
+ function useActionRef(action) {
75882
+ const ref = React2.useRef(action);
75883
+ return {
75884
+ call() {
75885
+ ref == null ? void 0 : ref.current();
75886
+ },
75887
+ set(func) {
75888
+ ref.current = func;
75889
+ }
75890
+ };
75891
+ }
75892
+ function useArgActionRef(action) {
75893
+ const ref = React2.useRef(action);
75894
+ return {
75895
+ call(arg) {
75896
+ ref == null ? void 0 : ref.current(arg);
75897
+ },
75898
+ set(func) {
75899
+ ref.current = func;
75900
+ }
75901
+ };
75902
+ }
75903
+ function useFuncRef(func) {
75904
+ const ref = React2.useRef(func);
75905
+ return {
75906
+ call() {
75907
+ return ref == null ? void 0 : ref.current();
75908
+ },
75909
+ set(func2) {
75910
+ ref.current = func2;
75911
+ }
75912
+ };
75913
+ }
75914
+ function useAsyncFuncRef(func) {
75915
+ const ref = React2.useRef(func);
75916
+ return {
75917
+ async call() {
75918
+ return ref == null ? void 0 : ref.current();
75919
+ },
75920
+ set(func2) {
75921
+ ref.current = func2;
75922
+ }
75923
+ };
75924
+ }
75922
75925
  function useSectionBox(adapter) {
75923
75926
  const enable = useStateRef(false);
75924
75927
  const visible2 = useStateRef(false);
@@ -75950,6 +75953,7 @@ Averrage Date/Second ${avgDataRatePS} kb
75950
75953
  });
75951
75954
  visible2.useOnChange((v) => adapter.setVisible(v));
75952
75955
  React2.useEffect(() => {
75956
+ adapter.setVisible(false);
75953
75957
  return adapter.onSelectionChanged.sub(() => {
75954
75958
  if (auto.get() && enable.get()) sectionSelection.call();
75955
75959
  });
@@ -76014,12 +76018,61 @@ Averrage Date/Second ${avgDataRatePS} kb
76014
76018
  fitBox: (box) => viewer.gizmos.sectionBox.fitBox(box),
76015
76019
  getSelectionBox: () => Promise.resolve(viewer.selection.getBoundingBox()),
76016
76020
  getRendererBox: () => Promise.resolve(viewer.renderer.getBoundingBox()),
76017
- onSceneChanged: viewer.renderer.onBoxUpdated,
76018
76021
  onSelectionChanged: viewer.selection.onValueChanged
76019
76022
  };
76020
76023
  viewer.gizmos.sectionBox.clip = true;
76021
76024
  return useSectionBox(vimAdapter);
76022
76025
  }
76026
+ function useCamera(adapter) {
76027
+ const autoCamera2 = useStateRef(false);
76028
+ autoCamera2.useOnChange((v) => {
76029
+ if (v) {
76030
+ frameSelection2.call();
76031
+ }
76032
+ });
76033
+ React2.useEffect(() => {
76034
+ adapter.onSelectionChanged.sub(() => {
76035
+ if (autoCamera2.get()) {
76036
+ frameSelection2.call();
76037
+ }
76038
+ });
76039
+ }, []);
76040
+ const reset = useActionRef(() => adapter.resetCamera(1));
76041
+ const frameSelection2 = useAsyncFuncRef(async () => {
76042
+ console.log("frameSelection");
76043
+ if (!adapter.hasSelection()) {
76044
+ frameScene.call();
76045
+ return;
76046
+ }
76047
+ const box = await adapter.getSelectionBox();
76048
+ if (!box) {
76049
+ return;
76050
+ }
76051
+ adapter.frameCamera(box, 1);
76052
+ });
76053
+ const frameScene = useAsyncFuncRef(async () => {
76054
+ adapter.frameAll(1);
76055
+ });
76056
+ return {
76057
+ autoCamera: autoCamera2,
76058
+ reset,
76059
+ frameSelection: frameSelection2,
76060
+ frameScene
76061
+ };
76062
+ }
76063
+ function useWebglCamera(viewer) {
76064
+ return useCamera({
76065
+ onSelectionChanged: viewer.selection.onValueChanged,
76066
+ frameCamera: (box, duration) => viewer.camera.lerp(duration).frame(box),
76067
+ resetCamera: (duration) => viewer.camera.lerp(duration).reset(),
76068
+ frameAll: (duration) => {
76069
+ const box = viewer.renderer.getBoundingBox();
76070
+ viewer.camera.lerp(duration).frame(box);
76071
+ },
76072
+ hasSelection: () => viewer.selection.count > 0,
76073
+ getSelectionBox: () => Promise.resolve(viewer.selection.getBoundingBox())
76074
+ });
76075
+ }
76023
76076
  function createWebglComponent(container, componentSettings = {}, viewerSettings = {}) {
76024
76077
  const promise2 = new DeferredPromise();
76025
76078
  const cmpContainer = container instanceof HTMLElement ? createContainer(container) : container ?? createContainer();
@@ -76051,7 +76104,7 @@ Averrage Date/Second ${avgDataRatePS} kb
76051
76104
  var _a2;
76052
76105
  const settings2 = useSettings(props.viewer, props.settings ?? {});
76053
76106
  const modal = useModal(settings2.value.capacity.canFollowUrl);
76054
- const camera2 = useCamera(props.viewer);
76107
+ const camera2 = useWebglCamera(props.viewer);
76055
76108
  const cursor = React2.useMemo(() => new CursorManager(props.viewer), []);
76056
76109
  const loader = React2.useRef(new ComponentLoader(props.viewer, modal));
76057
76110
  const [isolation] = React2.useState(() => new Isolation(props.viewer, camera2, settings2.value));
@@ -76507,6 +76560,7 @@ Averrage Date/Second ${avgDataRatePS} kb
76507
76560
  function useUltraSectionBox(viewer) {
76508
76561
  const ultraAdapter = {
76509
76562
  setVisible: (b) => {
76563
+ console.log("SetVisible!", b);
76510
76564
  viewer.sectionBox.visible = b;
76511
76565
  viewer.sectionBox.interactive = b;
76512
76566
  },
@@ -76514,15 +76568,26 @@ Averrage Date/Second ${avgDataRatePS} kb
76514
76568
  fitBox: (box) => viewer.sectionBox.fitBox(box),
76515
76569
  getSelectionBox: () => viewer.selection.getBoundingBox(),
76516
76570
  getRendererBox: () => viewer.renderer.getBoundingBox(),
76517
- onSelectionChanged: viewer.selection.onValueChanged,
76518
- onSceneChanged: viewer.vims.onChanged
76571
+ onSelectionChanged: viewer.selection.onValueChanged
76519
76572
  };
76520
76573
  return useSectionBox(ultraAdapter);
76521
76574
  }
76522
- function useUltraControlBar(viewer, section, customization) {
76523
- let controlBar2 = [controlBarSectionBox(section, viewer.selection.count > 0)];
76524
- controlBar2 = (customization == null ? void 0 : customization(controlBar2)) ?? controlBar2;
76525
- return controlBar2;
76575
+ function useUltraControlBar(viewer, section, camera2, customization) {
76576
+ const sectionSectionBox = controlBarSectionBox(section, viewer.selection.count > 0);
76577
+ const sectionCamera = controlBarCamera(camera2);
76578
+ let bar = [sectionCamera, sectionSectionBox];
76579
+ bar = (customization == null ? void 0 : customization(bar)) ?? bar;
76580
+ return bar;
76581
+ }
76582
+ function useUltraCamera(viewer) {
76583
+ return useCamera({
76584
+ onSelectionChanged: viewer.selection.onValueChanged,
76585
+ frameCamera: (box, duration) => void viewer.camera.frameBox(box, duration),
76586
+ frameAll: (duration) => viewer.camera.frameAll(duration),
76587
+ resetCamera: (duration) => viewer.camera.restoreSavedPosition(duration),
76588
+ hasSelection: () => viewer.selection.count > 0,
76589
+ getSelectionBox: () => viewer.selection.getBoundingBox()
76590
+ });
76526
76591
  }
76527
76592
  function createUltraComponent(container) {
76528
76593
  const promise2 = new DeferredPromise();
@@ -76552,10 +76617,11 @@ Averrage Date/Second ${avgDataRatePS} kb
76552
76617
  function UltraComponent(props) {
76553
76618
  const modal = useModal(true);
76554
76619
  const sectionBox2 = useUltraSectionBox(props.viewer);
76620
+ const camera2 = useUltraCamera(props.viewer);
76555
76621
  const side = useSideState(true, 400);
76556
76622
  const [_, setSelectState] = React2.useState(0);
76557
76623
  const [controlBarCustom, setControlBarCustom] = React2.useState(() => (c) => c);
76558
- const controlBar2 = useUltraControlBar(props.viewer, sectionBox2, (_2) => _2);
76624
+ const controlBar2 = useUltraControlBar(props.viewer, sectionBox2, camera2, (_2) => _2);
76559
76625
  React2.useEffect(() => {
76560
76626
  props.viewer.onStateChanged.subscribe((state) => updateModal(modal, state));
76561
76627
  props.viewer.selection.onValueChanged.subscribe(() => {