Skip to content

Commit

Permalink
Move height query functionality out of Tileset.cpp.
Browse files Browse the repository at this point in the history
  • Loading branch information
kring committed Sep 13, 2024
1 parent 7c167ee commit 06d9e79
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 160 deletions.
15 changes: 2 additions & 13 deletions Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
#include <list>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

namespace Cesium3DTilesSelection {
class TilesetContentManager;
class TilesetMetadata;
class TilesetHeightQuery;
class TilesetHeightRequest;

/**
* @brief A <a
Expand Down Expand Up @@ -443,11 +443,6 @@ class CESIUM3DTILESSELECTION_API Tileset final {
double tilePriority,
bool queuedForLoad);

struct HeightRequest {
std::vector<TilesetHeightQuery> queries;
CesiumAsync::Promise<SampleHeightResult> promise;
};

void _processWorkerThreadLoadQueue();
void _processMainThreadLoadQueue();

Expand Down Expand Up @@ -535,19 +530,13 @@ class CESIUM3DTILESSELECTION_API Tileset final {
CesiumUtility::IntrusivePointer<TilesetContentManager>
_pTilesetContentManager;

std::list<HeightRequest> _heightRequests;
std::list<TilesetHeightRequest> _heightRequests;

void addTileToLoadQueue(
Tile& tile,
TileLoadPriorityGroup priorityGroup,
double priority);

void processHeightRequests();

bool tryCompleteHeightRequest(
HeightRequest& request,
std::set<Tile*>& tilesNeedingLoading);

static TraversalDetails createTraversalDetailsForSingleTile(
const FrameState& frameState,
const Tile& tile,
Expand Down
153 changes: 10 additions & 143 deletions Cesium3DTilesSelection/src/Tileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,137 +310,6 @@ Tileset::updateViewOffline(const std::vector<ViewState>& frustums) {
return this->_updateResult;
}

bool Tileset::tryCompleteHeightRequest(
HeightRequest& request,
std::set<Tile*>& tilesNeedingLoading) {
Tile* pRoot = _pTilesetContentManager->getRootTile();

bool tileStillNeedsLoading = false;
std::vector<std::string> warnings;
for (TilesetHeightQuery& query : request.queries) {
if (query.candidateTiles.empty() && query.additiveCandidateTiles.empty()) {
// Find the initial set of tiles whose bounding volume is intersected by
// the query ray.
query.findCandidateTiles(pRoot, warnings);
} else {
// Refine the current set of candidate tiles, in case further tiles from
// implicit tiling, external tilesets, etc. having been loaded since last
// frame.
std::swap(query.candidateTiles, query.previousCandidateTiles);

query.candidateTiles.clear();

for (Tile* pCandidate : query.previousCandidateTiles) {
TileLoadState loadState = pCandidate->getState();
if (!pCandidate->getChildren().empty() &&
loadState >= TileLoadState::ContentLoaded) {
query.findCandidateTiles(pCandidate, warnings);
} else {
query.candidateTiles.emplace_back(pCandidate);
}
}
}

auto checkTile =
[this, &tilesNeedingLoading, &tileStillNeedsLoading](Tile* pTile) {
this->_pTilesetContentManager->createLatentChildrenIfNecessary(
*pTile,
this->getOptions());

TileLoadState state = pTile->getState();
if (state == TileLoadState::Unloading) {
// This tile is in the process of unloading, which must complete
// before we can load it again.
this->_pTilesetContentManager->unloadTileContent(*pTile);
tileStillNeedsLoading = true;
} else if (
state == TileLoadState::Unloaded ||
state == TileLoadState::FailedTemporarily) {
tilesNeedingLoading.insert(pTile);
tileStillNeedsLoading = true;
}
};

// If any candidates need loading, add to return set
for (Tile* pTile : query.additiveCandidateTiles) {
checkTile(pTile);
}
for (Tile* pTile : query.candidateTiles) {
checkTile(pTile);
}
}

// Bail if we're waiting on tiles to load
if (tileStillNeedsLoading)
return false;

// Do the intersect tests
for (TilesetHeightQuery& query : request.queries) {
for (Tile* pTile : query.additiveCandidateTiles) {
query.intersectVisibleTile(pTile);
}
for (Tile* pTile : query.candidateTiles) {
query.intersectVisibleTile(pTile);
}
}

// All rays are done, create results
SampleHeightResult results;

// Start with any warnings from tile traversal
results.warnings = std::move(warnings);

results.positions.resize(request.queries.size(), Cartographic(0.0, 0.0, 0.0));
results.heightSampled.resize(request.queries.size());

// Populate results with completed queries
for (size_t i = 0; i < request.queries.size(); ++i) {
const TilesetHeightQuery& query = request.queries[i];

bool heightSampled = query.intersectResult.hit.has_value();
results.heightSampled[i] = heightSampled;
results.positions[i] = query.inputCoordinate;

if (heightSampled) {
results.positions[i].height =
RAY_ORIGIN_HEIGHT -
glm::sqrt(query.intersectResult.hit->rayToWorldPointDistanceSq);
}

// Add query warnings into the height result
results.warnings.insert(
results.warnings.end(),
query.intersectResult.warnings.begin(),
query.intersectResult.warnings.end());
}

request.promise.resolve(std::move(results));
return true;
}

void Tileset::processHeightRequests() {
if (_heightRequests.size() == 0)
return;

// Go through all requests, either complete them, or gather the tiles they
// need for completion
std::set<Tile*> tilesNeedingLoading;
for (auto it = _heightRequests.begin(); it != _heightRequests.end();) {
HeightRequest& request = *it;
if (!tryCompleteHeightRequest(request, tilesNeedingLoading)) {
++it;
} else {
auto deleteIt = it;
++it;
_heightRequests.erase(deleteIt);
}
}

this->_heightQueryLoadQueue.assign(
tilesNeedingLoading.begin(),
tilesNeedingLoading.end());
}

const ViewUpdateResult&
Tileset::updateView(const std::vector<ViewState>& frustums, float deltaTime) {
CESIUM_TRACE("Tileset::updateView");
Expand Down Expand Up @@ -505,7 +374,11 @@ Tileset::updateView(const std::vector<ViewState>& frustums, float deltaTime) {
result = ViewUpdateResult();
}

processHeightRequests();
TilesetHeightRequest::processHeightRequests(
*this->_pTilesetContentManager,
this->_options,
this->_heightRequests,
this->_heightQueryLoadQueue);

result.workerThreadTileLoadQueueLength =
static_cast<int32_t>(this->_workerThreadLoadQueue.size());
Expand Down Expand Up @@ -683,20 +556,14 @@ Tileset::sampleHeightMostDetailed(const std::vector<Cartographic>& positions) {
Promise promise = this->_asyncSystem.createPromise<SampleHeightResult>();

std::vector<TilesetHeightQuery> queries;
for (const CesiumGeospatial::Cartographic& coordinate : positions) {
CesiumGeospatial::Cartographic startCoordinate(
coordinate.longitude,
coordinate.latitude,
RAY_ORIGIN_HEIGHT);

Ray ray(
Ellipsoid::WGS84.cartographicToCartesian(startCoordinate),
-Ellipsoid::WGS84.geodeticSurfaceNormal(startCoordinate));
queries.reserve(positions.size());

queries.push_back(TilesetHeightQuery{coordinate, std::move(ray)});
for (const CesiumGeospatial::Cartographic& position : positions) {
queries.emplace_back(position, this->_options.ellipsoid);
}

_heightRequests.emplace_back(HeightRequest{std::move(queries), promise});
this->_heightRequests.emplace_back(
TilesetHeightRequest{std::move(queries), promise});

return promise.getFuture();
}
Expand Down
Loading

0 comments on commit 06d9e79

Please sign in to comment.