Skip to content

Commit 476418d

Browse files
authored
Merge pull request #1188 from CesiumGS/tile-sse
Pass Tile SSEs to ViewUpdateResult
2 parents 155fa6b + 0168380 commit 476418d

File tree

5 files changed

+66
-26
lines changed

5 files changed

+66
-26
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
##### Additions :tada:
1010

1111
- Added a constructor overload for `Cesium3DTilesSelection::ITwinCesiumCuratedContentLoaderFactory` to override the iTwin Cesium Curated Content base URL. This makes it possible to connect to alternate servers (e.g., staging, QA, mock servers).
12+
- Added `ViewUpdateResult::tileScreenSpaceErrorThisFrame`, which stores the screen space errors computed for tiles in `tilesToRenderThisFrame`.
1213

1314
##### Fixes :wrench:
1415

Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,12 @@ class CESIUM3DTILESSELECTION_API Tileset final {
522522
const TilesetFrameState& frameState,
523523
Tile& tile,
524524
double tilePriority,
525+
double tileSse,
525526
ViewUpdateResult& result);
526527
TraversalDetails _renderInnerTile(
527528
const TilesetFrameState& frameState,
528529
Tile& tile,
530+
double tileSse,
529531
ViewUpdateResult& result);
530532
bool _kickDescendantsAndRenderTile(
531533
const TilesetFrameState& frameState,
@@ -535,7 +537,8 @@ class CESIUM3DTILESSELECTION_API Tileset final {
535537
size_t firstRenderedDescendantIndex,
536538
const TilesetViewGroup::LoadQueueCheckpoint& loadQueueBeforeChildren,
537539
bool queuedForLoad,
538-
double tilePriority);
540+
double tilePriority,
541+
double tileSse);
539542
TileOcclusionState _checkOcclusion(const Tile& tile);
540543

