bruce-cesium 7.0.1 → 7.0.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.
Files changed (84) hide show
  1. package/dist/bruce-cesium.es5.js +1475 -289
  2. package/dist/bruce-cesium.es5.js.map +1 -1
  3. package/dist/bruce-cesium.umd.js +1473 -287
  4. package/dist/bruce-cesium.umd.js.map +1 -1
  5. package/dist/lib/bruce-cesium.js +1 -1
  6. package/dist/lib/internal/cesium-show-gate.js +100 -0
  7. package/dist/lib/internal/cesium-show-gate.js.map +1 -0
  8. package/dist/lib/internal/cesium-utils.js +207 -1
  9. package/dist/lib/internal/cesium-utils.js.map +1 -1
  10. package/dist/lib/internal/js-utils.js +25 -1
  11. package/dist/lib/internal/js-utils.js.map +1 -1
  12. package/dist/lib/rendering/cesium-animated-in-out.js +66 -7
  13. package/dist/lib/rendering/cesium-animated-in-out.js.map +1 -1
  14. package/dist/lib/rendering/entity-render-engine-model3d.js +17 -8
  15. package/dist/lib/rendering/entity-render-engine-model3d.js.map +1 -1
  16. package/dist/lib/rendering/entity-render-engine-point.js +46 -12
  17. package/dist/lib/rendering/entity-render-engine-point.js.map +1 -1
  18. package/dist/lib/rendering/entity-render-engine-polygon.js +146 -63
  19. package/dist/lib/rendering/entity-render-engine-polygon.js.map +1 -1
  20. package/dist/lib/rendering/entity-render-engine-polyline.js +27 -8
  21. package/dist/lib/rendering/entity-render-engine-polyline.js.map +1 -1
  22. package/dist/lib/rendering/entity-render-engine.js +86 -14
  23. package/dist/lib/rendering/entity-render-engine.js.map +1 -1
  24. package/dist/lib/rendering/menu-item-manager.js +30 -2
  25. package/dist/lib/rendering/menu-item-manager.js.map +1 -1
  26. package/dist/lib/rendering/relation-render-engine.js +2 -1
  27. package/dist/lib/rendering/relation-render-engine.js.map +1 -1
  28. package/dist/lib/rendering/render-managers/common/entity-label.js +10 -2
  29. package/dist/lib/rendering/render-managers/common/entity-label.js.map +1 -1
  30. package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js +58 -4
  31. package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js.map +1 -1
  32. package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js +46 -23
  33. package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js.map +1 -1
  34. package/dist/lib/rendering/render-managers/entities/entities-render-manager.js +70 -11
  35. package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
  36. package/dist/lib/rendering/render-managers/entities/entity-render-manager.js +13 -1
  37. package/dist/lib/rendering/render-managers/entities/entity-render-manager.js.map +1 -1
  38. package/dist/lib/rendering/render-managers/other/legacy-relations-render-manager.js +3 -2
  39. package/dist/lib/rendering/render-managers/other/legacy-relations-render-manager.js.map +1 -1
  40. package/dist/lib/rendering/render-managers/other/relations-render-manager.js +3 -2
  41. package/dist/lib/rendering/render-managers/other/relations-render-manager.js.map +1 -1
  42. package/dist/lib/rendering/render-managers/render-manager.js +67 -3
  43. package/dist/lib/rendering/render-managers/render-manager.js.map +1 -1
  44. package/dist/lib/rendering/render-managers/tilesets/tileset-arb-render-manager.js +2 -0
  45. package/dist/lib/rendering/render-managers/tilesets/tileset-arb-render-manager.js.map +1 -1
  46. package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js +2 -0
  47. package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js.map +1 -1
  48. package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js +2 -0
  49. package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js.map +1 -1
  50. package/dist/lib/rendering/render-managers/tilesets/tileset-pointcloud-render-manager.js +4 -1
  51. package/dist/lib/rendering/render-managers/tilesets/tileset-pointcloud-render-manager.js.map +1 -1
  52. package/dist/lib/rendering/texture-frame-series-animator.js +7 -0
  53. package/dist/lib/rendering/texture-frame-series-animator.js.map +1 -1
  54. package/dist/lib/rendering/tileset-render-engine.js +18 -0
  55. package/dist/lib/rendering/tileset-render-engine.js.map +1 -1
  56. package/dist/lib/rendering/visual-register-culler.js +191 -97
  57. package/dist/lib/rendering/visual-register-culler.js.map +1 -1
  58. package/dist/lib/rendering/visuals-register.js +263 -25
  59. package/dist/lib/rendering/visuals-register.js.map +1 -1
  60. package/dist/lib/utils/cesium-entity-styler.js +7 -3
  61. package/dist/lib/utils/cesium-entity-styler.js.map +1 -1
  62. package/dist/types/bruce-cesium.d.ts +1 -1
  63. package/dist/types/internal/cesium-show-gate.d.ts +29 -0
  64. package/dist/types/internal/cesium-utils.d.ts +63 -0
  65. package/dist/types/internal/js-utils.d.ts +10 -0
  66. package/dist/types/rendering/cesium-animated-in-out.d.ts +5 -0
  67. package/dist/types/rendering/entity-render-engine-model3d.d.ts +2 -0
  68. package/dist/types/rendering/entity-render-engine-point.d.ts +2 -0
  69. package/dist/types/rendering/entity-render-engine-polygon.d.ts +2 -0
  70. package/dist/types/rendering/entity-render-engine-polyline.d.ts +2 -0
  71. package/dist/types/rendering/entity-render-engine.d.ts +17 -1
  72. package/dist/types/rendering/menu-item-manager.d.ts +6 -0
  73. package/dist/types/rendering/render-managers/entities/entities-datalab-render-manager.d.ts +13 -0
  74. package/dist/types/rendering/render-managers/entities/entities-loaded-render-manager.d.ts +2 -0
  75. package/dist/types/rendering/render-managers/entities/entities-render-manager.d.ts +14 -0
  76. package/dist/types/rendering/render-managers/entities/entity-render-manager.d.ts +2 -0
  77. package/dist/types/rendering/render-managers/render-manager.d.ts +33 -0
  78. package/dist/types/rendering/render-managers/tilesets/tileset-pointcloud-render-manager.d.ts +3 -0
  79. package/dist/types/rendering/texture-frame-series-animator.d.ts +5 -0
  80. package/dist/types/rendering/tileset-render-engine.d.ts +14 -0
  81. package/dist/types/rendering/visual-register-culler.d.ts +7 -0
  82. package/dist/types/rendering/visuals-register.d.ts +65 -1
  83. package/dist/types/utils/cesium-entity-styler.d.ts +1 -0
  84. package/package.json +1 -1
