bruce-cesium 7.3.7 → 7.3.8

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 (24) hide show
  1. package/dist/bruce-cesium.es5.js +119 -30
  2. package/dist/bruce-cesium.es5.js.map +1 -1
  3. package/dist/bruce-cesium.umd.js +117 -28
  4. package/dist/bruce-cesium.umd.js.map +1 -1
  5. package/dist/lib/bruce-cesium.js +1 -1
  6. package/dist/lib/rendering/displaced-surface-primitive.js +63 -24
  7. package/dist/lib/rendering/displaced-surface-primitive.js.map +1 -1
  8. package/dist/lib/rendering/entity-render-engine.js +22 -0
  9. package/dist/lib/rendering/entity-render-engine.js.map +1 -1
  10. package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js +5 -0
  11. package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js.map +1 -1
  12. package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js +8 -3
  13. package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js.map +1 -1
  14. package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js +5 -0
  15. package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js.map +1 -1
  16. package/dist/lib/rendering/render-managers/entities/entities-render-manager.js +5 -0
  17. package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
  18. package/dist/lib/rendering/visuals-register.js +8 -0
  19. package/dist/lib/rendering/visuals-register.js.map +1 -1
  20. package/dist/types/bruce-cesium.d.ts +1 -1
  21. package/dist/types/rendering/displaced-surface-primitive.d.ts +4 -0
  22. package/dist/types/rendering/entity-render-engine.d.ts +9 -0
  23. package/dist/types/rendering/visuals-register.d.ts +5 -0
  24. package/package.json +1 -1
@@ -9493,6 +9493,14 @@
9493
9493
  }
9494
9494
  };
9495
9495
  }
