Skip to content

Commit d3aeef7

Browse files
committed
Simplify and fix
1 parent 55634e1 commit d3aeef7

8 files changed

+124
-133
lines changed

Source/Scene/Batched3DModel3DTileContent.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ define([
6868
this.batchTable = undefined;
6969
this.featurePropertiesDirty = false;
7070

71-
this._contentReadyToProcessPromise = when.defer();
72-
this._readyPromise = when.defer();
71+
this._contentReadyToProcessPromise = undefined;
72+
this._readyPromise = undefined;
7373
this._featuresLength = 0;
7474
this._features = undefined;
7575
}
@@ -215,6 +215,9 @@ define([
215215
return false;
216216
}
217217

218+
this._contentReadyToProcessPromise = when.defer();
219+
this._readyPromise = when.defer();
220+
218221
this.state = Cesium3DTileContentState.LOADING;
219222
promise.then(function(arrayBuffer) {
220223
if (that.isDestroyed()) {

Source/Scene/Cesium3DTile.js

+48-13
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ define([
289289
}
290290

291291
/**
292-
* The time in seconds after the tile's content is downloaded when the content expires and new content is requested.
292+
* The time in seconds after the tile's content is ready when the content expires and new content is requested.
293293
*
294294
* @type {Number}
295295
*/
@@ -482,12 +482,49 @@ define([
482482
}
483483
});
484484

485+
var scratchJulianDate = new JulianDate();
486+
487+
/**
488+
* Check if the tile's content has expired.
489+
*
490+
* @private
491+
*/
492+
Cesium3DTile.prototype.isContentExpired = function() {
493+
if (this._content.state === Cesium3DTileContentState.EXPIRED) {
494+
return true;
495+
}
496+
if (defined(this.expireDate) && this.contentReady && (this.hasContent || this.hasTilesetContent)) {
497+
var now = JulianDate.now(scratchJulianDate);
498+
if (JulianDate.lessThan(this.expireDate, now)) {
499+
this._content.state = Cesium3DTileContentState.EXPIRED;
500+
return true;
501+
}
502+
}
503+
return false;
504+
};
505+
506+
function updateExpireDate(tile) {
507+
if (defined(tile.expireDuration)) {
508+
var expireDurationDate = JulianDate.now(scratchJulianDate);
509+
JulianDate.addSeconds(expireDurationDate, tile.expireDuration, expireDurationDate);
510+
511+
if (defined(tile.expireDate)) {
512+
if (JulianDate.lessThan(tile.expireDate, expireDurationDate)) {
513+
JulianDate.clone(expireDurationDate, tile.expireDate);
514+
}
515+
} else {
516+
tile.expireDate = JulianDate.clone(expireDurationDate);
517+
}
518+
}
519+
}
520+
485521
function addContentReadyPromise(tile) {
486522
// Content enters the READY state
487-
tile._content.readyPromise.then(function(content) {
523+
tile._content.readyPromise.then(function() {
488524
if (defined(tile.parent)) {
489525
--tile.parent.numberOfChildrenWithoutContent;
490526
}
527+
updateExpireDate(tile);
491528
}).otherwise(function(error) {
492529
// In this case, that.parent.numberOfChildrenWithoutContent will never reach zero
493530
// and therefore that.parent will never refine. If this becomes an issue, failed
@@ -531,11 +568,19 @@ define([
531568
*
532569
* @private
533570
*/
534-
Cesium3DTile.prototype.unloadContent = function() {
571+
Cesium3DTile.prototype.unloadContent = function(makeEmpty) {
535572
if (defined(this.parent)) {
536573
++this.parent.numberOfChildrenWithoutContent;
537574
}
538575

576+
if (makeEmpty) {
577+
this.hasContent = false;
578+
this.hasTilesetContent = false;
579+
this._createContent = function() {
580+
return new Empty3DTileContent();
581+
};
582+
}
583+
539584
this._content = this._content && this._content.destroy();
540585
this._content = this._createContent();
541586
if (!this.hasContent && !this.hasTilesetContent) {
@@ -556,16 +601,6 @@ define([
556601
this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy();
557602
};
558603

559-
Cesium3DTile.prototype.unloadContentAndMakeEmpty = function() {
560-
this.hasContent = false;
561-
this.hasTilesetContent = false;
562-
this._createContent = function() {
563-
return new Empty3DTileContent();
564-
};
565-
this.unloadContent();
566-
};
567-
568-
569604
var scratchProjectedBoundingSphere = new BoundingSphere();
570605

571606
function getBoundingVolume(tile, frameState) {

Source/Scene/Cesium3DTileset.js

+46-102
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ define([
434434
this.allTilesLoaded = new Event();
435435

436436
/**
437-
* The event fired to indicate that a tile's content was unloaded from the cache.
437+
* The event fired to indicate that a tile's content was unloaded.
438438
* <p>
439439
* The unloaded {@link Cesium3DTile} is passed to the event listener.
440440
* </p>
@@ -924,11 +924,6 @@ define([
924924
// If there is a parentTile, add the root of the currently loading tileset
925925
// to parentTile's children, and increment its numberOfChildrenWithoutContent
926926
if (defined(parentTile)) {
927-
if (parentTile.children.length > 0) {
928-
// Unload the old subtree if it exists
929-
unloadExpiredSubtree(parentTile);
930-
}
931-
932927
parentTile.children.push(rootTile);
933928
++parentTile.numberOfChildrenWithoutContent;
934929

@@ -1015,13 +1010,6 @@ define([
10151010
}
10161011
}
10171012

1018-
function recheckRefinement(tile) {
1019-
var ancestor = getAncestorWithContent(tile);
1020-
if (defined(ancestor) && (ancestor.refine === Cesium3DTileRefine.REPLACE)) {
1021-
prepareRefiningTiles([ancestor]);
1022-
}
1023-
}
1024-
10251013
var scratchPositionNormal = new Cartesian3();
10261014
var scratchCartographic = new Cartographic();
10271015
var scratchMatrix = new Matrix4();
@@ -1161,71 +1149,23 @@ define([
11611149

11621150
///////////////////////////////////////////////////////////////////////////
11631151

1164-
var scratchJulianDate = new JulianDate();
1165-
1166-
function updateExpireDate(tile) {
1167-
if (defined(tile.expireDuration)) {
1168-
var expireDurationDate = JulianDate.now(scratchJulianDate);
1169-
JulianDate.addSeconds(expireDurationDate, tile.expireDuration, expireDurationDate);
1170-
1171-
if (defined(tile.expireDate)) {
1172-
if (JulianDate.lessThan(expireDurationDate, tile.expireDate)) {
1173-
JulianDate.clone(expireDurationDate, tile.expireDate);
1174-
}
1175-
} else {
1176-
tile.expireDate = JulianDate.clone(expireDurationDate);
1177-
}
1178-
}
1179-
}
1180-
1181-
function unloadExpiredSubtree(tile) {
1152+
function unloadSubtree(tileset, tile) {
1153+
var stats = tileset._statistics;
11821154
var stack = [];
11831155
stack.push(tile);
11841156
while (stack.length > 0) {
11851157
tile = stack.pop();
1158+
unloadTile(tileset, tile, false);
11861159
var children = tile.children;
11871160
var length = children.length;
11881161
for (var i = 0; i < length; ++i) {
11891162
var child = children[i];
1190-
child.destroy();
1163+
--stats.numberTotal;
11911164
stack.push(child);
11921165
}
11931166
}
1194-
tile.children = [];
1195-
tile.unloadContent();
1196-
}
1197-
1198-
function unloadExpiredLeafTile(tile) {
1199-
tile.destroy();
1200-
var parent = tile.parent;
1201-
if (defined(parent)) {
1202-
var index = parent.children.indexOf(tile);
1203-
parent.children.splice(index, 1);
1204-
recheckRefinement(parent);
1205-
}
1206-
}
1207-
1208-
function unloadExpiredTile(tile) {
1209-
if (tile.children.length === 0) {
1210-
unloadExpiredLeafTile(tile);
1211-
return;
1212-
}
12131167

1214-
if (tile.hasContent) {
1215-
// When the tile is expired and the request fails, there is no longer any content to show.
1216-
// Unload the tile's old content and replace it with Empty3DTileContent.
1217-
tile.unloadContentAndMakeEmpty();
1218-
// Now that the tile is empty recheck its parent's refinement
1219-
recheckRefinement(tile.parent);
1220-
} else if (tile.hasTilesetContent) {
1221-
// When the tile is the root of an external tileset, unload the entire subtree
1222-
unloadExpiredSubtree(tile);
1223-
// Also destroy this tile
1224-
unloadExpiredLeafTile(tile);
1225-
}
1226-
}
1227-
function isVisible(visibilityPlaneMask) {
1228-
return visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE;
1168+
tile.children = [];
12291169
}
12301170

12311171
function requestContent(tileset, tile, outOfCore) {
@@ -1236,7 +1176,7 @@ define([
12361176
return;
12371177
}
12381178

1239-
var expired = (tile.content.state === Cesium3DTileContentState.EXPIRED);
1179+
var expired = tile.isContentExpired();
12401180

12411181
tile.requestContent();
12421182

@@ -1247,25 +1187,28 @@ define([
12471187
if (tile.content.state === Cesium3DTileContentState.LOADING) {
12481188
++stats.numberOfPendingRequests;
12491189

1190+
if (expired && tile.hasTilesetContent) {
1191+
unloadSubtree(tileset, tile);
1192+
}
1193+
12501194
var removeFunction = removeFromProcessingQueue(tileset, tile);
1251-
when(tile.content.contentReadyToProcessPromise).then(function() {
1252-
// Content is loaded and ready to process
1253-
addToProcessingQueue(tileset, tile);
1254-
updateExpireDate(tile);
1255-
}).otherwise(removeFunction);
1256-
1257-
when(tile.content.readyPromise).then(removeFunction).otherwise(function() {
1258-
// The request failed
1195+
tile.content.contentReadyToProcessPromise.then(addToProcessingQueue(tileset, tile));
1196+
tile.content.readyPromise.then(removeFunction).otherwise(function() {
12591197
removeFunction();
12601198
if (expired) {
1261-
unloadExpiredTile(tile);
1199+
// Failed to request new content for the expired tile, so unload it and make it empty
1200+
unloadTile(tileset, tile, true);
12621201
}
12631202
});
12641203
} else {
12651204
++stats.numberOfAttemptedRequests;
12661205
}
12671206
}
12681207

1208+
function isVisible(visibilityPlaneMask) {
1209+
return visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE;
1210+
}
1211+
12691212
function selectTile(tileset, tile, fullyVisible, frameState) {
12701213
// There may also be a tight box around just the tile's contents, e.g., for a city, we may be
12711214
// zoomed into a neighborhood and can cull the skyscrapers in the root node.
@@ -1386,6 +1329,10 @@ define([
13861329
t.replaced = false;
13871330
++stats.visited;
13881331

1332+
if (t.isContentExpired()) {
1333+
requestContent(tileset, t, outOfCore);
1334+
}
1335+
13891336
var visibilityPlaneMask = t.visibilityPlaneMask;
13901337
var fullyVisible = (visibilityPlaneMask === CullingVolume.MASK_INSIDE);
13911338

@@ -1395,18 +1342,6 @@ define([
13951342
var sse = getScreenSpaceError(tileset, t.geometricError, t, frameState);
13961343
// PERFORMANCE_IDEA: refine also based on (1) occlusion/VMSSE and/or (2) center of viewport
13971344

1398-
// If the tile is expired, request new content
1399-
if (defined(t.expireDate)) {
1400-
var now = JulianDate.now(scratchJulianDate);
1401-
if (JulianDate.lessThan(now, t.expireDate)) {
1402-
// Request new content
1403-
if (t.contentReady && (t.hasContent || t.hasTilesetContent)) {
1404-
t.content.state = Cesium3DTileContentState.EXPIRED;
1405-
requestContent(tileset, t, outOfCore);
1406-
}
1407-
}
1408-
}
1409-
14101345
var children = t.children;
14111346
var childrenLength = children.length;
14121347
var child;
@@ -1698,10 +1633,12 @@ define([
16981633
///////////////////////////////////////////////////////////////////////////
16991634

17001635
function addToProcessingQueue(tileset, tile) {
1701-
tileset._processingQueue.push(tile);
1636+
return function() {
1637+
tileset._processingQueue.push(tile);
17021638

1703-
--tileset._statistics.numberOfPendingRequests;
1704-
++tileset._statistics.numberProcessing;
1639+
--tileset._statistics.numberOfPendingRequests;
1640+
++tileset._statistics.numberProcessing;
1641+
};
17051642
}
17061643

17071644
function removeFromProcessingQueue(tileset, tile) {
@@ -1878,14 +1815,29 @@ define([
18781815
}
18791816
}
18801817

1818+
function unloadTile(tileset, tile, makeEmpty) {
1819+
if (tile.hasContent) {
1820+
var stats = tileset._statistics;
1821+
var replacementList = tileset._replacementList;
1822+
var tileUnload = tileset.tileUnload;
1823+
1824+
tileUnload.raiseEvent(tile);
1825+
replacementList.remove(tile.replacementNode);
1826+
decrementPointAndFeatureLoadCounts(tileset, tile.content);
1827+
--stats.numberContentReady;
1828+
}
1829+
1830+
if (tile.hasContent || (tile.hasTilesetContent && makeEmpty)) {
1831+
tile.unloadContent(makeEmpty);
1832+
}
1833+
}
1834+
18811835
function unloadTiles(tileset, frameState) {
18821836
var trimTiles = tileset._trimTiles;
18831837
tileset._trimTiles = false;
18841838

1885-
var stats = tileset._statistics;
18861839
var maximumNumberOfLoadedTiles = tileset._maximumNumberOfLoadedTiles + 1; // + 1 to account for sentinel
18871840
var replacementList = tileset._replacementList;
1888-
var tileUnload = tileset.tileUnload;
18891841

18901842
// Traverse the list only to the sentinel since tiles/nodes to the
18911843
// right of the sentinel were used this frame.
@@ -1895,16 +1847,8 @@ define([
18951847
var node = replacementList.head;
18961848
while ((node !== sentinel) && ((replacementList.length > maximumNumberOfLoadedTiles) || trimTiles)) {
18971849
var tile = node.item;
1898-
1899-
decrementPointAndFeatureLoadCounts(tileset, tile.content);
1900-
tileUnload.raiseEvent(tile);
1901-
tile.unloadContent();
1902-
1903-
var currentNode = node;
19041850
node = node.next;
1905-
replacementList.remove(currentNode);
1906-
1907-
--stats.numberContentReady;
1851+
unloadTile(tileset, tile, false);
19081852
}
19091853
}
19101854

Source/Scene/Composite3DTileContent.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ define([
5050
this.state = Cesium3DTileContentState.UNLOADED;
5151
this.batchTable = undefined;
5252

53-
this._contentReadyToProcessPromise = when.defer();
54-
this._readyPromise = when.defer();
53+
this._contentReadyToProcessPromise = undefined;
54+
this._readyPromise = undefined;
5555
}
5656

5757
defineProperties(Composite3DTileContent.prototype, {
@@ -192,6 +192,9 @@ define([
192192
return false;
193193
}
194194

195+
this._contentReadyToProcessPromise = when.defer();
196+
this._readyPromise = when.defer();
197+
195198
this.state = Cesium3DTileContentState.LOADING;
196199
promise.then(function(arrayBuffer) {
197200
if (that.isDestroyed()) {

0 commit comments

Comments
 (0)