Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
00b8651
Pass SSE through Tileset selection
j9liu May 13, 2025
5cd5df9
Make sure to clear screen space error
j9liu May 14, 2025
7d07561
Merge branch 'tileset-voxel-extension' into tile-sse
j9liu May 30, 2025
c8625b8
Merge branch 'tileset-voxel-extension' into tile-sse
j9liu May 30, 2025
ad5fac5
Merge branch 'tileset-voxel-extension' into tile-sse
j9liu Jun 2, 2025
8c904de
Merge remote-tracking branch 'origin/tileset-voxel-extension' into ti…
j9liu Jun 12, 2025
440d2f2
Merge remote-tracking branch 'origin/tileset-voxel-extension' into ac…
j9liu Jun 12, 2025
0050ee4
Merge branch 'tileset-voxel-extension' into tile-sse
j9liu Jun 18, 2025
2cd53b0
Merge branch 'accessible-accessor-view' into tile-sse
j9liu Jul 3, 2025
ab22b01
Merge branch 'main' into tile-sse
j9liu Jul 3, 2025
52b04c6
Merge branch 'accessible-accessor-view' into tile-sse
j9liu Jul 3, 2025
bbc2cdb
Merge branch 'accessible-accessor-view' into tile-sse
j9liu Aug 4, 2025
d1ab845
Merge branch 'main' into tile-sse
j9liu Sep 3, 2025
65a4952
Merge remote-tracking branch 'origin/main' into tile-sse
kring Oct 16, 2025
fe2ab2b
Merge branch 'main' into tile-sse
j9liu Dec 10, 2025
d94cc1b
Merge branch 'main' into tile-sse
j9liu Jan 16, 2026
ba7e242
Merge branch 'main' into tile-sse
j9liu Feb 18, 2026
857aab8
Merge branch 'main' into tile-sse
j9liu Mar 3, 2026
b051022
Merge branch 'tile-sse' of https://github.com/CesiumGS/cesium-native …
j9liu Mar 4, 2026
71a709e
Merge branch 'resolve-invalid-loader' into tile-sse
j9liu Mar 4, 2026
2b52c3b
Merge branch 'main' into tile-sse
j9liu Mar 12, 2026
9f5974a
Merge branch 'main' into tile-sse
j9liu Mar 18, 2026
1d5039b
Fix doc bug
j9liu Mar 18, 2026
f8afac4
Update changelog
j9liu Mar 18, 2026
47f8aa9
Add proper doc fix
j9liu Mar 19, 2026
0d04e75
Merge branch 'main' into tile-sse
j9liu Mar 23, 2026
0168380
Cleanup for PR feedback
j9liu Mar 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
##### Additions :tada:

- 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).
- Added `ViewUpdateResult::tileScreenSpaceErrorThisFrame`, which stores the screen space errors computed for tiles in `tilesToRenderThisFrame`.

##### Fixes :wrench:

Expand Down
14 changes: 10 additions & 4 deletions Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,10 +522,12 @@ class CESIUM3DTILESSELECTION_API Tileset final {
const TilesetFrameState& frameState,
Tile& tile,
double tilePriority,
double tileSse,
ViewUpdateResult& result);
TraversalDetails _renderInnerTile(
const TilesetFrameState& frameState,
Tile& tile,
double tileSse,
ViewUpdateResult& result);
bool _kickDescendantsAndRenderTile(
const TilesetFrameState& frameState,
Expand All @@ -535,7 +537,8 @@ class CESIUM3DTILESSELECTION_API Tileset final {
size_t firstRenderedDescendantIndex,
const TilesetViewGroup::LoadQueueCheckpoint& loadQueueBeforeChildren,
bool queuedForLoad,
double tilePriority);
double tilePriority,
double tileSse);
TileOcclusionState _checkOcclusion(const Tile& tile);

