import Intersect from '../Core/Intersect.js'; import ManagedArray from '../Core/ManagedArray.js'; import Cesium3DTileRefine from './Cesium3DTileRefine.js'; /** * Traversal that loads all leaves that intersect the camera frustum. * Used to determine ray-tileset intersections during a pickFromRayMostDetailed call. * * @private */ function Cesium3DTilesetMostDetailedTraversal() { } var traversal = { stack : new ManagedArray(), stackMaximumLength : 0 }; Cesium3DTilesetMostDetailedTraversal.selectTiles = function(tileset, frameState) { tileset._selectedTiles.length = 0; tileset._requestedTiles.length = 0; tileset._hasMixedContent = false; var ready = true; var root = tileset.root; root.updateVisibility(frameState); if (!isVisible(root)) { return ready; } var stack = traversal.stack; stack.push(tileset.root); while (stack.length > 0) { traversal.stackMaximumLength = Math.max(traversal.stackMaximumLength, stack.length); var tile = stack.pop(); var add = (tile.refine === Cesium3DTileRefine.ADD); var replace = (tile.refine === Cesium3DTileRefine.REPLACE); var traverse = canTraverse(tileset, tile); if (traverse) { updateAndPushChildren(tileset, tile, stack, frameState); } if (add || (replace && !traverse)) { loadTile(tileset, tile); touchTile(tileset, tile, frameState); selectDesiredTile(tileset, tile, frameState); if (!hasEmptyContent(tile) && !tile.contentAvailable) { ready = false; } } visitTile(tileset); } traversal.stack.trim(traversal.stackMaximumLength); return ready; }; function isVisible(tile) { return tile._visible && tile._inRequestVolume; } function hasEmptyContent(tile) { return tile.hasEmptyContent || tile.hasTilesetContent; } function hasUnloadedContent(tile) { return !hasEmptyContent(tile) && tile.contentUnloaded; } function canTraverse(tileset, tile) { if (tile.children.length === 0) { return false; } if (tile.hasTilesetContent) { // Traverse external tileset to visit its root tile // Don't traverse if the subtree is expired because it will be destroyed return !tile.contentExpired; } if (tile.hasEmptyContent) { return true; } return true; // Keep traversing until a leave is hit } function updateAndPushChildren(tileset, tile, stack, frameState) { var children = tile.children; var length = children.length; for (var i = 0; i < length; ++i) { var child = children[i]; child.updateVisibility(frameState); if (isVisible(child)) { stack.push(child); } } } function loadTile(tileset, tile) { if (hasUnloadedContent(tile) || tile.contentExpired) { tile._priority = 0.0; // Highest priority tileset._requestedTiles.push(tile); } } function touchTile(tileset, tile, frameState) { if (tile._touchedFrame === frameState.frameNumber) { // Prevents another pass from touching the frame again return; } tileset._cache.touch(tile); tile._touchedFrame = frameState.frameNumber; } function visitTile(tileset) { ++tileset.statistics.visited; } function selectDesiredTile(tileset, tile, frameState) { if (tile.contentAvailable && (tile.contentVisibility(frameState) !== Intersect.OUTSIDE)) { tileset._selectedTiles.push(tile); } } export default Cesium3DTilesetMostDetailedTraversal;