@@ -4,6 +4,8 @@ exports.VisualsRegister = void 0;
4
4
  const bruce_models_1 = require("bruce-models");
5
5
  const Cesium = require("cesium");
6
6
  const js_utils_1 = require("../internal/js-utils");
7
+ const cesium_show_gate_1 = require("../internal/cesium-show-gate");
8
+ const cesium_utils_1 = require("../internal/cesium-utils");
7
9
  const entity_label_1 = require("../rendering/render-managers/common/entity-label");
8
10
  const cesium_entity_styler_1 = require("../utils/cesium-entity-styler");
9
11
  const entity_render_engine_1 = require("./entity-render-engine");
@@ -35,7 +37,7 @@ function isAlive(viewer, visual) {
35
37
  return false;
36
38
  }
37
39
  if (visual instanceof Cesium.Entity) {
38
- return viewer.entities.contains(visual);
40
+ return (0, cesium_utils_1.IsCEntityInScene)(viewer, visual);
39
41
  }
40
42
  else if (visual instanceof Cesium.Primitive) {
41
43
  return viewer.scene.primitives.contains(visual);
@@ -62,6 +64,32 @@ function removeEntity(viewer, visual) {
62
64
  viewer
63
65
  });
64
66
  }
67
+ /**
68
+ * Returns the highest zIndex across a graphic and its siblings, or null when none of them set one.
69
+ * @param viewer
70
+ * @param visual
71
+ */
72
+ function getHighestZIndex(viewer, visual) {
73
+ if (!(visual instanceof Cesium.Entity)) {
74
+ return null;
75
+ }
76
+ let highest = null;
77
+ const parts = entity_utils_1.EntityUtils.GatherEntity({
78
+ entity: visual
79
+ });
80
+ for (const part of parts) {
81
+ if (!(part instanceof Cesium.Entity)) {
82
+ continue;
83
+ }
84
+ for (const graphic of [part.polygon, part.polyline, part.corridor, part.ellipse, part.rectangle]) {
85
+ const zIndex = graphic ? (0, cesium_utils_1.GetCValue)(viewer, graphic.zIndex) : null;
86
+ if (zIndex != null && !isNaN(zIndex) && (highest == null || zIndex > highest)) {
87
+ highest = zIndex;
88
+ }
89
+ }
90
+ }
91
+ return highest;
92
+ }
65
93
  const MAX_SHOW_DEPTH = 10;
