bruce-cesium 7.3.0 → 7.3.2

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.
@@ -6575,7 +6575,7 @@
6575
6575
  const adjustedSphere = boundingSphere.sphere.clone();
6576
6576
  // Terrain only matters here because it moves the sphere onto the ground.
6577
6577
  // Far enough away that a plausible ground height is a rounding error against the viewing distance, sampling it is wasted work.
6578
- const cameraDistance = Cesium.Cartesian3.distance(camera.position, adjustedSphere.center);
6578
+ const cameraDistance = Cesium.Cartesian3.distance(camera.positionWC, adjustedSphere.center);
6579
6579
  if (cameraDistance > TERRAIN_SKIP_DISTANCE) {
6580
6580
  adjustedSphere.radius += TERRAIN_SKIP_RADIUS_PAD;
6581
6581
  }
@@ -6588,7 +6588,8 @@
6588
6588
  }
6589
6589
  adjustedSphere.center = grounded;
6590
6590
  }
6591
- const cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up);
6591
+ // Camera vectors are frame relative while a reference frame is set (the compass orbits via lookAt).
6592
+ const cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC);
6592
6593
  const visibility = cullingVolume.computeVisibility(adjustedSphere);
6593
6594
  return visibility !== Cesium.Intersect.INSIDE && visibility !== Cesium.Intersect.INTERSECTING;
6594
6595
  }
@@ -6615,14 +6616,14 @@
6615
6616
  return true;
6616
6617
  }
6617
6618
  const camera = viewer.scene.camera;
6618
- if (!((_a = camera === null || camera === void 0 ? void 0 : camera.position) === null || _a === void 0 ? void 0 : _a.x)) {
6619
+ if (!((_a = camera === null || camera === void 0 ? void 0 : camera.positionWC) === null || _a === void 0 ? void 0 : _a.x)) {
6619
6620
  return false;
6620
6621
  }
6621
6622
  const lastRecheck = camera[LAST_RECHECK_KEY];
6622
6623
  if (!lastRecheck) {
6623
6624
  camera[LAST_RECHECK_KEY] = {
6624
- position: camera.position.clone(),
6625
- direction: camera.direction.clone(),
6625
+ position: camera.positionWC.clone(),
6626
+ direction: camera.directionWC.clone(),
6626
6627
  tilesLoading: viewer.scene.globe.tilesLoaded
6627
6628
  };
6628
6629
  return true;
@@ -6631,14 +6632,14 @@
6631
6632
  const tilesLoadingDiff = lastRecheck.tilesLoading != viewer.scene.globe.tilesLoaded;
6632
6633
  let recheck = tilesLoadingDiff;
6633
6634
  if (!recheck) {
6634
- const posDiff = Cesium.Cartesian3.magnitude(Cesium.Cartesian3.subtract(position, camera.position, new Cesium.Cartesian3()));
6635
- const dirDiff = Cesium.Cartesian3.magnitude(Cesium.Cartesian3.subtract(direction, camera.direction, new Cesium.Cartesian3()));
6635
+ const posDiff = Cesium.Cartesian3.magnitude(Cesium.Cartesian3.subtract(position, camera.positionWC, new Cesium.Cartesian3()));
6636
+ const dirDiff = Cesium.Cartesian3.magnitude(Cesium.Cartesian3.subtract(direction, camera.directionWC, new Cesium.Cartesian3()));
6636
6637
  recheck = posDiff > 100 || dirDiff > 0.01;
6637
6638
  }
6638
6639
  if (recheck) {
6639
6640
  camera[LAST_RECHECK_KEY] = {
6640
- position: camera.position.clone(),
6641
- direction: camera.direction.clone(),
6641
+ position: camera.positionWC.clone(),
6642
+ direction: camera.directionWC.clone(),
6642
6643
  tilesLoading: viewer.scene.globe.tilesLoaded
6643
6644
  };
6644
6645
  }
@@ -6691,7 +6692,9 @@
6691
6692
  return;
6692
6693
  }
6693
6694
  const camera = viewer.scene.camera;
6694
- const cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up);
6695
+ // Camera vectors are frame relative while a reference frame is set (the compass orbits via lookAt).
6696
+ // These spheres are world space, so only the world coordinate vectors compare against them correctly.
6697
+ const cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC);
6695
6698
  let changed = false;
