123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- 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() {}
- const traversal = {
- stack: new ManagedArray(),
- stackMaximumLength: 0,
- };
- Cesium3DTilesetMostDetailedTraversal.selectTiles = function (
- tileset,
- frameState
- ) {
- tileset._selectedTiles.length = 0;
- tileset._requestedTiles.length = 0;
- tileset._hasMixedContent = false;
- let ready = true;
- const root = tileset.root;
- root.updateVisibility(frameState);
- if (!isVisible(root)) {
- return ready;
- }
- const stack = traversal.stack;
- stack.push(tileset.root);
- while (stack.length > 0) {
- traversal.stackMaximumLength = Math.max(
- traversal.stackMaximumLength,
- stack.length
- );
- const tile = stack.pop();
- const add = tile.refine === Cesium3DTileRefine.ADD;
- const replace = tile.refine === Cesium3DTileRefine.REPLACE;
- const 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 || tile.hasImplicitContent
- );
- }
- function hasUnloadedContent(tile) {
- return !hasEmptyContent(tile) && tile.contentUnloaded;
- }
- function canTraverse(tileset, tile) {
- if (tile.children.length === 0) {
- return false;
- }
- if (tile.hasTilesetContent || tile.hasImplicitContent) {
- // 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) {
- const children = tile.children;
- const length = children.length;
- for (let i = 0; i < length; ++i) {
- const 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;
|