66
94
  function updateCEntityShow(viewer, visual, rego, show, ignoreParent, depth = 0) {
67
95
  if (depth > MAX_SHOW_DEPTH) {
@@ -80,26 +108,24 @@ function updateCEntityShow(viewer, visual, rego, show, ignoreParent, depth = 0)
80
108
  updateCEntityShow(viewer, sibling, rego, show, true, depth + 1);
81
109
  }
82
110
  }
83
- /**
84
- * Do NOT use ".show" as it causes crashes in Cesium polylines that are clamped to ground.
85
- * We could target them specifically here but we may be getting overall performance gain by just removing stuff from the scene.
86
- */
87
- if (rego.collection) {
88
- if (!show && rego.collection.contains(visual)) {
89
- rego.collection.remove(visual);
90
- }
91
- else if (show && !rego.collection.contains(visual)) {
92
- rego.collection.add(visual);
111
+ if (show) {
112
+ // Always restore membership on the way back in. Something else may have evicted this graphic while it
113
+ // was hidden (the culler removes outright), and `show` alone would leave it invisible.
114
+ (0, cesium_utils_1.AddCEntityToScene)(viewer, visual, rego.collection);
115
+ if (visual.show !== true) {
116
+ visual.show = true;
93
117
  }
118
+ return;
94
119
  }
95
- else {
96
- if (!show && viewer.entities.contains(visual)) {
97
- viewer.entities.remove(visual);
98
- }
99
- else if (show && !viewer.entities.contains(visual)) {
100
- viewer.entities.add(visual);
120
+ // Hiding via `show` only updates a per-instance attribute, where leaving the collection rebuilds the whole
121
+ // geometry batch. But it is not safe for every graphic, see CanToggleShowSafely for exactly why.
122
+ if ((0, cesium_utils_1.CanToggleShowSafely)([visual])) {
123
+ if (visual.show !== false) {
124
+ visual.show = false;
101
125
  }
126
+ return;
102
127
  }
128
+ (0, cesium_utils_1.RemoveCEntityFromScene)(viewer, visual);
103
129
  }
104
130
  function updateEntityShow(viewer, rego, show) {
105
131
  const visual = rego.visual;
@@ -412,12 +438,128 @@ var VisualsRegister;
412
438
  // This lets us modify the update without re-adding the item to the queue if it's already in it.
413
439
  this.updateQueueSettings = {};
414
440
  this.updateQueueInterval = null;
441
+ // Per menu item collections so we can refresh sets of Entities without affecting others.
442
+ this.menuItemSources = new Map();
443
+ // Set when the data source order no longer matches the zIndexes seen, so it is re-applied once.
444
+ this.sourceOrderDirty = false;
445
+ /*
446
+ * Tilesets in the scene, keyed by the tileset itself.
447
+ */
448
+ this.tilesets = new Map();
415
449
  this.viewer = params.viewer;
416
450
  this.apiGetters = params.apiGetters;
417
451
  this.cameraCullerDispose = visual_register_culler_1.VisualRegisterCuller.Monitor({
418
452
  register: this
419
453
  });
420
454
  }
455
+ /**
456
+ * Returns the collection a menu item's visuals belong in, creating its data source on first use.
457
+ * Returns null when there is nothing to key off, leaving the caller on the viewer's own collection.
458
+ * @param menuItemId
459
+ */
460
+ ensureMenuItemCollection(menuItemId) {
461
+ var _a;
462
+ if (!menuItemId || this.disposed || !((_a = this.viewer) === null || _a === void 0 ? void 0 : _a.dataSources)) {
463
+ return null;
464
+ }
465
+ const existing = this.menuItemSources.get(menuItemId);
466
+ if (existing) {
467
+ return existing.source.entities;
468
+ }
469
+ const source = new Cesium.CustomDataSource(`menu-item-${menuItemId}`);
470
+ const record = {
471
+ source,
472
+ maxZIndex: 0,
473
+ added: false
474
+ };
475
+ (0, cesium_utils_1.MarkCCollectionOwned)(source.entities);
476
+ this.menuItemSources.set(menuItemId, record);
477
+ // Adding is asynchronous, so ordering has to wait until it is actually in the collection.
478
+ Promise.resolve(this.viewer.dataSources.add(source))
479
+ .then(() => {
480
+ record.added = true;
481
+ this.applySourceOrder();
482
+ })
483
+ .catch((e) => {
484
+ console.error(e);
485
+ });
486
+ return source.entities;
487
+ }
488
+ /**
489
+ * Notes the highest zIndex seen for a menu item, since that is what its data source has to sort by.
490
+ * zIndex orders geometry within a data source but not between them, so a whole layer stacks by the
491
+ * highest value anything in it asked for.
492
+ * @param menuItemId
493
+ * @param visual
494
+ */
495
+ trackSourceZIndex(menuItemId, visual) {
496
+ const record = this.menuItemSources.get(menuItemId);
497
+ if (!record) {
498
+ return;
499
+ }
500
+ const zIndex = getHighestZIndex(this.viewer, visual);
501
+ if (zIndex == null || zIndex <= record.maxZIndex) {
502
+ return;
503
+ }
504
+ record.maxZIndex = zIndex;
505
+ this.sourceOrderDirty = true;
506
+ this.applySourceOrder();
507
+ }
508
+ /**
509
+ * Re-stacks the menu item data sources so a higher zIndex sits above a lower one.
510
+ */
511
+ applySourceOrder() {
512
+ var _a;
513
+ if (this.disposed || !this.sourceOrderDirty || !((_a = this.viewer) === null || _a === void 0 ? void 0 : _a.dataSources)) {
514
+ return;
515
+ }
516
+ const records = Array.from(this.menuItemSources.values()).filter(x => x.added);
517
+ if (records.length < 2) {
518
+ // Nothing to order against yet, so leave the flag set for when there is.
519
+ return;
520
+ }
521
+ this.sourceOrderDirty = false;
522
+ // Raising each in ascending order leaves the highest on top.
523
+ records.sort((a, b) => a.maxZIndex - b.maxZIndex);
524
+ for (const record of records) {
525
+ try {
526
+ this.viewer.dataSources.raiseToTop(record.source);
527
+ }
528
+ catch (e) {
529
+ console.error(e);
530
+ }
531
+ }
532
+ }
533
+ /**
534
+ * Drops a menu item's data source once nothing is registered under it any more.
535
+ * @param menuItemId
536
+ */
537
+ releaseMenuItemCollection(menuItemId) {
538
+ var _a, _b, _c;
539
+ const record = this.menuItemSources.get(menuItemId);
540
+ if (!record) {
541
+ return;
542
+ }
543
+ if ((_a = this.entityIdsByMenuItem[menuItemId]) === null || _a === void 0 ? void 0 : _a.size) {
544
+ return;
545
+ }
546
+ this.menuItemSources.delete(menuItemId);
547
+ try {
548
+ (_c = (_b = this.viewer) === null || _b === void 0 ? void 0 : _b.dataSources) === null || _c === void 0 ? void 0 : _c.remove(record.source, true);
549
+ }
550
+ catch (e) {
551
+ console.error(e);
552
+ }
553
+ }
554
+ /** Every collection a bulk pass over this register's visuals could mutate. */
555
+ allSceneCollections() {
556
+ var _a;
557
+ const collections = [(_a = this.viewer) === null || _a === void 0 ? void 0 : _a.entities];
558
+ for (const record of Array.from(this.menuItemSources.values())) {
559
+ collections.push(record.source.entities);
560
+ }
561
+ return collections;
562
+ }
421
563
  indexMenuItemEntity(menuItemId, entityId) {
422
564
  if (!menuItemId) {
423
565
  return;
@@ -1007,9 +1149,11 @@ var VisualsRegister;
1007
1149
  return;
1008
1150
  }
1009
1151
  const end = Math.min(index + BATCH_SIZE, items.length);
1010
- for (; index < end; index++) {
1011
- perItem(items[index]);
1012
- }
1152
+ (0, cesium_utils_1.WithSuspendedCCollections)(this.allSceneCollections(), () => {
1153
+ for (; index < end; index++) {
1154
+ perItem(items[index]);
1155
+ }
1156
+ });
1013
1157
  this.viewer.scene.requestRender();
1014
1158
  if (index >= items.length) {
1015
1159
  clearInterval(interval);
@@ -1166,7 +1310,7 @@ var VisualsRegister;
1166
1310
  markEntity(this, rego, rego.visual, false);
1167
1311
  }
1168
1312
  Dispose() {
1169
- var _a;
1313
+ var _a, _b, _c, _d;
1170
1314
  (_a = this.cameraCullerDispose) === null || _a === void 0 ? void 0 : _a.call(this, {
1171
1315
  uncull: false
1172
1316
  });
@@ -1181,6 +1325,20 @@ var VisualsRegister;
1181
1325
  }
1182
1326
  this.activeChunkedIntervals.clear();
1183
1327
  this.disposed = true;
1328
+ for (const record of Array.from(this.menuItemSources.values())) {
1329
+ try {
1330
+ (_c = (_b = this.viewer) === null || _b === void 0 ? void 0 : _b.dataSources) === null || _c === void 0 ? void 0 : _c.remove(record.source, true);
1331
+ }
1332
+ catch (e) {
1333
+ console.error(e);
1334
+ }
1335
+ }
1336
+ this.menuItemSources.clear();
1337
+ // Hand every tileset's show flag back to its owner, holding whatever the owner last asked for.
1338
+ for (const rego of Array.from(this.tilesets.values())) {
1339
+ (_d = rego.gate) === null || _d === void 0 ? void 0 : _d.Release();
1340
+ }
1341
+ this.tilesets.clear();
1184
1342
  }
1185
1343
  ForceUpdate(params) {
1186
1344
  var _a;
@@ -1778,6 +1936,14 @@ var VisualsRegister;
1778
1936
  });
1779
1937
  }
1780
1938
  const entityId = rego.entityId;
1939
+ // Scope this visual to its menu item's own data source, so a rebuild of it cannot re-tessellate
1940
+ // other layers. A caller that already picked a collection (eg. geojson) keeps its own.
1941
+ if (!rego.collection && rego.menuItemId) {
1942
+ const collection = this.ensureMenuItemCollection(rego.menuItemId);
1943
+ if (collection) {
1944
+ rego.collection = collection;
1945
+ }
1946
+ }
1781
1947
  // Add the new visual to the register.
1782
1948
  const entityRegos = (_a = this.rego[entityId]) !== null && _a !== void 0 ? _a : [];
1783
1949
  entityRegos.push(rego);
@@ -1785,6 +1951,7 @@ var VisualsRegister;
1785
1951
  this.indexMenuItemEntity(rego.menuItemId, entityId);
1786
1952
  // Mark the visual as part of this register so selection works.
1787
1953
  markEntity(this, rego, rego.visual, false);
1954
+ this.trackSourceZIndex(rego.menuItemId, rego.visual);
1788
1955
  // Run any updates on the visual based on the calculated state.
1789
1956
  // Eg: visibility, opacity, selection, etc.
1790
1957
  this.queueUpdate({
@@ -2089,9 +2256,13 @@ var VisualsRegister;
2089
2256
  this.startLazyRemoval(entityIds, removeOne, onComplete);
2090
2257
  return;
2091
2258
  }
2092
- for (const entityId of entityIds) {
2093
- removeOne(entityId);
2094
- }
2259
+ (0, cesium_utils_1.WithSuspendedCCollections)(this.allSceneCollections(), () => {
2260
+ for (const entityId of entityIds) {
2261
+ removeOne(entityId);
2262
+ }
2263
+ });
2264
+ this.releaseMenuItemCollection(menuItemId);
2265
+ this.RemoveTilesetsByMenuItem(menuItemId);
2095
2266
  }
2096
2267
  else if (entityId) {
2097
2268
  const entityRegos = this.rego[entityId];
@@ -2274,8 +2445,75 @@ var VisualsRegister;
2274
2445
  };
2275
2446
  }