6696
6699
  for (const rego of tilesets) {
6697
6700
  const tileset = rego.tileset;
@@ -9111,12 +9114,13 @@
9111
9114
  ReassignMenuItem(params) {
9112
9115
  var _a;
9113
9116
  const { fromMenuItemId, toMenuItemId, toMenuItemType, toPriority, requestRender, source, lazy, onBatch, onComplete } = params;
9117
+ const noop = () => { };
9114
9118
  if (!fromMenuItemId || !toMenuItemId || fromMenuItemId === toMenuItemId) {
9115
- return;
9119
+ return noop;
9116
9120
  }
9117
9121
  const entityIds = this.entityIdsByMenuItem[fromMenuItemId];
9118
9122
  if (!entityIds) {
9119
- return;
9123
+ return noop;
9120
9124
  }
9121
9125
  const idsSnapshot = Array.from(entityIds);
9122
9126
  const regoSnapshot = new Map();
@@ -9127,7 +9131,7 @@
9127
9131
  }
9128
9132
  }
9129
9133
  const reassignOne = (entityId) => {
9130
- var _a, _b;
9134
+ var _a, _b, _c;
9131
9135
  const regos = this.rego[entityId];
9132
9136
  if (!regos) {
9133
9137
  return null;
@@ -9146,6 +9150,7 @@
9146
9150
  }
9147
9151
  rego.menuItemId = toMenuItemId;
9148
9152
  rego.menuItemType = toMenuItemType;
9153
+ const priorityChanged = toPriority != null && rego.priority !== toPriority;
9149
9154
  if (toPriority != null) {
9150
9155
  rego.priority = toPriority;
9151
9156
  }
@@ -9171,15 +9176,17 @@
9171
9176
  }
9172
9177
  this.unindexMenuItemEntityIfAbsent(fromMenuItemId, entityId);
9173
9178
  this.indexMenuItemEntity(toMenuItemId, entityId);
9174
- this.queueUpdate({
9175
- entityId,
9176
- refresh: true
9177
- });
9179
+ // Don't queue if no register-level visual changes are required.
9180
+ if (priorityChanged || ((_c = this.states[entityId]) === null || _c === void 0 ? void 0 : _c[toMenuItemId])) {
9181
+ this.queueUpdate({
9182
+ entityId,
9183
+ refresh: true
9184
+ });
9185
+ }
9178
9186
  return rego;
9179
9187
  };
9180
9188
  if (lazy) {
9181
- this.startLazyReassign(idsSnapshot, reassignOne, requestRender, onBatch, onComplete);
9182
- return;
9189
+ return this.startLazyReassign(idsSnapshot, reassignOne, requestRender, onBatch, onComplete);
9183
9190
  }
9184
9191
  for (const entityId of idsSnapshot) {
9185
9192
  reassignOne(entityId);
@@ -9187,17 +9194,12 @@
9187
9194
  if (requestRender != false) {
9188
9195
  this.viewer.scene.requestRender();
9189
9196
  }
9197
+ return noop;
9190
9198
  }