9496
+ /**
9497
+ * Whether this register is holding a record of a visual.
9498
+ * @param visual
9499
+ */
9500
+ HasRego(visual) {
9501
+ const vis = visual;
9502
+ return Boolean(vis && vis._register === this && vis._rego);
9503
+ }
9496
9504
  /**
9497
9505
  * Locates a visual corresponding to a given entity id.
9498
9506
  * If no menu item id is provided, then it will pick the "best" one.
@@ -12659,6 +12667,11 @@
12659
12667
  optimizeTolerance: this.item.optimizeTolerance,
12660
12668
  });
12661
12669
  if (this.disposed) {
12670
+ exports.EntityRenderEngine.RemoveAll({
12671
+ viewer: this.viewer,
12672
+ entities: cEntities,
12673
+ register: this.visualsManager
12674
+ });
12662
12675
  this.doDispose();
12663
12676
  return;
12664
12677
  }
@@ -13660,6 +13673,11 @@
13660
13673
  force
13661
13674
  });
13662
13675
  if (this.disposed) {
13676
+ exports.EntityRenderEngine.RemoveAll({
13677
+ viewer: this.viewer,
13678
+ entities: cEntities,
13679
+ register: this.visualsManager
13680
+ });
13663
13681
  this.visualsManager.RemoveRegos({
13664
13682
  menuItemId: this.item.id
13665
13683
  });
@@ -14099,10 +14117,15 @@
14099
14117
  zoomControl: this.item.CameraZoomSettings,
14100
14118
  force: force || changed
14101
14119
  });
14120
+ if (this.disposed) {
14121
+ exports.EntityRenderEngine.RemoveAll({
14122
+ viewer: this.viewer,
14123
+ entities: cEntities,
14124
+ register: this.visualsManager
14125
+ });
14126
+ return;
14127
+ }
14102
14128
  for (let i = 0; i < entities.length; i++) {
14103
- if (this.disposed) {
14104
- break;
14105
- }
14106
14129
  const entity = entities[i];
14107
14130
  const id = entity.Bruce.ID;
14108
14131
  const cEntity = cEntities.get(id);
@@ -19471,6 +19494,11 @@
19471
19494
  force
19472
19495
  });
19473
19496
  if (this.disposed) {
19497
+ exports.EntityRenderEngine.RemoveAll({
19498
+ viewer: this.viewer,
19499
+ entities: cEntities,
19500
+ register: this.visualsManager
19501
+ });
19474
19502
  return;
19475
19503
  }
19476
19504
  for (let i = 0; i < entities.length; i++) {
@@ -43545,17 +43573,21 @@ uniform vec2 u_maskGroundSize;
43545
43573
  uniform vec4 u_extentDegrees;
43546
43574
  uniform vec4 u_maskGroundDegrees;
43547
43575
  uniform float u_coverageCutoffVertex;
43576
+ //#water
43548
43577
  uniform vec2 u_extentMetres;
43549
43578
  uniform vec2 u_waveOrigin;
43579
+ //#endwater
43550
43580
 
43551
43581
  out vec2 v_st;
43552
43582
  out float v_value;
43553
43583
  out float v_coverage;
43584
+ //#water
43554
43585
  out vec3 v_positionEC;
43555
43586
  out vec3 v_eastEC;
43556
43587
  out vec3 v_northEC;
43557
43588
  out vec3 v_upEC;
43558
43589
  out vec2 v_waveMetres;
43590
+ //#endwater
43559
43591
 
43560
43592
  float decodeGround(vec2 uv) {
43561
43593
  // Channels arrive normalised to 0..1, so they go back to bytes before being reassembled.
@@ -43675,6 +43707,7 @@ void main() {
43675
43707
  // would be lost to float32 rounding at an earth radius.
43676
43708
  vec4 p = czm_translateRelativeToEye(position3DHigh, position3DLow + normal * displacement);
43677
43709
 
43710
+ //#water
43678
43711
  // The local frame at this vertex so a shading normal built in east/north/up meters can be turned into something usable.
43679
43712
  v_upEC = czm_normal * normal;
43680
43713
  vec3 east = normalize(cross(vec3(0.0, 0.0, 1.0), normal));
@@ -43682,16 +43715,9 @@ void main() {
43682
43715
  v_northEC = czm_normal * cross(normal, east);
43683
43716
  v_positionEC = (czm_modelViewRelativeToEye * p).xyz;
43684
43717
 
43685
- /*
43686
- * Where this vertex sits in the ripple field, in metres from an origin that follows the camera.
43687
- *
43688
- * Subtracted here rather than in the fragment shader because the position it is subtracted from
43689
- * spans the whole archive, which over a sound is tens of kilometres. A wave number times that
43690
- * is thousands of radians, and no fragment shader that may only have mediump can step through a
43691
- * cosine at that magnitude: the ripples come out as a flat surface, which is what a first cut of
43692
- * this did. What crosses into the fragment shader is a small number the camera is standing in.
43693
- */
43718
+ // Where this vertex sits in the ripple field, in metres from an origin that follows the camera.
43694
43719
  v_waveMetres = st * u_extentMetres - u_waveOrigin;
43720
+ //#endwater
43695
43721
 
43696
43722
  gl_Position = czm_modelViewProjectionRelativeToEye * p;
43697
43723
  }
@@ -43705,7 +43731,7 @@ uniform float u_valuePacked;
43705
43731
  uniform float u_valueRange;
43706
43732
  uniform float u_exaggeration;
43707
43733
  uniform float u_metresPerTexel;
43708
- uniform float u_waterOn;
43734
+ //#water
43709
43735
  uniform float u_waterWavelength;
43710
43736
  uniform float u_waterAmplitude;
43711
43737
  uniform float u_waterReflectivity;
@@ -43717,15 +43743,18 @@ uniform vec4 u_wavePhase;
43717
43743
  uniform vec4 u_wavePhaseB;
43718
43744
  // Metres the whole ripple field repeats over.
43719
43745
  uniform float u_wavePeriod;
43746
+ //#endwater
43720
43747
 
43721
43748
  in vec2 v_st;
43722
43749
  in float v_value;
43723
43750
  in float v_coverage;
43751
+ //#water
43724
43752
  in vec3 v_positionEC;
