TileImagery.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import defined from "../Core/defined.js";
  2. import ImageryState from "./ImageryState.js";
  3. /**
  4. * The assocation between a terrain tile and an imagery tile.
  5. *
  6. * @alias TileImagery
  7. * @private
  8. *
  9. * @param {Imagery} imagery The imagery tile.
  10. * @param {Cartesian4} textureCoordinateRectangle The texture rectangle of the tile that is covered
  11. * by the imagery, where X=west, Y=south, Z=east, W=north.
  12. * @param {boolean} useWebMercatorT true to use the Web Mercator texture coordinates for this imagery tile.
  13. */
  14. function TileImagery(imagery, textureCoordinateRectangle, useWebMercatorT) {
  15. this.readyImagery = undefined;
  16. this.loadingImagery = imagery;
  17. this.textureCoordinateRectangle = textureCoordinateRectangle;
  18. this.textureTranslationAndScale = undefined;
  19. this.useWebMercatorT = useWebMercatorT;
  20. }
  21. /**
  22. * Frees the resources held by this instance.
  23. */
  24. TileImagery.prototype.freeResources = function () {
  25. if (defined(this.readyImagery)) {
  26. this.readyImagery.releaseReference();
  27. }
  28. if (defined(this.loadingImagery)) {
  29. this.loadingImagery.releaseReference();
  30. }
  31. };
  32. /**
  33. * Processes the load state machine for this instance.
  34. *
  35. * @param {Tile} tile The tile to which this instance belongs.
  36. * @param {FrameState} frameState The frameState.
  37. * @param {boolean} skipLoading True to skip loading, e.g. new requests, creating textures. This function will
  38. * still synchronously process imagery that's already mostly ready to go, e.g. use textures
  39. * already loaded on ancestor tiles.
  40. * @returns {boolean} True if this instance is done loading; otherwise, false.
  41. */
  42. TileImagery.prototype.processStateMachine = function (
  43. tile,
  44. frameState,
  45. skipLoading
  46. ) {
  47. const loadingImagery = this.loadingImagery;
  48. const imageryLayer = loadingImagery.imageryLayer;
  49. loadingImagery.processStateMachine(
  50. frameState,
  51. !this.useWebMercatorT,
  52. skipLoading
  53. );
  54. if (loadingImagery.state === ImageryState.READY) {
  55. if (defined(this.readyImagery)) {
  56. this.readyImagery.releaseReference();
  57. }
  58. this.readyImagery = this.loadingImagery;
  59. this.loadingImagery = undefined;
  60. this.textureTranslationAndScale = imageryLayer._calculateTextureTranslationAndScale(
  61. tile,
  62. this
  63. );
  64. return true; // done loading
  65. }
  66. // Find some ancestor imagery we can use while this imagery is still loading.
  67. let ancestor = loadingImagery.parent;
  68. let closestAncestorThatNeedsLoading;
  69. while (
  70. defined(ancestor) &&
  71. (ancestor.state !== ImageryState.READY ||
  72. (!this.useWebMercatorT && !defined(ancestor.texture)))
  73. ) {
  74. if (
  75. ancestor.state !== ImageryState.FAILED &&
  76. ancestor.state !== ImageryState.INVALID
  77. ) {
  78. // ancestor is still loading
  79. closestAncestorThatNeedsLoading =
  80. closestAncestorThatNeedsLoading || ancestor;
  81. }
  82. ancestor = ancestor.parent;
  83. }
  84. if (this.readyImagery !== ancestor) {
  85. if (defined(this.readyImagery)) {
  86. this.readyImagery.releaseReference();
  87. }
  88. this.readyImagery = ancestor;
  89. if (defined(ancestor)) {
  90. ancestor.addReference();
  91. this.textureTranslationAndScale = imageryLayer._calculateTextureTranslationAndScale(
  92. tile,
  93. this
  94. );
  95. }
  96. }
  97. if (
  98. loadingImagery.state === ImageryState.FAILED ||
  99. loadingImagery.state === ImageryState.INVALID
  100. ) {
  101. // The imagery tile is failed or invalid, so we'd like to use an ancestor instead.
  102. if (defined(closestAncestorThatNeedsLoading)) {
  103. // Push the ancestor's load process along a bit. This is necessary because some ancestor imagery
  104. // tiles may not be attached directly to a terrain tile. Such tiles will never load if
  105. // we don't do it here.
  106. closestAncestorThatNeedsLoading.processStateMachine(
  107. frameState,
  108. !this.useWebMercatorT,
  109. skipLoading
  110. );
  111. return false; // not done loading
  112. }
  113. // This imagery tile is failed or invalid, and we have the "best available" substitute.
  114. return true; // done loading
  115. }
  116. return false; // not done loading
  117. };
  118. export default TileImagery;