9191
9199
  startLazyReassign(entityIds, reassignOne, requestRender, onBatch, onComplete) {
9192
9200
  const BATCH_SIZE = 5000;
9193
9201
  let index = 0;
9194
- const interval = setInterval(() => {
9195
- if (this.Disposed) {
9196
- clearInterval(interval);
9197
- this.activeChunkedIntervals.delete(interval);
9198
- return;
9199
- }
9200
- const end = Math.min(index + BATCH_SIZE, entityIds.length);
9202
+ const runTo = (end) => {
9201
9203
  const batch = [];
9202
9204
  for (; index < end; index++) {
9203
9205
  const rego = reassignOne(entityIds[index]);
@@ -9211,6 +9213,14 @@
9211
9213
  if (requestRender != false) {
9212
9214
  this.viewer.scene.requestRender();
9213
9215
  }
9216
+ };
9217
+ const interval = setInterval(() => {
9218
+ if (this.Disposed) {
9219
+ clearInterval(interval);
9220
+ this.activeChunkedIntervals.delete(interval);
9221
+ return;
9222
+ }
9223
+ runTo(Math.min(index + BATCH_SIZE, entityIds.length));
9214
9224
  if (index >= entityIds.length) {
9215
9225
  clearInterval(interval);
9216
9226
  this.activeChunkedIntervals.delete(interval);
@@ -9218,6 +9228,14 @@
9218
9228
  }
9219
9229
  }, 10);
9220
9230
  this.activeChunkedIntervals.add(interval);
9231
+ return (finishRemaining) => {
9232
+ clearInterval(interval);
9233
+ this.activeChunkedIntervals.delete(interval);
9234
+ if (finishRemaining && !this.Disposed) {
9235
+ runTo(entityIds.length);
9236
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
9237
+ }
9238
+ };
9221
9239
  }
9222
9240
  /**
9223
9241
  * Locates a visual corresponding to a given entity id.
@@ -9340,7 +9358,7 @@
9340
9358
  }
9341
9359
  }
9342
9360
  const removeOne = (entityId) => {
9343
- var _a;
9361
+ var _a, _b;
9344
9362
  const entityRegos = this.rego[entityId];
9345
9363
  if (!entityRegos) {
9346
9364
  return;
@@ -9379,15 +9397,24 @@
9379
9397
  if (source !== EUpdateSource.TREE_CASCADE) {
9380
9398
  (_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(update);
9381
9399
  }
9382
- if (doesInclude) {
9400
+ // Only worth refreshing while the Entity is still drawn by something else, since
9401
+ // losing this rego can change which of the survivors wins. With none left there is
9402
+ // nothing to restyle, and queueing one per removed Entity is what turns disabling a
9403
+ // large menu item into minutes of scheduled work.
9404
+ if (doesInclude && ((_b = this.rego[entityId]) === null || _b === void 0 ? void 0 : _b.length)) {
9383
9405
  this.queueUpdate({
9384
9406
  entityId: entityId,
9385
9407
  refresh: false
9386
9408
  });
9387
9409
  }
9388
9410
  };
9411
+ const finish = () => {
9412
+ this.releaseMenuItemCollection(menuItemId);
9413
+ this.RemoveTilesetsByMenuItem(menuItemId);
9414
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
9415
+ };
9389
9416
  if (lazy) {
9390
- this.startLazyRemoval(entityIds, removeOne, onComplete);
9417
+ this.startLazyRemoval(entityIds, removeOne, finish);
9391
9418
  return;
9392
9419
  }
9393
9420
  WithSuspendedCCollections(this.allSceneCollections(), () => {
@@ -9395,8 +9422,7 @@
9395
9422
  removeOne(entityId);
9396
9423
  }
9397
9424
  });
9398
- this.releaseMenuItemCollection(menuItemId);
9399
- this.RemoveTilesetsByMenuItem(menuItemId);
9425
+ finish();
9400
9426
  }
9401
9427
  else if (entityId) {
9402
9428
  const entityRegos = this.rego[entityId];
@@ -14368,6 +14394,14 @@
14368
14394
  this.disposed = true;
14369
14395
  this.hDisposals.forEach((d) => d());
14370
14396
  this.hDisposals = [];
14397
+ // A tick still awaiting a response resumes after this, and anything left here would have it
14398
+ // ask for the whole set again on the way out.
14399
+ this.eIdQueue = [];
14400
+ this.eIdQueued.clear();
14401
+ this.priorityCount = 0;
14402
+ this.allEIds.clear();
14403
+ this.lastFoundDateTimes.clear();
14404
+ this.entityDataOverrides.clear();
14371
14405
  }
14372
14406
  checkRange(force) {
14373
14407
  const min = this.viewer.clock.startTime.toString();
@@ -14380,7 +14414,7 @@
14380
14414
  }
14381
14415
  }
14382
14416
  onTick(force) {
14383
- if (this.runningTick) {
14417
+ if (this.runningTick || this.disposed) {
14384
14418
  return;
14385
14419
  }
14386
14420
  const rTime = this.viewer.clock.currentTime.toString();
@@ -16179,9 +16213,12 @@
16179
16213
  // Removal callbacks for this instance's own tile stream listeners.
16180
16214
  this.tileLoadRemoval = null;
16181
16215
  this.tileUnloadRemoval = null;
16182
- // Chunks AdoptHandoff()'s restyle of handed-off content across ticks instead of one
16183
- // synchronous pass over potentially millions of regos.
16184
- this.handoffRestyleInterval = null;
16216
+ // Cancels AdoptHandoff()'s chunked re-parent of handed-off content, which runs across ticks
16217
+ // instead of one synchronous pass over potentially millions of regos.
16218
+ this.handoffReassignCancel = null;
16219
+ // Menu item the in-flight re-parent is still pulling regos off, so a teardown mid-swap can
16220
+ // clear both sides rather than orphaning whatever had not moved yet.
16221
+ this.handoffSourceMenuItemId = null;
16185
16222
  this.styler = new exports.TilesetRenderEngine.Styler();
16186
16223
  this.modelTreeUpdate = new BModels.BruceEvent();
16187
16224
  // Quick look-up of the model tree nodes by entity/geomId.
@@ -16510,7 +16547,7 @@
16510
16547
  }
16511
16548
  // Returns null (fall back to a normal Dispose()) if the tileset hasn't finished loading yet.
16512
16549
  PrepareHandoff() {
16513
- var _a, _b, _c;
16550
+ var _a, _b, _c, _d;
16514
16551
  if (this.disposed || !this.cTileset || this.cTileset.isDestroyed()) {
16515
16552
  return null;
16516
16553
  }
@@ -16522,15 +16559,15 @@
16522
16559
  clearInterval(this.featureQueueInterval);
16523
16560
  this.featureQueueInterval = null;
16524
16561
  }
16525
- if (this.handoffRestyleInterval) {
16526
- clearInterval(this.handoffRestyleInterval);
16527
- this.handoffRestyleInterval = null;
16528
- }
16562
+ // Settle a re-parent still in flight, so what is handed on is not split across two menu items.
16563
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this, true);
16564
+ this.handoffReassignCancel = null;
16565
+ this.handoffSourceMenuItemId = null;
16529
16566
  // Not transferred, the receiving manager sets up its own fresh copy if needed.
16530
16567
  this.viewerDateTimeDispose();
16531
- (_a = this.styler) === null || _a === void 0 ? void 0 : _a.Dispose();
16532
- (_b = this.tileLoadRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
16533
- (_c = this.tileUnloadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
16568
+ (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
16569
+ (_c = this.tileLoadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
16570
+ (_d = this.tileUnloadRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
16534
16571
  this.tileLoadRemoval = null;
16535
16572
  this.tileUnloadRemoval = null;
16536
16573
  const payload = {
@@ -16580,13 +16617,6 @@
16580
16617
  }
16581
16618
  });
16582
16619
  // Same visuals, same registrations so just re-keyed onto this menu item.
16583
- this.visualsManager.ReassignMenuItem({
16584
- fromMenuItemId: payload.sourceMenuItemId,
16585
- toMenuItemId: this.item.id,
16586
- toMenuItemType: this.item.Type,
16587
- toPriority: this.renderPriority,
16588
- requestRender: false
16589
- });
16590
16620
  this.onCTilesetLoad();
16591
16621
  this.styler.Init({
16592
16622
  viewer: this.viewer,
@@ -16600,33 +16630,32 @@
16600
16630
  scenario: (_b = this.item.BruceEntity) === null || _b === void 0 ? void 0 : _b.Scenario,
16601
16631
  historic: (_c = this.item.BruceEntity) === null || _c === void 0 ? void 0 : _c.historic,
16602
16632
  });
16603
- this.queueHandoffRestyle(this.visualsManager.GetRegos({ menuItemId: this.item.id }));
16633
+ // A swap runs inside a render pass, so re-parenting a whole tileset in one go stalls it.
16634
+ // Each batch is restyled as it lands rather than after a second walk of the same set.
16635
+ this.handoffSourceMenuItemId = payload.sourceMenuItemId;
16636
+ this.handoffReassignCancel = this.visualsManager.ReassignMenuItem({
16637
+ fromMenuItemId: payload.sourceMenuItemId,
16638
+ toMenuItemId: this.item.id,
16639
+ toMenuItemType: this.item.Type,
16640
+ toPriority: this.renderPriority,
16641
+ requestRender: false,
16642
+ lazy: true,
16643
+ onBatch: (regos) => {
16644
+ if (this.disposed) {
16645
+ return;
16646
+ }
16647
+ this.styler.QueueEntities(regos, true);
16648
+ },
16649
+ onComplete: () => {
16650
+ this.handoffReassignCancel = null;
16651
+ this.handoffSourceMenuItemId = null;
16652
+ }
16653
+ });
16604
16654
  this.viewer.scene.requestRender();
16605
16655
  if (((_d = this.item.BruceEntity) === null || _d === void 0 ? void 0 : _d.historic) && this.tileset) {
16606
16656
  this.viewerDateTimeSub(this.tileset);
16607
16657
  }
16608
16658
  }
16609
- queueHandoffRestyle(regos) {
16610
- if (!regos.length) {
16611
- return;
16612
- }
16613
- const BATCH_SIZE = 5000;
16614
- let index = 0;
16615
- this.handoffRestyleInterval = setInterval(() => {
16616
- if (this.disposed) {
16617
- clearInterval(this.handoffRestyleInterval);
16618
- this.handoffRestyleInterval = null;
16619
- return;
16620
- }
16621
- const end = Math.min(index + BATCH_SIZE, regos.length);
16622
- this.styler.QueueEntities(regos.slice(index, end), true);
16623
- index = end;
16624
- if (index >= regos.length) {
16625
- clearInterval(this.handoffRestyleInterval);
16626
- this.handoffRestyleInterval = null;
16627
- }
16628
- }, 10);
16629
- }
16630
16659
  /**
16631
16660
  * @param tile
16632
16661
  * @param load indicates if we are loading or unloading the tile.
@@ -17178,33 +17207,40 @@
17178
17207
  this.doDispose();
17179
17208
  }
17180
17209
  doDispose() {
17181
- var _a, _b;
17210
+ var _a, _b, _c;
17182
17211
  if (this.featureQueueInterval) {
17183
17212
  clearInterval(this.featureQueueInterval);
17184
17213
  this.featureQueueInterval = null;
17185
17214
  this.featureQueue = [];
17186
17215
  }
17187
- if (this.handoffRestyleInterval) {
17188
- clearInterval(this.handoffRestyleInterval);
17189
- this.handoffRestyleInterval = null;
17190
- }
17216
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this);
17217
+ this.handoffReassignCancel = null;
17191
17218
  if (this.cTileset) {
17192
17219
  const viewer = this.viewer;
17193
17220
  if (!(viewer === null || viewer === void 0 ? void 0 : viewer.isDestroyed()) && this.viewer.scene.primitives.contains(this.cTileset)) {
17194
17221
  this.cTileset.show = false;
17195
17222
  this.viewer.scene.primitives.remove(this.cTileset);
17196
- (_a = exports.TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _a === void 0 ? void 0 : _a.Unwatch(this.cTileset);
17223
+ (_b = exports.TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _b === void 0 ? void 0 : _b.Unwatch(this.cTileset);
17197
17224
  this.viewer.scene.requestRender();
17198
17225
  }
17199
17226
  this.cTileset = null;
17200
17227
  }
17201
- (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
17228
+ (_c = this.styler) === null || _c === void 0 ? void 0 : _c.Dispose();
17202
17229
  this.visualsManager.RemoveRegos({
17203
17230
  menuItemId: this.item.id,
17204
17231
  doRemove: false,
17205
17232
  source: exports.VisualsRegister.EUpdateSource.TILESET_DISPOSE,
17206
17233
  lazy: true
17207
17234
  });
17235
+ if (this.handoffSourceMenuItemId) {
17236
+ this.visualsManager.RemoveRegos({
17237
+ menuItemId: this.handoffSourceMenuItemId,
17238
+ doRemove: false,
17239
+ source: exports.VisualsRegister.EUpdateSource.TILESET_DISPOSE,
17240
+ lazy: true
17241
+ });
17242
+ this.handoffSourceMenuItemId = null;
17243
+ }
17208
17244
  this.viewerDateTimeDispose();
17209
17245
  }
17210
17246
  async ReRender(params) {
@@ -19957,9 +19993,12 @@
19957
19993
  // Removal callbacks for this instance's own tile stream listeners.
19958
19994
  this.tileLoadRemoval = null;
19959
19995
  this.tileUnloadRemoval = null;
19960
- // Chunks AdoptHandoff()'s restyle of handed-off content across ticks instead of one
19961
- // synchronous pass over potentially millions of regos.
19962
- this.handoffRestyleInterval = null;
19996
+ // Cancels AdoptHandoff()'s chunked re-parent of handed-off content, which runs across ticks
19997
+ // instead of one synchronous pass over potentially millions of regos.
19998
+ this.handoffReassignCancel = null;
19999
+ // Menu item the in-flight re-parent is still pulling regos off, so a teardown mid-swap can
20000
+ // clear both sides rather than orphaning whatever had not moved yet.
20001
+ this.handoffSourceMenuItemId = null;
19963
20002
  this.styler = new exports.TilesetRenderEngine.Styler();
19964
20003
  // Entity ID -> rego.
19965
20004
  // We retain this information as a quick look-up on what has been registered.
@@ -20272,31 +20311,36 @@
20272
20311
  this.doDispose();
20273
20312
  }
20274
20313
  doDispose() {
20275
- var _a, _b;
20314
+ var _a, _b, _c;
20276
20315
  if (this.featureQueueInterval) {
20277
20316
  clearInterval(this.featureQueueInterval);
20278
20317
  this.featureQueueInterval = null;
20279
20318
  this.featureQueue = [];
20280
20319
  }
20281
- if (this.handoffRestyleInterval) {
20282
- clearInterval(this.handoffRestyleInterval);
20283
- this.handoffRestyleInterval = null;
20284
- }
20320
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this);
20321
+ this.handoffReassignCancel = null;
20285
20322
  if (this.cTileset) {
20286
20323
  const viewer = this.viewer;
20287
20324
  if (!(viewer === null || viewer === void 0 ? void 0 : viewer.isDestroyed()) && this.viewer.scene.primitives.contains(this.cTileset)) {
20288
20325
  this.cTileset.show = false;
20289
20326
  this.viewer.scene.primitives.remove(this.cTileset);
20290
- (_a = exports.TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _a === void 0 ? void 0 : _a.Unwatch(this.cTileset);
20327
+ (_b = exports.TilesetRenderEngine.GetMemoryWatcher(viewer)) === null || _b === void 0 ? void 0 : _b.Unwatch(this.cTileset);
20291
20328
  this.viewer.scene.requestRender();
20292
20329
  }
20293
20330
  this.cTileset = null;
20294
20331
  }
20295
- (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
20332
+ (_c = this.styler) === null || _c === void 0 ? void 0 : _c.Dispose();
20296
20333
  this.visualsManager.RemoveRegos({
20297
20334
  menuItemId: this.item.id,
20298
20335
  lazy: true
20299
20336
  });
20337
+ if (this.handoffSourceMenuItemId) {
20338
+ this.visualsManager.RemoveRegos({
20339
+ menuItemId: this.handoffSourceMenuItemId,
20340
+ lazy: true
20341
+ });
20342
+ this.handoffSourceMenuItemId = null;
20343
+ }
20300
20344
  }
20301
20345
  onCTilesetLoad() {
20302
20346
  if (this.item.FlyTo) {
@@ -20336,7 +20380,7 @@
20336
20380
  }
20337
20381
  // Returns null (fall back to a normal Dispose()) if the tileset hasn't finished loading yet.
20338
20382
  PrepareHandoff() {
20339
- var _a, _b, _c;
20383
+ var _a, _b, _c, _d;
20340
20384
  if (this.disposed || !this.cTileset || this.cTileset.isDestroyed()) {
20341
20385
  return null;
20342
20386
  }
@@ -20348,13 +20392,13 @@
20348
20392
  clearInterval(this.featureQueueInterval);
20349
20393
  this.featureQueueInterval = null;
20350
20394
  }
20351
- if (this.handoffRestyleInterval) {
20352
- clearInterval(this.handoffRestyleInterval);
20353
- this.handoffRestyleInterval = null;
20354
- }
20355
- (_a = this.styler) === null || _a === void 0 ? void 0 : _a.Dispose();
20356
- (_b = this.tileLoadRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
20357
- (_c = this.tileUnloadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
20395
+ // Settle a re-parent still in flight, so what is handed on is not split across two menu items.
20396
+ (_a = this.handoffReassignCancel) === null || _a === void 0 ? void 0 : _a.call(this, true);
20397
+ this.handoffReassignCancel = null;
20398
+ this.handoffSourceMenuItemId = null;
20399
+ (_b = this.styler) === null || _b === void 0 ? void 0 : _b.Dispose();
20400
+ (_c = this.tileLoadRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
20401
+ (_d = this.tileUnloadRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
20358
20402
  this.tileLoadRemoval = null;
20359
20403
  this.tileUnloadRemoval = null;
20360
20404
  const payload = {
@@ -20396,14 +20440,8 @@
20396
20440
  console.error(e);
20397
20441
  }
20398
20442
  });
20399
- this.visualsManager.ReassignMenuItem({
20400
- fromMenuItemId: payload.sourceMenuItemId,
20401
- toMenuItemId: this.item.id,
20402
- toMenuItemType: this.item.Type,
20403
- toPriority: this.renderPriority,
20404
- requestRender: false
20405
- });
20406
- if (Manager.NeedsStyler(this.item)) {
20443
+ const needsStyler = Manager.NeedsStyler(this.item);
20444
+ if (needsStyler) {
20407
20445
  this.styler.Init({
20408
20446
  viewer: this.viewer,
20409
20447
  api: this.getters.GetBruceApi(),
@@ -20417,8 +20455,28 @@
20417
20455
  applyStyles: Boolean(this.item.ApplyStyles),
20418
20456
  monitor: this.monitor
20419
20457
  });
20420
- this.queueHandoffRestyle(this.visualsManager.GetRegos({ menuItemId: this.item.id }));
20421
20458
  }
20459
+ // A swap runs inside a render pass, so re-parenting a whole Entities Set in one go stalls it.
20460
+ // Each batch is restyled as it lands rather than after a second walk of the same set.
20461
+ this.handoffSourceMenuItemId = payload.sourceMenuItemId;
20462
+ this.handoffReassignCancel = this.visualsManager.ReassignMenuItem({
20463
+ fromMenuItemId: payload.sourceMenuItemId,
20464
+ toMenuItemId: this.item.id,
20465
+ toMenuItemType: this.item.Type,
20466
+ toPriority: this.renderPriority,
20467
+ requestRender: false,
20468
+ lazy: true,
20469
+ onBatch: (regos) => {
20470
+ if (this.disposed || !needsStyler) {
20471
+ return;
20472
+ }
20473
+ this.styler.QueueEntities(regos, true);
20474
+ },
20475
+ onComplete: () => {
20476
+ this.handoffReassignCancel = null;
20477
+ this.handoffSourceMenuItemId = null;
20478
+ }
20479
+ });
20422
20480
  this.onCTilesetLoad();
20423
20481
  let attenuation = this.item.attenuation;
20424
20482
  if (!attenuation && attenuation != false) {
@@ -20437,27 +20495,6 @@
20437
20495
  });
20438
20496
  this.viewer.scene.requestRender();
20439
20497
  }
20440
- queueHandoffRestyle(regos) {
20441
- if (!regos.length) {
20442
- return;
20443
- }
20444
- const BATCH_SIZE = 5000;
20445
- let index = 0;
20446
- this.handoffRestyleInterval = setInterval(() => {
20447
- if (this.disposed) {
20448
- clearInterval(this.handoffRestyleInterval);
20449
- this.handoffRestyleInterval = null;
20450
- return;
20451
- }
20452
- const end = Math.min(index + BATCH_SIZE, regos.length);
20453
- this.styler.QueueEntities(regos.slice(index, end), true);
20454
- index = end;
20455
- if (index >= regos.length) {
20456
- clearInterval(this.handoffRestyleInterval);
20457
- this.handoffRestyleInterval = null;
20458
- }
20459
- }, 10);
20460
- }
20461
20498
  /*
20462
20499
  * Reads a numeric feature property, returning null for anything that is not one.
20463
20500
  */
@@ -46253,7 +46290,7 @@ void main() {
46253
46290
  StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
46254
46291
  })(exports.StyleUtils || (exports.StyleUtils = {}));
46255
46292
 
46256
- const VERSION = "7.3.0";
46293
+ const VERSION = "7.3.2";
46257
46294
  /**
46258
46295
  * Updates the environment instance used by bruce-cesium to one specified.
46259
46296
  * This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.