TraversalDetails _visitTile(
Expand All @@ -545,6 +548,7 @@ class CESIUM3DTILESSELECTION_API Tileset final {
bool ancestorMeetsSse,
Tile& tile,
double tilePriority,
double tileSse,
ViewUpdateResult& result);

struct CullResult {
Expand All @@ -564,11 +568,11 @@ class CESIUM3DTILESSELECTION_API Tileset final {
const TilesetFrameState& frameState,
const std::vector<double>& distances,
CullResult& cullResult);
bool _meetsSse(
double _computeSse(
const std::vector<ViewState>& frustums,
const Tile& tile,
const std::vector<double>& distances,
bool culled) const noexcept;
const std::vector<double>& distances) const noexcept;
bool _meetsSseThreshold(double sse, bool culled) const noexcept;

TraversalDetails _visitTileIfNeeded(
const TilesetFrameState& frameState,
Expand All @@ -593,6 +597,7 @@ class CESIUM3DTILESSELECTION_API Tileset final {
* @param result The current view update result.
* @param tilePriority The load priority of this tile.
* priority.
* @param tileSse The screen space error of this tile.
* @param queuedForLoad True if this tile has already been queued for loading.
* @return true The additive-refined tile was queued for load and added to the
* render list.
Expand All @@ -603,6 +608,7 @@ class CESIUM3DTILESSELECTION_API Tileset final {
Tile& tile,
ViewUpdateResult& result,
double tilePriority,
double tileSse,
bool queuedForLoad);

void _unloadCachedTiles(double timeBudget) noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,26 @@ class CESIUM3DTILESSELECTION_API ViewUpdateResult final {
* @brief The tiles that were selected by the tileset traversal this frame.
* These tiles should be rendered by the client.
*
* Tiles in this list may be fading in if
* {@link TilesetOptions::enableLodTransitionPeriod} is true.
* Tiles in this list may be fading in if \ref
* TilesetOptions::enableLodTransitionPeriod is true.
*/
std::vector<Tile::ConstPointer> tilesToRenderThisFrame;

/**
* @brief The computed screen space error of the tiles selected by the
* tileset traversal this frame. The values correspond to the tiles linked in
* \ref tilesToRenderThisFrame, and may be used by the client to influence
* rendering behavior.
*/
std::vector<double> tileScreenSpaceErrorThisFrame;

/**
* @brief Tiles on this list are no longer selected for rendering.
*
* If {@link TilesetOptions::enableLodTransitionPeriod} is true they may be
* fading out. If a tile's {TileRenderContent::lodTransitionPercentage} is 0
* or lod transitions are disabled, the tile should be hidden right away.
* If \ref TilesetOptions::enableLodTransitionPeriod is true they may be
* fading out. If a tile's \ref
* TileRenderContent::getLodTransitionFadePercentage is 0 or LOD transitions
* are disabled, the tile should be hidden right away.
*/
std::unordered_set<Tile::ConstPointer> tilesFadingOut;

Expand Down
57 changes: 40 additions & 17 deletions Cesium3DTilesSelection/src/Tileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -856,15 +856,14 @@ void computeDistances(

} // namespace

bool Tileset::_meetsSse(
double Tileset::_computeSse(
const std::vector<ViewState>& frustums,
const Tile& tile,
const std::vector<double>& distances,
bool culled) const noexcept {

const std::vector<double>& distances) const noexcept {
double largestSse = 0.0;

for (size_t i = 0; i < frustums.size() && i < distances.size(); ++i) {
CESIUM_ASSERT(frustums.size() == distances.size());
for (size_t i = 0; i < frustums.size(); ++i) {
const ViewState& frustum = frustums[i];
const double distance = distances[i];

Expand All @@ -875,12 +874,22 @@ bool Tileset::_meetsSse(
largestSse = sse;
}
}
return largestSse;
}

bool Tileset::_meetsSseThreshold(double sse, bool culled) const noexcept {
return culled ? !this->_options.enforceCulledScreenSpaceError ||
largestSse < this->_options.culledScreenSpaceError
: largestSse < this->_options.maximumScreenSpaceError;
sse < this->_options.culledScreenSpaceError
: sse < this->_options.maximumScreenSpaceError;
}

namespace {
void addTileToRender(ViewUpdateResult& result, Tile& tile, double sse) {
result.tilesToRenderThisFrame.emplace_back(&tile);
result.tileScreenSpaceErrorThisFrame.emplace_back(sse);
}
} // namespace

// Visits a tile for possible rendering. When we call this function with a tile:
// * It is not yet known whether the tile is visible.
// * Its parent tile does _not_ meet the SSE (unless ancestorMeetsSse=true,
Expand Down Expand Up @@ -987,8 +996,8 @@ Tileset::TraversalDetails Tileset::_visitTileIfNeeded(
++result.culledTilesVisited;
}

bool meetsSse =
this->_meetsSse(frameState.frustums, tile, distances, cullResult.culled);
double tileSse = this->_computeSse(frameState.frustums, tile, distances);
bool meetsSse = this->_meetsSseThreshold(tileSse, cullResult.culled);

TraversalDetails details = this->_visitTile(
frameState,
Expand All @@ -997,6 +1006,7 @@ Tileset::TraversalDetails Tileset::_visitTileIfNeeded(
ancestorMeetsSse,
tile,
tilePriority,
tileSse,
result);

traversalState.finishNode(&tile);
Expand All @@ -1012,10 +1022,11 @@ Tileset::TraversalDetails Tileset::_renderLeaf(
const TilesetFrameState& frameState,
Tile& tile,
double tilePriority,
double tileSse,
ViewUpdateResult& result) {
frameState.viewGroup.getTraversalState().currentState() =
TileSelectionState(TileSelectionState::Result::Rendered);
result.tilesToRenderThisFrame.emplace_back(&tile);
addTileToRender(result, tile, tileSse);

addTileToLoadQueue(
frameState,
Expand Down Expand Up @@ -1059,14 +1070,15 @@ bool mustContinueRefiningToDeeperTiles(
Tileset::TraversalDetails Tileset::_renderInnerTile(
const TilesetFrameState& frameState,
Tile& tile,
double tileSse,
ViewUpdateResult& result) {
addCurrentTileDescendantsToTilesFadingOutIfPreviouslyRendered(
frameState.viewGroup,
tile,
result);
frameState.viewGroup.getTraversalState().currentState() =
TileSelectionState(TileSelectionState::Result::Rendered);
result.tilesToRenderThisFrame.emplace_back(&tile);
addTileToRender(result, tile, tileSse);

return Tileset::createTraversalDetailsForSingleTile(frameState, tile);
}
Expand All @@ -1076,11 +1088,12 @@ bool Tileset::_loadAndRenderAdditiveRefinedTile(
Tile& tile,
ViewUpdateResult& result,
double tilePriority,
double tileSse,
bool queuedForLoad) {
// If this tile uses additive refinement, we need to render this tile in
// addition to its children.
if (tile.getRefine() == TileRefine::Add) {
result.tilesToRenderThisFrame.emplace_back(&tile);
addTileToRender(result, tile, tileSse);
if (!queuedForLoad)
addTileToLoadQueue(
frameState,
Expand All @@ -1101,7 +1114,8 @@ bool Tileset::_kickDescendantsAndRenderTile(
size_t firstRenderedDescendantIndex,
const TilesetViewGroup::LoadQueueCheckpoint& loadQueueBeforeChildren,
bool queuedForLoad,
double tilePriority) {
double tilePriority,
double tileSse) {
// Mark all visited descendants of this tile as kicked.
TilesetViewGroup::TraversalState& traversalState =
frameState.viewGroup.getTraversalState();
Expand Down Expand Up @@ -1130,14 +1144,20 @@ bool Tileset::_kickDescendantsAndRenderTile(

// Remove all descendants from the render list and add this tile.
std::vector<Tile::ConstPointer>& renderList = result.tilesToRenderThisFrame;
std::vector<double>& sseList = result.tileScreenSpaceErrorThisFrame;
renderList.erase(
renderList.begin() +
static_cast<std::vector<Tile*>::iterator::difference_type>(
firstRenderedDescendantIndex),
renderList.end());
sseList.erase(
sseList.begin() +
static_cast<std::vector<double>::iterator::difference_type>(
firstRenderedDescendantIndex),
sseList.end());

if (tile.getRefine() != Cesium3DTilesSelection::TileRefine::Add) {
renderList.emplace_back(&tile);
addTileToRender(result, tile, tileSse);
}

traversalState.currentState() =
Expand Down Expand Up @@ -1291,6 +1311,7 @@ Tileset::TraversalDetails Tileset::_visitTile(
// children!
Tile& tile,
double tilePriority,
double tileSse,
ViewUpdateResult& result) {
TilesetViewGroup::TraversalState& traversalState =
frameState.viewGroup.getTraversalState();
Expand All @@ -1300,7 +1321,7 @@ Tileset::TraversalDetails Tileset::_visitTile(

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

const bool unconditionallyRefine = tile.getUnconditionallyRefine();
Expand Down Expand Up @@ -1404,7 +1425,7 @@ Tileset::TraversalDetails Tileset::_visitTile(
tilePriority);
}

return this->_renderInnerTile(frameState, tile, result);
return this->_renderInnerTile(frameState, tile, tileSse, result);
}
}

Expand All @@ -1415,6 +1436,7 @@ Tileset::TraversalDetails Tileset::_visitTile(
tile,
result,
tilePriority,
tileSse,
queuedForLoad) ||
queuedForLoad;

Expand Down Expand Up @@ -1468,7 +1490,8 @@ Tileset::TraversalDetails Tileset::_visitTile(
firstRenderedDescendantIndex,
loadQueueBeforeChildren,
queuedForLoad,
tilePriority);
tilePriority,
tileSse);
} else {
if (tile.getRefine() != TileRefine::Add) {
addCurrentTileToTilesFadingOutIfPreviouslyRendered(
Expand Down
1 change: 1 addition & 0 deletions Cesium3DTilesSelection/src/TilesetViewGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ void TilesetViewGroup::startNewFrame(
this->_updateResult.maxDepthVisited = 0;

this->_updateResult.tilesToRenderThisFrame.clear();
this->_updateResult.tileScreenSpaceErrorThisFrame.clear();

if (!tileset.getOptions().enableLodTransitionPeriod) {
this->_updateResult.tilesFadingOut.clear();
Expand Down
Loading