Cesium3DTilesetMostDetailedTraversal.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import Intersect from "../Core/Intersect.js";
  2. import ManagedArray from "../Core/ManagedArray.js";
  3. import Cesium3DTileRefine from "./Cesium3DTileRefine.js";
  4. /**
  5. * Traversal that loads all leaves that intersect the camera frustum.
  6. * Used to determine ray-tileset intersections during a pickFromRayMostDetailed call.
  7. *
  8. * @private
  9. */
  10. function Cesium3DTilesetMostDetailedTraversal() {}
  11. const traversal = {
  12. stack: new ManagedArray(),
  13. stackMaximumLength: 0,
  14. };
  15. Cesium3DTilesetMostDetailedTraversal.selectTiles = function (
  16. tileset,
  17. frameState
  18. ) {
  19. tileset._selectedTiles.length = 0;
  20. tileset._requestedTiles.length = 0;
  21. tileset._hasMixedContent = false;
  22. let ready = true;
  23. const root = tileset.root;
  24. root.updateVisibility(frameState);
  25. if (!isVisible(root)) {
  26. return ready;
  27. }
  28. const stack = traversal.stack;
  29. stack.push(tileset.root);
  30. while (stack.length > 0) {
  31. traversal.stackMaximumLength = Math.max(
  32. traversal.stackMaximumLength,
  33. stack.length
  34. );
  35. const tile = stack.pop();
  36. const add = tile.refine === Cesium3DTileRefine.ADD;
  37. const replace = tile.refine === Cesium3DTileRefine.REPLACE;
  38. const traverse = canTraverse(tileset, tile);
  39. if (traverse) {
  40. updateAndPushChildren(tileset, tile, stack, frameState);
  41. }
  42. if (add || (replace && !traverse)) {
  43. loadTile(tileset, tile);
  44. touchTile(tileset, tile, frameState);
  45. selectDesiredTile(tileset, tile, frameState);
  46. if (!hasEmptyContent(tile) && !tile.contentAvailable) {
  47. ready = false;
  48. }
  49. }
  50. visitTile(tileset);
  51. }
  52. traversal.stack.trim(traversal.stackMaximumLength);
  53. return ready;
  54. };
  55. function isVisible(tile) {
  56. return tile._visible && tile._inRequestVolume;
  57. }
  58. function hasEmptyContent(tile) {
  59. return (
  60. tile.hasEmptyContent || tile.hasTilesetContent || tile.hasImplicitContent
  61. );
  62. }
  63. function hasUnloadedContent(tile) {
  64. return !hasEmptyContent(tile) && tile.contentUnloaded;
  65. }
  66. function canTraverse(tileset, tile) {
  67. if (tile.children.length === 0) {
  68. return false;
  69. }
  70. if (tile.hasTilesetContent || tile.hasImplicitContent) {
  71. // Traverse external tileset to visit its root tile
  72. // Don't traverse if the subtree is expired because it will be destroyed
  73. return !tile.contentExpired;
  74. }
  75. if (tile.hasEmptyContent) {
  76. return true;
  77. }
  78. return true; // Keep traversing until a leave is hit
  79. }
  80. function updateAndPushChildren(tileset, tile, stack, frameState) {
  81. const children = tile.children;
  82. const length = children.length;
  83. for (let i = 0; i < length; ++i) {
  84. const child = children[i];
  85. child.updateVisibility(frameState);
  86. if (isVisible(child)) {
  87. stack.push(child);
  88. }
  89. }
  90. }
  91. function loadTile(tileset, tile) {
  92. if (hasUnloadedContent(tile) || tile.contentExpired) {
  93. tile._priority = 0.0; // Highest priority
  94. tileset._requestedTiles.push(tile);
  95. }
  96. }
  97. function touchTile(tileset, tile, frameState) {
  98. if (tile._touchedFrame === frameState.frameNumber) {
  99. // Prevents another pass from touching the frame again
  100. return;
  101. }
  102. tileset._cache.touch(tile);
  103. tile._touchedFrame = frameState.frameNumber;
  104. }
  105. function visitTile(tileset) {
  106. ++tileset.statistics.visited;
  107. }
  108. function selectDesiredTile(tileset, tile, frameState) {
  109. if (
  110. tile.contentAvailable &&
  111. tile.contentVisibility(frameState) !== Intersect.OUTSIDE
  112. ) {
  113. tileset._selectedTiles.push(tile);
  114. }
  115. }
  116. export default Cesium3DTilesetMostDetailedTraversal;