All files / engine/Source/Scene TileImagery.js

94.87% Statements 37/39
90% Branches 27/30
100% Functions 3/3
94.87% Lines 37/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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