541544
TraversalDetails _visitTile(
@@ -545,6 +548,7 @@ class CESIUM3DTILESSELECTION_API Tileset final {
545548
bool ancestorMeetsSse,
546549
Tile& tile,
547550
double tilePriority,
551+
double tileSse,
548552
ViewUpdateResult& result);
549553

550554
struct CullResult {
@@ -564,11 +568,11 @@ class CESIUM3DTILESSELECTION_API Tileset final {
564568
const TilesetFrameState& frameState,
565569
const std::vector<double>& distances,
566570
CullResult& cullResult);
567-
bool _meetsSse(
571+
double _computeSse(
568572
const std::vector<ViewState>& frustums,
569573
const Tile& tile,
570-
const std::vector<double>& distances,
571-
bool culled) const noexcept;
574+
const std::vector<double>& distances) const noexcept;
575+
bool _meetsSseThreshold(double sse, bool culled) const noexcept;
572576

573577
TraversalDetails _visitTileIfNeeded(
574578
const TilesetFrameState& frameState,
@@ -593,6 +597,7 @@ class CESIUM3DTILESSELECTION_API Tileset final {
593597
* @param result The current view update result.
594598
* @param tilePriority The load priority of this tile.
595599
* priority.
600+
* @param tileSse The screen space error of this tile.
596601
* @param queuedForLoad True if this tile has already been queued for loading.
597602
* @return true The additive-refined tile was queued for load and added to the
598603
* render list.
@@ -603,6 +608,7 @@ class CESIUM3DTILESSELECTION_API Tileset final {
603608
Tile& tile,
604609
ViewUpdateResult& result,
605610
double tilePriority,
611+
double tileSse,
606612
bool queuedForLoad);
607613

608614
void _unloadCachedTiles(double timeBudget) noexcept;

Cesium3DTilesSelection/include/Cesium3DTilesSelection/ViewUpdateResult.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,26 @@ class CESIUM3DTILESSELECTION_API ViewUpdateResult final {
2424
* @brief The tiles that were selected by the tileset traversal this frame.
2525
* These tiles should be rendered by the client.
2626
*
27-
* Tiles in this list may be fading in if
28-
* {@link TilesetOptions::enableLodTransitionPeriod} is true.
27+
* Tiles in this list may be fading in if \ref
28+
* TilesetOptions::enableLodTransitionPeriod is true.
2929
*/
3030
std::vector<Tile::ConstPointer> tilesToRenderThisFrame;
3131

32+
/**
33+
* @brief The computed screen space error of the tiles selected by the
34+
* tileset traversal this frame. The values correspond to the tiles linked in
35+
* \ref tilesToRenderThisFrame, and may be used by the client to influence
36+
* rendering behavior.
37+
*/
38+
std::vector<double> tileScreenSpaceErrorThisFrame;
39+
3240
/**
3341
* @brief Tiles on this list are no longer selected for rendering.
3442
*
35-
* If {@link TilesetOptions::enableLodTransitionPeriod} is true they may be
36-
* fading out. If a tile's {TileRenderContent::lodTransitionPercentage} is 0
37-
* or lod transitions are disabled, the tile should be hidden right away.
43+
* If \ref TilesetOptions::enableLodTransitionPeriod is true they may be
44+
* fading out. If a tile's \ref
45+
* TileRenderContent::getLodTransitionFadePercentage is 0 or LOD transitions
46+
* are disabled, the tile should be hidden right away.
3847
*/
3948
std::unordered_set<Tile::ConstPointer> tilesFadingOut;
4049

Cesium3DTilesSelection/src/Tileset.cpp

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -856,15 +856,14 @@ void computeDistances(
856856

857857
} // namespace
858858

859-
bool Tileset::_meetsSse(
859+
double Tileset::_computeSse(
860860
const std::vector<ViewState>& frustums,
861861
const Tile& tile,
862-
const std::vector<double>& distances,
863-
bool culled) const noexcept {
864-
862+
const std::vector<double>& distances) const noexcept {
865863
double largestSse = 0.0;
866864

867-
for (size_t i = 0; i < frustums.size() && i < distances.size(); ++i) {
865+
CESIUM_ASSERT(frustums.size() == distances.size());
866+
for (size_t i = 0; i < frustums.size(); ++i) {
868867
const ViewState& frustum = frustums[i];
869868
const double distance = distances[i];
870869

@@ -875,12 +874,22 @@ bool Tileset::_meetsSse(
875874
largestSse = sse;
876875
}
877876
}
877+
return largestSse;
878+
}
878879

880+
bool Tileset::_meetsSseThreshold(double sse, bool culled) const noexcept {
879881
return culled ? !this->_options.enforceCulledScreenSpaceError ||
880-
largestSse < this->_options.culledScreenSpaceError
881-
: largestSse < this->_options.maximumScreenSpaceError;
882+
sse < this->_options.culledScreenSpaceError
883+
: sse < this->_options.maximumScreenSpaceError;
882884
}
883885

886+
namespace {
887+
void addTileToRender(ViewUpdateResult& result, Tile& tile, double sse) {
888+
result.tilesToRenderThisFrame.emplace_back(&tile);
889+
result.tileScreenSpaceErrorThisFrame.emplace_back(sse);
890+
}
891+
} // namespace
892+
884893
// Visits a tile for possible rendering. When we call this function with a tile:
885894
// * It is not yet known whether the tile is visible.
886895
// * Its parent tile does _not_ meet the SSE (unless ancestorMeetsSse=true,
@@ -987,8 +996,8 @@ Tileset::TraversalDetails Tileset::_visitTileIfNeeded(
987996
++result.culledTilesVisited;
988997
}
989998

990-
bool meetsSse =
991-
this->_meetsSse(frameState.frustums, tile, distances, cullResult.culled);
999+
double tileSse = this->_computeSse(frameState.frustums, tile, distances);
1000+
bool meetsSse = this->_meetsSseThreshold(tileSse, cullResult.culled);
9921001

9931002
TraversalDetails details = this->_visitTile(
9941003
frameState,
@@ -997,6 +1006,7 @@ Tileset::TraversalDetails Tileset::_visitTileIfNeeded(
9971006
ancestorMeetsSse,
9981007
tile,
9991008
tilePriority,
1009+
tileSse,
10001010
result);
10011011

10021012
traversalState.finishNode(&tile);
@@ -1012,10 +1022,11 @@ Tileset::TraversalDetails Tileset::_renderLeaf(
10121022
const TilesetFrameState& frameState,
10131023
Tile& tile,
10141024
double tilePriority,
1025+
double tileSse,
10151026
ViewUpdateResult& result) {
10161027
frameState.viewGroup.getTraversalState().currentState() =
10171028
TileSelectionState(TileSelectionState::Result::Rendered);
1018-
result.tilesToRenderThisFrame.emplace_back(&tile);
1029+
addTileToRender(result, tile, tileSse);
10191030

10201031
addTileToLoadQueue(
10211032
frameState,
@@ -1059,14 +1070,15 @@ bool mustContinueRefiningToDeeperTiles(
10591070
Tileset::TraversalDetails Tileset::_renderInnerTile(
10601071
const TilesetFrameState& frameState,
10611072
Tile& tile,
1073+
double tileSse,
10621074
ViewUpdateResult& result) {
10631075
addCurrentTileDescendantsToTilesFadingOutIfPreviouslyRendered(
10641076
frameState.viewGroup,
10651077
tile,
10661078
result);
10671079
frameState.viewGroup.getTraversalState().currentState() =
10681080
TileSelectionState(TileSelectionState::Result::Rendered);
1069-
result.tilesToRenderThisFrame.emplace_back(&tile);
1081+
addTileToRender(result, tile, tileSse);
10701082

10711083
return Tileset::createTraversalDetailsForSingleTile(frameState, tile);
10721084
}
@@ -1076,11 +1088,12 @@ bool Tileset::_loadAndRenderAdditiveRefinedTile(
10761088
Tile& tile,
10771089
ViewUpdateResult& result,
10781090
double tilePriority,
1091+
double tileSse,
10791092
bool queuedForLoad) {
10801093
// If this tile uses additive refinement, we need to render this tile in
10811094
// addition to its children.
10821095
if (tile.getRefine() == TileRefine::Add) {
1083-
result.tilesToRenderThisFrame.emplace_back(&tile);
1096+
addTileToRender(result, tile, tileSse);
10841097
if (!queuedForLoad)
10851098
addTileToLoadQueue(
10861099
frameState,
@@ -1101,7 +1114,8 @@ bool Tileset::_kickDescendantsAndRenderTile(
11011114
size_t firstRenderedDescendantIndex,
11021115
const TilesetViewGroup::LoadQueueCheckpoint& loadQueueBeforeChildren,
11031116
bool queuedForLoad,
1104-
double tilePriority) {
1117+
double tilePriority,
1118+
double tileSse) {
11051119
// Mark all visited descendants of this tile as kicked.
11061120
TilesetViewGroup::TraversalState& traversalState =
11071121
frameState.viewGroup.getTraversalState();
@@ -1130,14 +1144,20 @@ bool Tileset::_kickDescendantsAndRenderTile(
11301144

11311145
// Remove all descendants from the render list and add this tile.
11321146
std::vector<Tile::ConstPointer>& renderList = result.tilesToRenderThisFrame;
1147+
std::vector<double>& sseList = result.tileScreenSpaceErrorThisFrame;
11331148
renderList.erase(
11341149
renderList.begin() +
11351150
static_cast<std::vector<Tile*>::iterator::difference_type>(
11361151
firstRenderedDescendantIndex),
11371152
renderList.end());
1153+
sseList.erase(
1154+
sseList.begin() +
1155+
static_cast<std::vector<double>::iterator::difference_type>(
1156+
firstRenderedDescendantIndex),
1157+
sseList.end());
11381158

11391159
if (tile.getRefine() != Cesium3DTilesSelection::TileRefine::Add) {
1140-
renderList.emplace_back(&tile);
1160+
addTileToRender(result, tile, tileSse);
11411161
}
11421162

11431163
traversalState.currentState() =
@@ -1291,6 +1311,7 @@ Tileset::TraversalDetails Tileset::_visitTile(
12911311
// children!
12921312
Tile& tile,
12931313
double tilePriority,
1314+
double tileSse,
12941315
ViewUpdateResult& result) {
12951316
TilesetViewGroup::TraversalState& traversalState =
12961317
frameState.viewGroup.getTraversalState();
@@ -1300,7 +1321,7 @@ Tileset::TraversalDetails Tileset::_visitTile(
13001321

13011322
// If this is a leaf tile, just render it (it's already been deemed visible).
13021323
if (isLeaf(tile)) {
1303-
return this->_renderLeaf(frameState, tile, tilePriority, result);
1324+
return this->_renderLeaf(frameState, tile, tilePriority, tileSse, result);
13041325
}
13051326

13061327
const bool unconditionallyRefine = tile.getUnconditionallyRefine();
@@ -1404,7 +1425,7 @@ Tileset::TraversalDetails Tileset::_visitTile(
14041425
tilePriority);
14051426
}
14061427

1407-
return this->_renderInnerTile(frameState, tile, result);
1428+
return this->_renderInnerTile(frameState, tile, tileSse, result);
14081429
}
14091430
}
14101431

@@ -1415,6 +1436,7 @@ Tileset::TraversalDetails Tileset::_visitTile(
14151436
tile,
14161437
result,
14171438
tilePriority,
1439+
tileSse,
14181440
queuedForLoad) ||
14191441
queuedForLoad;
14201442

@@ -1468,7 +1490,8 @@ Tileset::TraversalDetails Tileset::_visitTile(
14681490
firstRenderedDescendantIndex,
14691491
loadQueueBeforeChildren,
14701492
queuedForLoad,
1471-
tilePriority);
1493+
tilePriority,
1494+
tileSse);
14721495
} else {
14731496
if (tile.getRefine() != TileRefine::Add) {
14741497
addCurrentTileToTilesFadingOutIfPreviouslyRendered(

Cesium3DTilesSelection/src/TilesetViewGroup.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void TilesetViewGroup::startNewFrame(
128128
this->_updateResult.maxDepthVisited = 0;
129129

130130
this->_updateResult.tilesToRenderThisFrame.clear();
131+
this->_updateResult.tileScreenSpaceErrorThisFrame.clear();
131132

132133
if (!tileset.getOptions().enableLodTransitionPeriod) {
133134
this->_updateResult.tilesFadingOut.clear();

0 commit comments

Comments
 (0)