Skip to content

Commit 67964c0

Browse files
committed
add children union culling optimization
1 parent 0e6b512 commit 67964c0

File tree

1 file changed

+41
-21
lines changed

1 file changed

+41
-21
lines changed

Source/Scene/Cesium3DTilesetTraversal.js

+41-21
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,12 @@ define([
300300
};
301301

302302
BaseTraversal.prototype.getChildren = function(tile) {
303-
if (hasVisibleChildren(this, tile, this.baseScreenSpaceError)) {
303+
if (this.updateAndCheckChildren(tile)) {
304+
if (!childrenAreVisible(tile)) {
305+
++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion;
306+
return emptyArray;
307+
}
308+
304309
var children = tile.children;
305310
var childrenLength = children.length;
306311
var allReady = true;
@@ -326,13 +331,13 @@ define([
326331
return emptyArray;
327332
};
328333

329-
function hasVisibleChildren(traversal, tile, screenSpaceError) {
330-
var tileset = traversal.tileset;
334+
BaseTraversal.prototype.updateAndCheckChildren = function(tile) {
335+
var tileset = this.tileset;
331336

332337
if (tile.hasTilesetContent) {
333338
// load any tilesets of tilesets now because at this point we still have not achieved a base level of content
334339
if (!defined(tile._ancestorWithContent)) {
335-
loadTile(tile, traversal.frameState);
340+
loadTile(tile, this.frameState);
336341
}
337342
}
338343

@@ -341,11 +346,11 @@ define([
341346
}
342347

343348
// stop traversal when we've attained the desired level of error
344-
if (tile._screenSpaceError <= screenSpaceError && tile.hasRenderableContent) {
349+
if (tile._screenSpaceError <= this.baseScreenSpaceError && tile.hasRenderableContent) {
345350
return false;
346351
}
347352

348-
var childrenVisibility = updateChildren(tileset, tile, traversal.frameState);
353+
var childrenVisibility = updateChildren(tileset, tile, this.frameState);
349354
var showAdditive = tile.refine === Cesium3DTileRefine.ADD;
350355
var showReplacement = tile.refine === Cesium3DTileRefine.REPLACE && (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME) !== 0;
351356

@@ -386,11 +391,16 @@ define([
386391

387392
// Continue traversing until we have renderable content. We want the first descendants with content of the root to load
388393
InternalBaseTraversal.prototype.shouldVisit = function(tile) {
389-
return !tile.hasRenderableContent && isVisible(tile.visibilityPlaneMask);
394+
return !tile.hasRenderableContent && isVisible(tile.visibilityPlaneMask);
390395
};
391396

392397
InternalBaseTraversal.prototype.getChildren = function(tile) {
393-
if (hasVisibleChildren(this, tile, this.baseScreenSpaceError)) {
398+
if (this.updateAndCheckChildren(tile, this.baseScreenSpaceError)) {
399+
if (!childrenAreVisible(tile)) {
400+
++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion;
401+
return emptyArray;
402+
}
403+
394404
var children = tile.children;
395405
var childrenLength = children.length;
396406
for (var i = 0; i < childrenLength; ++i) {
@@ -403,6 +413,8 @@ define([
403413
return emptyArray;
404414
};
405415

416+
InternalBaseTraversal.prototype.updateAndCheckChildren = BaseTraversal.prototype.updateAndCheckChildren;
417+
406418
function SkipTraversal(options) {
407419
this.tileset = undefined;
408420
this.frameState = undefined;
@@ -497,6 +509,11 @@ define([
497509
}
498510

499511
if (showAdditive || showReplacement || tile.hasTilesetContent) {
512+
if (!childrenAreVisible(tile)) {
513+
++this.tileset._statistics.numberOfTilesCulledWithChildrenUnion;
514+
return emptyArray;
515+
}
516+
500517
var children = tile.children;
501518
var childrenLength = children.length;
502519
for (var i = 0; i < childrenLength; ++i) {
@@ -546,7 +563,7 @@ define([
546563
updateTransforms(children, tile.computedTransform);
547564
computeDistanceToCamera(children, frameState);
548565

549-
return computeChildrenVisibility(tile, frameState, true);
566+
return computeChildrenVisibility(tile, frameState);
550567
}
551568

552569
function visitTile(tileset, tile, frameState, outOfCore) {
@@ -595,7 +612,7 @@ define([
595612
}
596613
}
597614

598-
function computeChildrenVisibility(tile, frameState, checkViewerRequestVolume) {
615+
function computeChildrenVisibility(tile, frameState) {
599616
var flag = Cesium3DTileChildrenVisibility.NONE;
600617
var children = tile.children;
601618
var childrenLength = children.length;
@@ -609,17 +626,15 @@ define([
609626
flag |= Cesium3DTileChildrenVisibility.VISIBLE;
610627
}
611628

612-
if (checkViewerRequestVolume) {
613-
if (!child.insideViewerRequestVolume(frameState)) {
614-
if (isVisible(visibilityMask)) {
615-
flag |= Cesium3DTileChildrenVisibility.VISIBLE_NOT_IN_REQUEST_VOLUME;
616-
}
617-
visibilityMask = CullingVolume.MASK_OUTSIDE;
618-
} else {
619-
flag |= Cesium3DTileChildrenVisibility.IN_REQUEST_VOLUME;
620-
if (isVisible(visibilityMask)) {
621-
flag |= Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME;
622-
}
629+
if (!child.insideViewerRequestVolume(frameState)) {
630+
if (isVisible(visibilityMask)) {
631+
flag |= Cesium3DTileChildrenVisibility.VISIBLE_NOT_IN_REQUEST_VOLUME;
632+
}
633+
visibilityMask = CullingVolume.MASK_OUTSIDE;
634+
} else {
635+
flag |= Cesium3DTileChildrenVisibility.IN_REQUEST_VOLUME;
636+
if (isVisible(visibilityMask)) {
637+
flag |= Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME;
623638
}
624639
}
625640

@@ -688,6 +703,11 @@ define([
688703
return visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE;
689704
}
690705

706+
function childrenAreVisible(tile) {
707+
// optimization does not apply for additive refinement
708+
return tile.refine === Cesium3DTileRefine.ADD || tile.children.length === 0 || tile.childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE !== 0;
709+
}
710+
691711
function DFS(root, options) {
692712
var stack = options.stack;
693713

0 commit comments

Comments
 (0)