2276
2447
  /**
2277
- * Returns all registered entity ids.
2448
+ * Registers a tileset so the register can decide when it is worth drawing.
2449
+ * @param params
2450
+ */
2451
+ AddTileset(params) {
2452
+ const { tileset, menuItemId } = params;
2453
+ if (!tileset || this.disposed) {
2454
+ return;
2455
+ }
2456
+ const existing = this.tilesets.get(tileset);
2457
+ if (existing) {
2458
+ existing.menuItemId = menuItemId !== null && menuItemId !== void 0 ? menuItemId : existing.menuItemId;
2459
+ return;
2460
+ }
2461
+ this.tilesets.set(tileset, {
2462
+ tileset,
2463
+ menuItemId,
2464
+ // Null when the property could not be intercepted, in which case this tileset simply never gets
2465
+ // culled rather than us fighting its owner over the same field.
2466
+ gate: (0, cesium_show_gate_1.InstallShowGate)(tileset),
2467
+ culled: false
2468
+ });
2469
+ }
2470
+ /**
2471
+ * Stops tracking a tileset and hands its show flag back to its owner.
2472
+ * @param tileset
2278
2473
  */
2474
+ RemoveTileset(tileset) {
2475
+ var _a;
2476
+ const rego = this.tilesets.get(tileset);
2477
+ if (!rego) {
2478
+ return;
2479
+ }
2480
+ this.tilesets.delete(tileset);
2481
+ (_a = rego.gate) === null || _a === void 0 ? void 0 : _a.Release();
2482
+ }
2483
+ /**
2484
+ * Stops tracking every tileset belonging to a menu item.
2485
+ * @param menuItemId
2486
+ */
2487
+ RemoveTilesetsByMenuItem(menuItemId) {
2488
+ if (!menuItemId) {
2489
+ return;
2490
+ }
2491
+ for (const rego of Array.from(this.tilesets.values())) {
2492
+ if (rego.menuItemId === menuItemId) {
2493
+ this.RemoveTileset(rego.tileset);
2494
+ }
2495
+ }
2496
+ }
2497
+ /**
2498
+ * Every tileset currently tracked.
2499
+ */
2500
+ GetTilesets() {
2501
+ return Array.from(this.tilesets.values());
2502
+ }
2503
+ /**
2504
+ * Suppresses or restores a tileset.
2505
+ * Returns whether its effective visibility changed, so a caller can skip requesting a render when nothing did.
2506
+ * @param tileset
2507
+ * @param culled
2508
+ */
2509
+ SetTilesetCulled(tileset, culled) {
2510
+ const rego = this.tilesets.get(tileset);
2511
+ if (!(rego === null || rego === void 0 ? void 0 : rego.gate)) {
2512
+ return false;
2513
+ }
2514
+ rego.culled = Boolean(culled);
2515
+ return rego.gate.SetSuppressed(rego.culled);
2516
+ }
2279
2517
  GetEntityIds() {
2280
2518
  const ids = [];
2281
2519
  for (const entityId in this.rego) {