43725
43753
  in vec3 v_eastEC;
43726
43754
  in vec3 v_northEC;
43727
43755
  in vec3 v_upEC;
43728
43756
  in vec2 v_waveMetres;
43757
+ //#endwater
43729
43758
 
43730
43759
  /*
43731
43760
  * Scaled per channel for the same reason the vertex shader's decode is: reassembling the pair reaches
@@ -43737,6 +43766,7 @@ float valueAt(vec2 uv) {
43737
43766
  return mix(texel.r, packed16, u_valuePacked);
43738
43767
  }
43739
43768
 
43769
+ //#water
43740
43770
  /*
43741
43771
  * Slope of the ripple field at a point, in metres of rise per metre travelled.
43742
43772
  */
@@ -43812,6 +43842,7 @@ vec4 water(vec3 relief, vec4 color) {
43812
43842
  alpha = clamp(alpha + (1.0 - alpha) * (fresnel * 0.55 + glint), 0.0, 1.0);
43813
43843
  return vec4(lit, alpha);
43814
43844
  }
43845
+ //#endwater
43815
43846
 
43816
43847
  void main() {
43817
43848
  if (v_coverage < u_coverageCutoff) {
@@ -43834,10 +43865,10 @@ void main() {
43834
43865
  float scale = u_valueRange * u_exaggeration;
43835
43866
  vec3 n = normalize(vec3((left - right) * scale, (down - up) * scale, 2.0 * u_metresPerTexel));
43836
43867
 
43837
- if (u_waterOn > 0.5) {
43838
- out_FragColor = water(n, color);
43839
- return;
43840
- }
43868
+ //#water
43869
+ out_FragColor = water(n, color);
43870
+ return;
43871
+ //#endwater
43841
43872
 
43842
43873
  float lambert = clamp(dot(n, normalize(vec3(-0.5, -0.6, 0.62))), 0.0, 1.0);
43843
43874
  color.rgb *= 0.45 + 0.9 * lambert;
@@ -43845,6 +43876,15 @@ void main() {
43845
43876
  out_FragColor = vec4(color.rgb, color.a * v_coverage);
43846
43877
  }
43847
43878
  `;
43879
+ /*
43880
+ * Strips the water-only regions out of a shader source unless this surface is drawing water.
43881
+ */
43882
+ function withWater(source, water) {
43883
+ if (water) {
43884
+ return source.replace(/^\/\/#(end)?water\n/gm, "");
43885
+ }
43886
+ return source.replace(/^\/\/#water\n[\s\S]*?^\/\/#endwater\n/gm, "");
43887
+ }
43848
43888
  /*
43849
43889
  * Rewrites a GLSL 300 es source into the GLSL 100 dialect older Cesium builds author in.
43850
43890
  */
@@ -44173,6 +44213,7 @@ void main() {
44173
44213
  this.texture = null;
44174
44214
  this.textureDirty = true;
44175
44215
  this.shaderProgram = null;
44216
+ this.shaderProgramWater = false;
44176
44217
  this.renderState = null;
44177
44218
  this.destroyed = false;
44178
44219
  this.lastEyePosition = null;
@@ -44192,6 +44233,10 @@ void main() {
44192
44233
  this.water = null;
44193
44234
  this.waterStartMs = now();
44194
44235
  this.waveOrigin = new Cesium.Cartesian2(0, 0);
44236
+ this.extentMetresCache = null;
44237
+ // Written in place each frame rather than reallocated, since they are read per tile.
44238
+ this.wavePhaseScratch = [new Cesium.Cartesian4(), new Cesium.Cartesian4()];
44239
+ this.waterSkyScratch = new Cesium.Cartesian3();
44195
44240
  this.followGround = Boolean(options.followGround);
44196
44241
  this.terrainProvider = options.terrainProvider || null;
44197
44242
  this.extent = options.extent;
@@ -44616,32 +44661,45 @@ void main() {
44616
44661
  * 0..1 surface coordinate into the real distance the ripple wavelength is measured in.
44617
44662
  */
44618
44663
  extentMetres() {
44664
+ // The extent never moves, and this is read once per tile per frame.
44665
+ if (this.extentMetresCache) {
44666
+ return this.extentMetresCache;
44667
+ }
44619
44668
  const southWest = Cesium.Cartesian3.fromDegrees(this.extent.West, this.extent.South, 0);
44620
44669
  const southEast = Cesium.Cartesian3.fromDegrees(this.extent.East, this.extent.South, 0);
44621
44670
  const northWest = Cesium.Cartesian3.fromDegrees(this.extent.West, this.extent.North, 0);
44622
- return new Cesium.Cartesian2(Math.max(1, Cesium.Cartesian3.distance(southWest, southEast)), Math.max(1, Cesium.Cartesian3.distance(southWest, northWest)));
44671
+ this.extentMetresCache = new Cesium.Cartesian2(Math.max(1, Cesium.Cartesian3.distance(southWest, southEast)), Math.max(1, Cesium.Cartesian3.distance(southWest, northWest)));
44672
+ return this.extentMetresCache;
44623
44673
  }
44624
44674
  /*
44625
44675
  * Where each ripple layer has scrolled to, wrapped into one turn.
44626
44676
  */
44627
44677
  wavePhase(from) {
44628
44678
  var _a;
44679
+ const into = this.wavePhaseScratch[from / 4];
44629
44680
  const water = this.water;
44630
44681
  if (!water) {
44631
- return new Cesium.Cartesian4(0, 0, 0, 0);
44682
+ return Cesium.Cartesian4.clone(Cesium.Cartesian4.ZERO, into);
44632
44683
  }
44633
44684
  const speed = (_a = water.speed) !== null && _a !== void 0 ? _a : DEFAULT_WATER_SPEED_METRES_PER_SECOND;
44634
44685
  const period = this.wavePeriod();
44635
44686
  const seconds = (now() - this.waterStartMs) / 1000;
44636
44687
  const base = waveCycles(WATER_WAVES[WATER_BASE_WAVE]);
44637
- const phases = WATER_WAVES.slice(from, from + 4).map((wave) => {
44688
+ const phaseAt = (index) => {
44689
+ const wave = WATER_WAVES[from + index];
44690
+ if (!wave) {
44691
+ return 0;
44692
+ }
44638
44693
  const cycles = waveCycles(wave);
44639
44694
  const waveNumber = 2 * Math.PI * cycles / period;
44640
44695
  const travels = Math.sqrt(base / cycles);
44641
- const travelled = seconds * speed * travels * waveNumber;
44642
- return travelled % (2 * Math.PI);
44643
- });
44644
- return new Cesium.Cartesian4(phases[0] || 0, phases[1] || 0, phases[2] || 0, phases[3] || 0);
44696
+ return (seconds * speed * travels * waveNumber) % (2 * Math.PI);
44697
+ };
44698
+ into.x = phaseAt(0);
44699
+ into.y = phaseAt(1);
44700
+ into.z = phaseAt(2);
44701
+ into.w = phaseAt(3);
44702
+ return into;
44645
44703
  }
44646
44704
  wavePeriod() {
44647
44705
  const wavelength = (this.water && this.water.wavelength) || DEFAULT_WATER_WAVELENGTH_METRES;
@@ -44828,14 +44886,22 @@ void main() {
44828
44886
  return isFinite(nearest) ? Math.max(1, nearest) : 1;
44829
44887
  }
44830
44888
  commandFor(context, tile, mesh) {
44889
+ // Rebuilt when the effect is switched, since which program is wanted is part of it.
44890
+ const wantsWater = Boolean(this.water);
44891
+ if (this.shaderProgram && this.shaderProgramWater !== wantsWater) {
44892
+ this.shaderProgram = null;
44893
+ }
44831
44894
  if (!this.shaderProgram) {
44832
44895
  const glsl300 = usesGlsl300(context);
44896
+ const vertex = withWater(VERTEX_SHADER_GLSL300, wantsWater);
44897
+ const fragment = withWater(FRAGMENT_SHADER_GLSL300, wantsWater);
44833
44898
  this.shaderProgram = Cesium.ShaderProgram.fromCache({
44834
44899
  context,
44835
- vertexShaderSource: glsl300 ? VERTEX_SHADER_GLSL300 : toGlsl100(VERTEX_SHADER_GLSL300, false),
44836
- fragmentShaderSource: glsl300 ? FRAGMENT_SHADER_GLSL300 : toGlsl100(FRAGMENT_SHADER_GLSL300, true),
44900
+ vertexShaderSource: glsl300 ? vertex : toGlsl100(vertex, false),
44901
+ fragmentShaderSource: glsl300 ? fragment : toGlsl100(fragment, true),
44837
44902
  attributeLocations: mesh.attributeLocations
44838
44903
  });
44904
+ this.shaderProgramWater = wantsWater;
44839
44905
  this.renderState = Cesium.RenderState.fromCache({
44840
44906
  depthTest: { enabled: true },
44841
44907
  // Translucent ramp: blend, and leave the depth buffer to the opaque world.
@@ -44911,7 +44977,7 @@ void main() {
44911
44977
  },
44912
44978
  u_waterSky: () => {
44913
44979
  const sky = (self.water && self.water.skyColor) || DEFAULT_WATER_SKY_COLOR;
44914
- return new Cesium.Cartesian3(sky.red / 255, sky.green / 255, sky.blue / 255);
44980
+ return Cesium.Cartesian3.fromElements(sky.red / 255, sky.green / 255, sky.blue / 255, self.waterSkyScratch);
44915
44981
  },
44916
44982
  u_wavePhase: () => self.wavePhase(0),
44917
44983
  u_wavePhaseB: () => self.wavePhase(4),
@@ -44922,6 +44988,7 @@ void main() {
44922
44988
  });
44923
44989
  }
44924
44990
  // Bounding volume belongs to the mesh, so it follows whichever tier is drawing.
44991
+ tile.command.shaderProgram = this.shaderProgram;
44925
44992
  tile.command.vertexArray = mesh.vertexArray;
44926
44993
  tile.command.boundingVolume = mesh.boundingSphere;
44927
44994
  return tile.command;
@@ -46870,6 +46937,28 @@ void main() {
46870
46937
  };
46871
46938
  }
46872
46939
  EntityRenderEngine.Render = Render;
46940
+ /**
46941
+ * Removes what a render produced that nothing has a record of, for a render whose caller has gone away.
46942
+ * @param params
46943
+ */
46944
+ function RemoveAll(params) {
46945
+ const { viewer, entities, register } = params;
46946
+ if (!entities || viewer.isDestroyed()) {
46947
+ return;
46948
+ }
46949
+ entities.forEach((entity) => {
46950
+ if (!entity || (register === null || register === void 0 ? void 0 : register.HasRego(entity))) {
46951
+ return;
46952
+ }
46953
+ try {
46954
+ Remove({ viewer, entity });
46955
+ }
46956
+ catch (e) {
46957
+ console.error("EntityRenderEngine.RemoveAll: failed to remove a visual:", e);
46958
+ }
46959
+ });
46960
+ }
46961
+ EntityRenderEngine.RemoveAll = RemoveAll;
46873
46962
  function Remove(params) {
46874
46963
  function doRemove(params) {
46875
46964
  const { viewer, entity, ignoreParent } = params;
@@ -47695,7 +47784,7 @@ void main() {
47695
47784
  StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
47696
47785
  })(exports.StyleUtils || (exports.StyleUtils = {}));
47697
47786
 
47698
- const VERSION = "7.3.7";
47787
+ const VERSION = "7.3.8";
47699
47788
  /**
47700
47789
  * Updates the environment instance used by bruce-cesium to one specified.
47701
47790
  * This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.