1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579 |
- import Cartesian3 from "../Core/Cartesian3.js";
- import Cartographic from "../Core/Cartographic.js";
- import defaultValue from "../Core/defaultValue.js";
- import defined from "../Core/defined.js";
- import DeveloperError from "../Core/DeveloperError.js";
- import Event from "../Core/Event.js";
- import getTimestamp from "../Core/getTimestamp.js";
- import CesiumMath from "../Core/Math.js";
- import Matrix4 from "../Core/Matrix4.js";
- import OrthographicFrustum from "../Core/OrthographicFrustum.js";
- import OrthographicOffCenterFrustum from "../Core/OrthographicOffCenterFrustum.js";
- import Ray from "../Core/Ray.js";
- import Rectangle from "../Core/Rectangle.js";
- import Visibility from "../Core/Visibility.js";
- import QuadtreeOccluders from "./QuadtreeOccluders.js";
- import QuadtreeTile from "./QuadtreeTile.js";
- import QuadtreeTileLoadState from "./QuadtreeTileLoadState.js";
- import SceneMode from "./SceneMode.js";
- import TileReplacementQueue from "./TileReplacementQueue.js";
- import TileSelectionResult from "./TileSelectionResult.js";
- function QuadtreePrimitive(options) {
-
- if (!defined(options) || !defined(options.tileProvider)) {
- throw new DeveloperError("options.tileProvider is required.");
- }
- if (defined(options.tileProvider.quadtree)) {
- throw new DeveloperError(
- "A QuadtreeTileProvider can only be used with a single QuadtreePrimitive"
- );
- }
-
- this._tileProvider = options.tileProvider;
- this._tileProvider.quadtree = this;
- this._debug = {
- enableDebugOutput: false,
- maxDepth: 0,
- maxDepthVisited: 0,
- tilesVisited: 0,
- tilesCulled: 0,
- tilesRendered: 0,
- tilesWaitingForChildren: 0,
- lastMaxDepth: -1,
- lastMaxDepthVisited: -1,
- lastTilesVisited: -1,
- lastTilesCulled: -1,
- lastTilesRendered: -1,
- lastTilesWaitingForChildren: -1,
- suspendLodUpdate: false,
- };
- var tilingScheme = this._tileProvider.tilingScheme;
- var ellipsoid = tilingScheme.ellipsoid;
- this._tilesToRender = [];
- this._tileLoadQueueHigh = [];
- this._tileLoadQueueMedium = [];
- this._tileLoadQueueLow = [];
- this._tileReplacementQueue = new TileReplacementQueue();
- this._levelZeroTiles = undefined;
- this._loadQueueTimeSlice = 5.0;
- this._tilesInvalidated = false;
- this._addHeightCallbacks = [];
- this._removeHeightCallbacks = [];
- this._tileToUpdateHeights = [];
- this._lastTileIndex = 0;
- this._updateHeightsTimeSlice = 2.0;
-
-
-
-
- this._cameraPositionCartographic = undefined;
- this._cameraReferenceFrameOriginCartographic = undefined;
-
- this.maximumScreenSpaceError = defaultValue(
- options.maximumScreenSpaceError,
- 2
- );
-
- this.tileCacheSize = defaultValue(options.tileCacheSize, 100);
-
- this.loadingDescendantLimit = 20;
-
- this.preloadAncestors = true;
-
- this.preloadSiblings = false;
- this._occluders = new QuadtreeOccluders({
- ellipsoid: ellipsoid,
- });
- this._tileLoadProgressEvent = new Event();
- this._lastTileLoadQueueLength = 0;
- this._lastSelectionFrameNumber = undefined;
- }
- Object.defineProperties(QuadtreePrimitive.prototype, {
-
- tileProvider: {
- get: function () {
- return this._tileProvider;
- },
- },
-
- tileLoadProgressEvent: {
- get: function () {
- return this._tileLoadProgressEvent;
- },
- },
- occluders: {
- get: function () {
- return this._occluders;
- },
- },
- });
- QuadtreePrimitive.prototype.invalidateAllTiles = function () {
- this._tilesInvalidated = true;
- };
- function invalidateAllTiles(primitive) {
-
- var replacementQueue = primitive._tileReplacementQueue;
- replacementQueue.head = undefined;
- replacementQueue.tail = undefined;
- replacementQueue.count = 0;
- clearTileLoadQueue(primitive);
-
- var levelZeroTiles = primitive._levelZeroTiles;
- if (defined(levelZeroTiles)) {
- for (var i = 0; i < levelZeroTiles.length; ++i) {
- var tile = levelZeroTiles[i];
- var customData = tile.customData;
- var customDataLength = customData.length;
- for (var j = 0; j < customDataLength; ++j) {
- var data = customData[j];
- data.level = 0;
- primitive._addHeightCallbacks.push(data);
- }
- levelZeroTiles[i].freeResources();
- }
- }
- primitive._levelZeroTiles = undefined;
- primitive._tileProvider.cancelReprojections();
- }
- QuadtreePrimitive.prototype.forEachLoadedTile = function (tileFunction) {
- var tile = this._tileReplacementQueue.head;
- while (defined(tile)) {
- if (tile.state !== QuadtreeTileLoadState.START) {
- tileFunction(tile);
- }
- tile = tile.replacementNext;
- }
- };
- QuadtreePrimitive.prototype.forEachRenderedTile = function (tileFunction) {
- var tilesRendered = this._tilesToRender;
- for (var i = 0, len = tilesRendered.length; i < len; ++i) {
- tileFunction(tilesRendered[i]);
- }
- };
- QuadtreePrimitive.prototype.updateHeight = function (cartographic, callback) {
- var primitive = this;
- var object = {
- positionOnEllipsoidSurface: undefined,
- positionCartographic: cartographic,
- level: -1,
- callback: callback,
- };
- object.removeFunc = function () {
- var addedCallbacks = primitive._addHeightCallbacks;
- var length = addedCallbacks.length;
- for (var i = 0; i < length; ++i) {
- if (addedCallbacks[i] === object) {
- addedCallbacks.splice(i, 1);
- break;
- }
- }
- primitive._removeHeightCallbacks.push(object);
- };
- primitive._addHeightCallbacks.push(object);
- return object.removeFunc;
- };
- QuadtreePrimitive.prototype.update = function (frameState) {
- if (defined(this._tileProvider.update)) {
- this._tileProvider.update(frameState);
- }
- };
- function clearTileLoadQueue(primitive) {
- var debug = primitive._debug;
- debug.maxDepth = 0;
- debug.maxDepthVisited = 0;
- debug.tilesVisited = 0;
- debug.tilesCulled = 0;
- debug.tilesRendered = 0;
- debug.tilesWaitingForChildren = 0;
- primitive._tileLoadQueueHigh.length = 0;
- primitive._tileLoadQueueMedium.length = 0;
- primitive._tileLoadQueueLow.length = 0;
- }
- QuadtreePrimitive.prototype.beginFrame = function (frameState) {
- var passes = frameState.passes;
- if (!passes.render) {
- return;
- }
- if (this._tilesInvalidated) {
- invalidateAllTiles(this);
- this._tilesInvalidated = false;
- }
-
- this._tileProvider.initialize(frameState);
- clearTileLoadQueue(this);
- if (this._debug.suspendLodUpdate) {
- return;
- }
- this._tileReplacementQueue.markStartOfRenderFrame();
- };
- QuadtreePrimitive.prototype.render = function (frameState) {
- var passes = frameState.passes;
- var tileProvider = this._tileProvider;
- if (passes.render) {
- tileProvider.beginUpdate(frameState);
- selectTilesForRendering(this, frameState);
- createRenderCommandsForSelectedTiles(this, frameState);
- tileProvider.endUpdate(frameState);
- }
- if (passes.pick && this._tilesToRender.length > 0) {
- tileProvider.updateForPick(frameState);
- }
- };
- function updateTileLoadProgress(primitive, frameState) {
- var currentLoadQueueLength =
- primitive._tileLoadQueueHigh.length +
- primitive._tileLoadQueueMedium.length +
- primitive._tileLoadQueueLow.length;
- if (
- currentLoadQueueLength !== primitive._lastTileLoadQueueLength ||
- primitive._tilesInvalidated
- ) {
- frameState.afterRender.push(
- Event.prototype.raiseEvent.bind(
- primitive._tileLoadProgressEvent,
- currentLoadQueueLength
- )
- );
- primitive._lastTileLoadQueueLength = currentLoadQueueLength;
- }
- var debug = primitive._debug;
- if (debug.enableDebugOutput && !debug.suspendLodUpdate) {
- debug.maxDepth = primitive._tilesToRender.reduce(function (max, tile) {
- return Math.max(max, tile.level);
- }, -1);
- debug.tilesRendered = primitive._tilesToRender.length;
- if (
- debug.tilesVisited !== debug.lastTilesVisited ||
- debug.tilesRendered !== debug.lastTilesRendered ||
- debug.tilesCulled !== debug.lastTilesCulled ||
- debug.maxDepth !== debug.lastMaxDepth ||
- debug.tilesWaitingForChildren !== debug.lastTilesWaitingForChildren ||
- debug.maxDepthVisited !== debug.lastMaxDepthVisited
- ) {
- console.log(
- "Visited " +
- debug.tilesVisited +
- ", Rendered: " +
- debug.tilesRendered +
- ", Culled: " +
- debug.tilesCulled +
- ", Max Depth Rendered: " +
- debug.maxDepth +
- ", Max Depth Visited: " +
- debug.maxDepthVisited +
- ", Waiting for children: " +
- debug.tilesWaitingForChildren
- );
- debug.lastTilesVisited = debug.tilesVisited;
- debug.lastTilesRendered = debug.tilesRendered;
- debug.lastTilesCulled = debug.tilesCulled;
- debug.lastMaxDepth = debug.maxDepth;
- debug.lastTilesWaitingForChildren = debug.tilesWaitingForChildren;
- debug.lastMaxDepthVisited = debug.maxDepthVisited;
- }
- }
- }
- QuadtreePrimitive.prototype.endFrame = function (frameState) {
- var passes = frameState.passes;
- if (!passes.render || frameState.mode === SceneMode.MORPHING) {
-
-
- return;
- }
-
- processTileLoadQueue(this, frameState);
- updateHeights(this, frameState);
- updateTileLoadProgress(this, frameState);
- };
- QuadtreePrimitive.prototype.isDestroyed = function () {
- return false;
- };
- QuadtreePrimitive.prototype.destroy = function () {
- this._tileProvider = this._tileProvider && this._tileProvider.destroy();
- };
- var comparisonPoint;
- var centerScratch = new Cartographic();
- function compareDistanceToPoint(a, b) {
- var center = Rectangle.center(a.rectangle, centerScratch);
- var alon = center.longitude - comparisonPoint.longitude;
- var alat = center.latitude - comparisonPoint.latitude;
- center = Rectangle.center(b.rectangle, centerScratch);
- var blon = center.longitude - comparisonPoint.longitude;
- var blat = center.latitude - comparisonPoint.latitude;
- return alon * alon + alat * alat - (blon * blon + blat * blat);
- }
- var cameraOriginScratch = new Cartesian3();
- var rootTraversalDetails = [];
- function selectTilesForRendering(primitive, frameState) {
- var debug = primitive._debug;
- if (debug.suspendLodUpdate) {
- return;
- }
-
- var tilesToRender = primitive._tilesToRender;
- tilesToRender.length = 0;
-
- var i;
- var tileProvider = primitive._tileProvider;
- if (!defined(primitive._levelZeroTiles)) {
- if (tileProvider.ready) {
- var tilingScheme = tileProvider.tilingScheme;
- primitive._levelZeroTiles = QuadtreeTile.createLevelZeroTiles(
- tilingScheme
- );
- var numberOfRootTiles = primitive._levelZeroTiles.length;
- if (rootTraversalDetails.length < numberOfRootTiles) {
- rootTraversalDetails = new Array(numberOfRootTiles);
- for (i = 0; i < numberOfRootTiles; ++i) {
- if (rootTraversalDetails[i] === undefined) {
- rootTraversalDetails[i] = new TraversalDetails();
- }
- }
- }
- } else {
-
- return;
- }
- }
- primitive._occluders.ellipsoid.cameraPosition = frameState.camera.positionWC;
- var tile;
- var levelZeroTiles = primitive._levelZeroTiles;
- var occluders = levelZeroTiles.length > 1 ? primitive._occluders : undefined;
-
-
-
- comparisonPoint = frameState.camera.positionCartographic;
- levelZeroTiles.sort(compareDistanceToPoint);
- var customDataAdded = primitive._addHeightCallbacks;
- var customDataRemoved = primitive._removeHeightCallbacks;
- var frameNumber = frameState.frameNumber;
- var len;
- if (customDataAdded.length > 0 || customDataRemoved.length > 0) {
- for (i = 0, len = levelZeroTiles.length; i < len; ++i) {
- tile = levelZeroTiles[i];
- tile._updateCustomData(frameNumber, customDataAdded, customDataRemoved);
- }
- customDataAdded.length = 0;
- customDataRemoved.length = 0;
- }
- var camera = frameState.camera;
- primitive._cameraPositionCartographic = camera.positionCartographic;
- var cameraFrameOrigin = Matrix4.getTranslation(
- camera.transform,
- cameraOriginScratch
- );
- primitive._cameraReferenceFrameOriginCartographic = primitive.tileProvider.tilingScheme.ellipsoid.cartesianToCartographic(
- cameraFrameOrigin,
- primitive._cameraReferenceFrameOriginCartographic
- );
-
- for (i = 0, len = levelZeroTiles.length; i < len; ++i) {
- tile = levelZeroTiles[i];
- primitive._tileReplacementQueue.markTileRendered(tile);
- if (!tile.renderable) {
- queueTileLoad(primitive, primitive._tileLoadQueueHigh, tile, frameState);
- ++debug.tilesWaitingForChildren;
- } else {
- visitIfVisible(
- primitive,
- tile,
- tileProvider,
- frameState,
- occluders,
- false,
- rootTraversalDetails[i]
- );
- }
- }
- primitive._lastSelectionFrameNumber = frameNumber;
- }
- function queueTileLoad(primitive, queue, tile, frameState) {
- if (!tile.needsLoading) {
- return;
- }
- if (primitive.tileProvider.computeTileLoadPriority !== undefined) {
- tile._loadPriority = primitive.tileProvider.computeTileLoadPriority(
- tile,
- frameState
- );
- }
- queue.push(tile);
- }
- function TraversalDetails() {
-
- this.allAreRenderable = true;
-
- this.anyWereRenderedLastFrame = false;
-
- this.notYetRenderableCount = 0;
- }
- function TraversalQuadDetails() {
- this.southwest = new TraversalDetails();
- this.southeast = new TraversalDetails();
- this.northwest = new TraversalDetails();
- this.northeast = new TraversalDetails();
- }
- TraversalQuadDetails.prototype.combine = function (result) {
- var southwest = this.southwest;
- var southeast = this.southeast;
- var northwest = this.northwest;
- var northeast = this.northeast;
- result.allAreRenderable =
- southwest.allAreRenderable &&
- southeast.allAreRenderable &&
- northwest.allAreRenderable &&
- northeast.allAreRenderable;
- result.anyWereRenderedLastFrame =
- southwest.anyWereRenderedLastFrame ||
- southeast.anyWereRenderedLastFrame ||
- northwest.anyWereRenderedLastFrame ||
- northeast.anyWereRenderedLastFrame;
- result.notYetRenderableCount =
- southwest.notYetRenderableCount +
- southeast.notYetRenderableCount +
- northwest.notYetRenderableCount +
- northeast.notYetRenderableCount;
- };
- var traversalQuadsByLevel = new Array(31);
- for (var i = 0; i < traversalQuadsByLevel.length; ++i) {
- traversalQuadsByLevel[i] = new TraversalQuadDetails();
- }
- function visitTile(
- primitive,
- frameState,
- tile,
- ancestorMeetsSse,
- traversalDetails
- ) {
- var debug = primitive._debug;
- ++debug.tilesVisited;
- primitive._tileReplacementQueue.markTileRendered(tile);
- tile._updateCustomData(frameState.frameNumber);
- if (tile.level > debug.maxDepthVisited) {
- debug.maxDepthVisited = tile.level;
- }
- var meetsSse =
- screenSpaceError(primitive, frameState, tile) <
- primitive.maximumScreenSpaceError;
- var southwestChild = tile.southwestChild;
- var southeastChild = tile.southeastChild;
- var northwestChild = tile.northwestChild;
- var northeastChild = tile.northeastChild;
- var lastFrame = primitive._lastSelectionFrameNumber;
- var lastFrameSelectionResult =
- tile._lastSelectionResultFrame === lastFrame
- ? tile._lastSelectionResult
- : TileSelectionResult.NONE;
- var tileProvider = primitive.tileProvider;
- if (meetsSse || ancestorMeetsSse) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var oneRenderedLastFrame =
- TileSelectionResult.originalResult(lastFrameSelectionResult) ===
- TileSelectionResult.RENDERED;
- var twoCulledOrNotVisited =
- TileSelectionResult.originalResult(lastFrameSelectionResult) ===
- TileSelectionResult.CULLED ||
- lastFrameSelectionResult === TileSelectionResult.NONE;
- var threeCompletelyLoaded = tile.state === QuadtreeTileLoadState.DONE;
- var renderable =
- oneRenderedLastFrame || twoCulledOrNotVisited || threeCompletelyLoaded;
- if (!renderable) {
-
-
- if (defined(tileProvider.canRenderWithoutLosingDetail)) {
- renderable = tileProvider.canRenderWithoutLosingDetail(tile);
- }
- }
- if (renderable) {
-
- if (meetsSse) {
- queueTileLoad(
- primitive,
- primitive._tileLoadQueueMedium,
- tile,
- frameState
- );
- }
- addTileToRenderList(primitive, tile);
- traversalDetails.allAreRenderable = tile.renderable;
- traversalDetails.anyWereRenderedLastFrame =
- lastFrameSelectionResult === TileSelectionResult.RENDERED;
- traversalDetails.notYetRenderableCount = tile.renderable ? 0 : 1;
- tile._lastSelectionResultFrame = frameState.frameNumber;
- tile._lastSelectionResult = TileSelectionResult.RENDERED;
- if (!traversalDetails.anyWereRenderedLastFrame) {
-
- primitive._tileToUpdateHeights.push(tile);
- }
- return;
- }
-
-
-
-
-
-
- ancestorMeetsSse = true;
-
- if (meetsSse) {
- queueTileLoad(primitive, primitive._tileLoadQueueHigh, tile, frameState);
- }
- }
- if (tileProvider.canRefine(tile)) {
- var allAreUpsampled =
- southwestChild.upsampledFromParent &&
- southeastChild.upsampledFromParent &&
- northwestChild.upsampledFromParent &&
- northeastChild.upsampledFromParent;
- if (allAreUpsampled) {
-
- addTileToRenderList(primitive, tile);
-
- queueTileLoad(
- primitive,
- primitive._tileLoadQueueMedium,
- tile,
- frameState
- );
-
- primitive._tileReplacementQueue.markTileRendered(southwestChild);
- primitive._tileReplacementQueue.markTileRendered(southeastChild);
- primitive._tileReplacementQueue.markTileRendered(northwestChild);
- primitive._tileReplacementQueue.markTileRendered(northeastChild);
- traversalDetails.allAreRenderable = tile.renderable;
- traversalDetails.anyWereRenderedLastFrame =
- lastFrameSelectionResult === TileSelectionResult.RENDERED;
- traversalDetails.notYetRenderableCount = tile.renderable ? 0 : 1;
- tile._lastSelectionResultFrame = frameState.frameNumber;
- tile._lastSelectionResult = TileSelectionResult.RENDERED;
- if (!traversalDetails.anyWereRenderedLastFrame) {
-
- primitive._tileToUpdateHeights.push(tile);
- }
- return;
- }
-
- tile._lastSelectionResultFrame = frameState.frameNumber;
- tile._lastSelectionResult = TileSelectionResult.REFINED;
- var firstRenderedDescendantIndex = primitive._tilesToRender.length;
- var loadIndexLow = primitive._tileLoadQueueLow.length;
- var loadIndexMedium = primitive._tileLoadQueueMedium.length;
- var loadIndexHigh = primitive._tileLoadQueueHigh.length;
- var tilesToUpdateHeightsIndex = primitive._tileToUpdateHeights.length;
-
- visitVisibleChildrenNearToFar(
- primitive,
- southwestChild,
- southeastChild,
- northwestChild,
- northeastChild,
- frameState,
- ancestorMeetsSse,
- traversalDetails
- );
-
-
- if (firstRenderedDescendantIndex !== primitive._tilesToRender.length) {
-
-
- var allAreRenderable = traversalDetails.allAreRenderable;
- var anyWereRenderedLastFrame = traversalDetails.anyWereRenderedLastFrame;
- var notYetRenderableCount = traversalDetails.notYetRenderableCount;
- var queuedForLoad = false;
- if (!allAreRenderable && !anyWereRenderedLastFrame) {
-
-
-
- var renderList = primitive._tilesToRender;
- for (var i = firstRenderedDescendantIndex; i < renderList.length; ++i) {
- var workTile = renderList[i];
- while (
- workTile !== undefined &&
- workTile._lastSelectionResult !== TileSelectionResult.KICKED &&
- workTile !== tile
- ) {
- workTile._lastSelectionResult = TileSelectionResult.kick(
- workTile._lastSelectionResult
- );
- workTile = workTile.parent;
- }
- }
-
- primitive._tilesToRender.length = firstRenderedDescendantIndex;
- primitive._tileToUpdateHeights.length = tilesToUpdateHeightsIndex;
- addTileToRenderList(primitive, tile);
- tile._lastSelectionResult = TileSelectionResult.RENDERED;
-
-
-
- var wasRenderedLastFrame =
- lastFrameSelectionResult === TileSelectionResult.RENDERED;
- if (
- !wasRenderedLastFrame &&
- notYetRenderableCount > primitive.loadingDescendantLimit
- ) {
-
- primitive._tileLoadQueueLow.length = loadIndexLow;
- primitive._tileLoadQueueMedium.length = loadIndexMedium;
- primitive._tileLoadQueueHigh.length = loadIndexHigh;
- queueTileLoad(
- primitive,
- primitive._tileLoadQueueMedium,
- tile,
- frameState
- );
- traversalDetails.notYetRenderableCount = tile.renderable ? 0 : 1;
- queuedForLoad = true;
- }
- traversalDetails.allAreRenderable = tile.renderable;
- traversalDetails.anyWereRenderedLastFrame = wasRenderedLastFrame;
- if (!wasRenderedLastFrame) {
-
- primitive._tileToUpdateHeights.push(tile);
- }
- ++debug.tilesWaitingForChildren;
- }
- if (primitive.preloadAncestors && !queuedForLoad) {
- queueTileLoad(primitive, primitive._tileLoadQueueLow, tile, frameState);
- }
- }
- return;
- }
- tile._lastSelectionResultFrame = frameState.frameNumber;
- tile._lastSelectionResult = TileSelectionResult.RENDERED;
-
-
-
-
- addTileToRenderList(primitive, tile);
- queueTileLoad(primitive, primitive._tileLoadQueueHigh, tile, frameState);
- traversalDetails.allAreRenderable = tile.renderable;
- traversalDetails.anyWereRenderedLastFrame =
- lastFrameSelectionResult === TileSelectionResult.RENDERED;
- traversalDetails.notYetRenderableCount = tile.renderable ? 0 : 1;
- }
- function visitVisibleChildrenNearToFar(
- primitive,
- southwest,
- southeast,
- northwest,
- northeast,
- frameState,
- ancestorMeetsSse,
- traversalDetails
- ) {
- var cameraPosition = frameState.camera.positionCartographic;
- var tileProvider = primitive._tileProvider;
- var occluders = primitive._occluders;
- var quadDetails = traversalQuadsByLevel[southwest.level];
- var southwestDetails = quadDetails.southwest;
- var southeastDetails = quadDetails.southeast;
- var northwestDetails = quadDetails.northwest;
- var northeastDetails = quadDetails.northeast;
- if (cameraPosition.longitude < southwest.rectangle.east) {
- if (cameraPosition.latitude < southwest.rectangle.north) {
-
- visitIfVisible(
- primitive,
- southwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southwestDetails
- );
- visitIfVisible(
- primitive,
- southeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southeastDetails
- );
- visitIfVisible(
- primitive,
- northwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northwestDetails
- );
- visitIfVisible(
- primitive,
- northeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northeastDetails
- );
- } else {
-
- visitIfVisible(
- primitive,
- northwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northwestDetails
- );
- visitIfVisible(
- primitive,
- southwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southwestDetails
- );
- visitIfVisible(
- primitive,
- northeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northeastDetails
- );
- visitIfVisible(
- primitive,
- southeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southeastDetails
- );
- }
- } else if (cameraPosition.latitude < southwest.rectangle.north) {
-
- visitIfVisible(
- primitive,
- southeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southeastDetails
- );
- visitIfVisible(
- primitive,
- southwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southwestDetails
- );
- visitIfVisible(
- primitive,
- northeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northeastDetails
- );
- visitIfVisible(
- primitive,
- northwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northwestDetails
- );
- } else {
-
- visitIfVisible(
- primitive,
- northeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northeastDetails
- );
- visitIfVisible(
- primitive,
- northwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- northwestDetails
- );
- visitIfVisible(
- primitive,
- southeast,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southeastDetails
- );
- visitIfVisible(
- primitive,
- southwest,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- southwestDetails
- );
- }
- quadDetails.combine(traversalDetails);
- }
- function containsNeededPosition(primitive, tile) {
- var rectangle = tile.rectangle;
- return (
- (defined(primitive._cameraPositionCartographic) &&
- Rectangle.contains(rectangle, primitive._cameraPositionCartographic)) ||
- (defined(primitive._cameraReferenceFrameOriginCartographic) &&
- Rectangle.contains(
- rectangle,
- primitive._cameraReferenceFrameOriginCartographic
- ))
- );
- }
- function visitIfVisible(
- primitive,
- tile,
- tileProvider,
- frameState,
- occluders,
- ancestorMeetsSse,
- traversalDetails
- ) {
- if (
- tileProvider.computeTileVisibility(tile, frameState, occluders) !==
- Visibility.NONE
- ) {
- return visitTile(
- primitive,
- frameState,
- tile,
- ancestorMeetsSse,
- traversalDetails
- );
- }
- ++primitive._debug.tilesCulled;
- primitive._tileReplacementQueue.markTileRendered(tile);
- traversalDetails.allAreRenderable = true;
- traversalDetails.anyWereRenderedLastFrame = false;
- traversalDetails.notYetRenderableCount = 0;
- if (containsNeededPosition(primitive, tile)) {
-
-
-
- if (!defined(tile.data) || !defined(tile.data.vertexArray)) {
- queueTileLoad(
- primitive,
- primitive._tileLoadQueueMedium,
- tile,
- frameState
- );
- }
- var lastFrame = primitive._lastSelectionFrameNumber;
- var lastFrameSelectionResult =
- tile._lastSelectionResultFrame === lastFrame
- ? tile._lastSelectionResult
- : TileSelectionResult.NONE;
- if (
- lastFrameSelectionResult !== TileSelectionResult.CULLED_BUT_NEEDED &&
- lastFrameSelectionResult !== TileSelectionResult.RENDERED
- ) {
- primitive._tileToUpdateHeights.push(tile);
- }
- tile._lastSelectionResult = TileSelectionResult.CULLED_BUT_NEEDED;
- } else if (primitive.preloadSiblings || tile.level === 0) {
-
-
- queueTileLoad(primitive, primitive._tileLoadQueueLow, tile, frameState);
- tile._lastSelectionResult = TileSelectionResult.CULLED;
- } else {
- tile._lastSelectionResult = TileSelectionResult.CULLED;
- }
- tile._lastSelectionResultFrame = frameState.frameNumber;
- }
- function screenSpaceError(primitive, frameState, tile) {
- if (
- frameState.mode === SceneMode.SCENE2D ||
- frameState.camera.frustum instanceof OrthographicFrustum ||
- frameState.camera.frustum instanceof OrthographicOffCenterFrustum
- ) {
- return screenSpaceError2D(primitive, frameState, tile);
- }
- var maxGeometricError = primitive._tileProvider.getLevelMaximumGeometricError(
- tile.level
- );
- var distance = tile._distance;
- var height = frameState.context.drawingBufferHeight;
- var sseDenominator = frameState.camera.frustum.sseDenominator;
- var error = (maxGeometricError * height) / (distance * sseDenominator);
- if (frameState.fog.enabled) {
- error -=
- CesiumMath.fog(distance, frameState.fog.density) * frameState.fog.sse;
- }
- error /= frameState.pixelRatio;
- return error;
- }
- function screenSpaceError2D(primitive, frameState, tile) {
- var camera = frameState.camera;
- var frustum = camera.frustum;
- if (defined(frustum._offCenterFrustum)) {
- frustum = frustum._offCenterFrustum;
- }
- var context = frameState.context;
- var width = context.drawingBufferWidth;
- var height = context.drawingBufferHeight;
- var maxGeometricError = primitive._tileProvider.getLevelMaximumGeometricError(
- tile.level
- );
- var pixelSize =
- Math.max(frustum.top - frustum.bottom, frustum.right - frustum.left) /
- Math.max(width, height);
- var error = maxGeometricError / pixelSize;
- if (frameState.fog.enabled && frameState.mode !== SceneMode.SCENE2D) {
- error -=
- CesiumMath.fog(tile._distance, frameState.fog.density) *
- frameState.fog.sse;
- }
- error /= frameState.pixelRatio;
- return error;
- }
- function addTileToRenderList(primitive, tile) {
- primitive._tilesToRender.push(tile);
- }
- function processTileLoadQueue(primitive, frameState) {
- var tileLoadQueueHigh = primitive._tileLoadQueueHigh;
- var tileLoadQueueMedium = primitive._tileLoadQueueMedium;
- var tileLoadQueueLow = primitive._tileLoadQueueLow;
- if (
- tileLoadQueueHigh.length === 0 &&
- tileLoadQueueMedium.length === 0 &&
- tileLoadQueueLow.length === 0
- ) {
- return;
- }
-
-
- primitive._tileReplacementQueue.trimTiles(primitive.tileCacheSize);
- var endTime = getTimestamp() + primitive._loadQueueTimeSlice;
- var tileProvider = primitive._tileProvider;
- var didSomeLoading = processSinglePriorityLoadQueue(
- primitive,
- frameState,
- tileProvider,
- endTime,
- tileLoadQueueHigh,
- false
- );
- didSomeLoading = processSinglePriorityLoadQueue(
- primitive,
- frameState,
- tileProvider,
- endTime,
- tileLoadQueueMedium,
- didSomeLoading
- );
- processSinglePriorityLoadQueue(
- primitive,
- frameState,
- tileProvider,
- endTime,
- tileLoadQueueLow,
- didSomeLoading
- );
- }
- function sortByLoadPriority(a, b) {
- return a._loadPriority - b._loadPriority;
- }
- function processSinglePriorityLoadQueue(
- primitive,
- frameState,
- tileProvider,
- endTime,
- loadQueue,
- didSomeLoading
- ) {
- if (tileProvider.computeTileLoadPriority !== undefined) {
- loadQueue.sort(sortByLoadPriority);
- }
- for (
- var i = 0, len = loadQueue.length;
- i < len && (getTimestamp() < endTime || !didSomeLoading);
- ++i
- ) {
- var tile = loadQueue[i];
- primitive._tileReplacementQueue.markTileRendered(tile);
- tileProvider.loadTile(frameState, tile);
- didSomeLoading = true;
- }
- return didSomeLoading;
- }
- var scratchRay = new Ray();
- var scratchCartographic = new Cartographic();
- var scratchPosition = new Cartesian3();
- var scratchArray = [];
- function updateHeights(primitive, frameState) {
- if (!primitive.tileProvider.ready) {
- return;
- }
- var tryNextFrame = scratchArray;
- tryNextFrame.length = 0;
- var tilesToUpdateHeights = primitive._tileToUpdateHeights;
- var terrainProvider = primitive._tileProvider.terrainProvider;
- var startTime = getTimestamp();
- var timeSlice = primitive._updateHeightsTimeSlice;
- var endTime = startTime + timeSlice;
- var mode = frameState.mode;
- var projection = frameState.mapProjection;
- var ellipsoid = primitive.tileProvider.tilingScheme.ellipsoid;
- var i;
- while (tilesToUpdateHeights.length > 0) {
- var tile = tilesToUpdateHeights[0];
- if (!defined(tile.data) || !defined(tile.data.mesh)) {
-
-
- var selectionResult =
- tile._lastSelectionResultFrame === primitive._lastSelectionFrameNumber
- ? tile._lastSelectionResult
- : TileSelectionResult.NONE;
- if (
- selectionResult === TileSelectionResult.RENDERED ||
- selectionResult === TileSelectionResult.CULLED_BUT_NEEDED
- ) {
- tryNextFrame.push(tile);
- }
- tilesToUpdateHeights.shift();
- primitive._lastTileIndex = 0;
- continue;
- }
- var customData = tile.customData;
- var customDataLength = customData.length;
- var timeSliceMax = false;
- for (i = primitive._lastTileIndex; i < customDataLength; ++i) {
- var data = customData[i];
- if (tile.level > data.level) {
- if (!defined(data.positionOnEllipsoidSurface)) {
-
- data.positionOnEllipsoidSurface = Cartesian3.fromRadians(
- data.positionCartographic.longitude,
- data.positionCartographic.latitude,
- 0.0,
- ellipsoid
- );
- }
- if (mode === SceneMode.SCENE3D) {
- var surfaceNormal = ellipsoid.geodeticSurfaceNormal(
- data.positionOnEllipsoidSurface,
- scratchRay.direction
- );
-
-
-
- var rayOrigin = ellipsoid.getSurfaceNormalIntersectionWithZAxis(
- data.positionOnEllipsoidSurface,
- 11500.0,
- scratchRay.origin
- );
-
- if (!defined(rayOrigin)) {
-
-
- var minimumHeight;
- if (defined(tile.data.tileBoundingRegion)) {
- minimumHeight = tile.data.tileBoundingRegion.minimumHeight;
- }
- var magnitude = Math.min(
- defaultValue(minimumHeight, 0.0),
- -11500.0
- );
-
- var vectorToMinimumPoint = Cartesian3.multiplyByScalar(
- surfaceNormal,
- Math.abs(magnitude) + 1,
- scratchPosition
- );
- Cartesian3.subtract(
- data.positionOnEllipsoidSurface,
- vectorToMinimumPoint,
- scratchRay.origin
- );
- }
- } else {
- Cartographic.clone(data.positionCartographic, scratchCartographic);
-
- scratchCartographic.height = -11500.0;
- projection.project(scratchCartographic, scratchPosition);
- Cartesian3.fromElements(
- scratchPosition.z,
- scratchPosition.x,
- scratchPosition.y,
- scratchPosition
- );
- Cartesian3.clone(scratchPosition, scratchRay.origin);
- Cartesian3.clone(Cartesian3.UNIT_X, scratchRay.direction);
- }
- var position = tile.data.pick(
- scratchRay,
- mode,
- projection,
- false,
- scratchPosition
- );
- if (defined(position)) {
- data.callback(position);
- data.level = tile.level;
- }
- } else if (tile.level === data.level) {
- var children = tile.children;
- var childrenLength = children.length;
- var child;
- for (var j = 0; j < childrenLength; ++j) {
- child = children[j];
- if (Rectangle.contains(child.rectangle, data.positionCartographic)) {
- break;
- }
- }
- var tileDataAvailable = terrainProvider.getTileDataAvailable(
- child.x,
- child.y,
- child.level
- );
- var parentTile = tile.parent;
- if (
- (defined(tileDataAvailable) && !tileDataAvailable) ||
- (defined(parentTile) &&
- defined(parentTile.data) &&
- defined(parentTile.data.terrainData) &&
- !parentTile.data.terrainData.isChildAvailable(
- parentTile.x,
- parentTile.y,
- child.x,
- child.y
- ))
- ) {
- data.removeFunc();
- }
- }
- if (getTimestamp() >= endTime) {
- timeSliceMax = true;
- break;
- }
- }
- if (timeSliceMax) {
- primitive._lastTileIndex = i;
- break;
- } else {
- primitive._lastTileIndex = 0;
- tilesToUpdateHeights.shift();
- }
- }
- for (i = 0; i < tryNextFrame.length; i++) {
- tilesToUpdateHeights.push(tryNextFrame[i]);
- }
- }
- function createRenderCommandsForSelectedTiles(primitive, frameState) {
- var tileProvider = primitive._tileProvider;
- var tilesToRender = primitive._tilesToRender;
- for (var i = 0, len = tilesToRender.length; i < len; ++i) {
- var tile = tilesToRender[i];
- tileProvider.showTileThisFrame(tile, frameState);
- }
- }
- export default QuadtreePrimitive;
|