Skip to content

Commit

Permalink
Add ITilesetHeightQuery.
Browse files Browse the repository at this point in the history
  • Loading branch information
kring committed Nov 19, 2024
1 parent 5e5c4b1 commit 34cff71
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Cesium3DTilesSelection {
* @brief A loader that will generate a tileset by tesselating the surface of an
* ellipsoid, producing a simple globe tileset without any terrain features.
*/
class EllipsoidTilesetLoader : public TilesetContentLoader {
class EllipsoidTilesetLoader : public TilesetContentLoader,
public ITilesetHeightQuery {
public:
/**
* @brief Constructs a new instance.
Expand All @@ -35,6 +36,12 @@ class EllipsoidTilesetLoader : public TilesetContentLoader {
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) override;

ITilesetHeightQuery* getHeightQuery() override;

CesiumAsync::Future<SampleHeightResult> queryHeights(
const CesiumAsync::AsyncSystem& asyncSystem,
std::vector<CesiumGeospatial::Cartographic>&& positions) override;

private:
struct Geometry {
std::vector<uint16_t> indices;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "TileLoadResult.h"
#include "TilesetOptions.h"

#include <Cesium3DTilesSelection/SampleHeightResult.h>
#include <CesiumAsync/AsyncSystem.h>
#include <CesiumAsync/Future.h>
#include <CesiumAsync/IAssetAccessor.h>
Expand Down Expand Up @@ -108,6 +109,25 @@ struct CESIUM3DTILESSELECTION_API TileChildrenResult {
TileLoadResultState state;
};

/**
* @brief An interface to query heights from a tileset that can do so
* efficiently without necessarily downloading individual tiles.
*/
class CESIUM3DTILESSELECTION_API ITilesetHeightQuery {
public:
/**
* @brief Queries the heights at a list of locations.
*
* @param asyncSystem The async system used to do work in threads.
* @param positions The positions at which to query heights. The height field
* of each {@link Cartographic} is ignored.
* @return A future that will be resolved when the heights have been queried.
*/
virtual CesiumAsync::Future<SampleHeightResult> queryHeights(
const CesiumAsync::AsyncSystem& asyncSystem,
std::vector<CesiumGeospatial::Cartographic>&& positions) = 0;
};

/**
* @brief The loader interface to load the tile content
*/
Expand Down Expand Up @@ -145,5 +165,24 @@ class CESIUM3DTILESSELECTION_API TilesetContentLoader {
const Tile& tile,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) = 0;

/**
* @brief Gets an interface that can be used to efficiently query heights from
* this tileset.
*
* Some loaders may be able to query heights very efficiently by using a web
* service or by using an analytical model, e.g., when the "terrain" is a
* simple ellipsoid.
*
* For loaders that have no particular way to query heights, this method will
* return `nullptr`, signaling that heights should be computed by downloading
* and sampling individual tiles.
*
* @return The interface that can be used to efficiently query heights from
* this loader, or `nullptr` if this loader has no particular way to do that.
* The returned instance must have a lifetime that is at least as long as the
* loader itself.
*/
virtual ITilesetHeightQuery* getHeightQuery() { return nullptr; }
};
} // namespace Cesium3DTilesSelection
17 changes: 17 additions & 0 deletions Cesium3DTilesSelection/src/EllipsoidTilesetLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ TileChildrenResult EllipsoidTilesetLoader::createTileChildren(
return TileChildrenResult{{}, TileLoadResultState::Failed};
}

ITilesetHeightQuery* EllipsoidTilesetLoader::getHeightQuery() { return this; }

CesiumAsync::Future<SampleHeightResult> EllipsoidTilesetLoader::queryHeights(
const CesiumAsync::AsyncSystem& asyncSystem,
std::vector<CesiumGeospatial::Cartographic>&& positions) {
SampleHeightResult result;

result.positions = std::move(positions);
result.sampleSuccess.resize(result.positions.size(), true);

for (Cartographic& position : result.positions) {
position.height = 0.0;
}

return asyncSystem.createResolvedFuture(std::move(result));
}

void EllipsoidTilesetLoader::createChildTile(
const Tile& parent,
std::vector<Tile>& children,
Expand Down
1 change: 1 addition & 0 deletions Cesium3DTilesSelection/src/Tileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ Tileset::updateView(const std::vector<ViewState>& frustums, float deltaTime) {
}

TilesetHeightRequest::processHeightRequests(
this->getAsyncSystem(),
*this->_pTilesetContentManager,
this->_options,
this->_loadedTiles,
Expand Down
27 changes: 27 additions & 0 deletions Cesium3DTilesSelection/src/TilesetHeightQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ void TilesetHeightQuery::findCandidateTiles(
}

/*static*/ void TilesetHeightRequest::processHeightRequests(
const AsyncSystem& asyncSystem,
TilesetContentManager& contentManager,
const TilesetOptions& options,
Tile::LoadedLinkedList& loadedTiles,
Expand All @@ -214,6 +215,7 @@ void TilesetHeightQuery::findCandidateTiles(
for (auto it = heightRequests.begin(); it != heightRequests.end();) {
TilesetHeightRequest& request = *it;
if (!request.tryCompleteHeightRequest(
asyncSystem,
contentManager,
options,
loadedTiles,
Expand Down Expand Up @@ -249,10 +251,35 @@ void Cesium3DTilesSelection::TilesetHeightRequest::failHeightRequests(
}

bool TilesetHeightRequest::tryCompleteHeightRequest(
const AsyncSystem& asyncSystem,
TilesetContentManager& contentManager,
const TilesetOptions& options,
Tile::LoadedLinkedList& loadedTiles,
std::set<Tile*>& tileLoadSet) {
// If this TilesetContentLoader supports direct height queries, use that
// instead of downloading tiles.
if (contentManager.getRootTile() &&
contentManager.getRootTile()->getLoader()) {
ITilesetHeightQuery* pQuery =
contentManager.getRootTile()->getLoader()->getHeightQuery();
if (pQuery) {
std::vector<Cartographic> positions;
positions.reserve(this->queries.size());
for (TilesetHeightQuery& query : this->queries) {
positions.emplace_back(query.inputPosition);
}

pQuery->queryHeights(asyncSystem, std::move(positions))
.thenImmediately(
[promise = this->promise](SampleHeightResult&& result) {
promise.resolve(std::move(result));
});

return true;
}
}

// No direct height query possible, so download and sample tiles.
bool tileStillNeedsLoading = false;
std::vector<std::string> warnings;
for (TilesetHeightQuery& query : this->queries) {
Expand Down
4 changes: 4 additions & 0 deletions Cesium3DTilesSelection/src/TilesetHeightQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ struct TilesetHeightRequest {
* @brief Process a given list of height requests. This is called by the {@link Tileset}
* in every call to {@link Tileset::updateView}.
*
* @param asyncSystem The async system used to do work in threads.
* @param contentManager The content manager.
* @param options Options associated with the tileset.
* @param loadedTiles The linked list of loaded tiles, used to ensure that
Expand All @@ -137,6 +138,7 @@ struct TilesetHeightRequest {
* height requests can complete are added to this vector.
*/
static void processHeightRequests(
const CesiumAsync::AsyncSystem& asyncSystem,
TilesetContentManager& contentManager,
const TilesetOptions& options,
Tile::LoadedLinkedList& loadedTiles,
Expand All @@ -160,6 +162,7 @@ struct TilesetHeightRequest {
* @brief Tries to complete this height request. Returns false if further data
* still needs to be loaded and thus the request cannot yet complete.
*
* @param asyncSystem The async system used to do work in threads.
* @param contentManager The content manager.
* @param options Options associated with the tileset.
* @param loadedTiles The linked list of loaded tiles, used to ensure that
Expand All @@ -169,6 +172,7 @@ struct TilesetHeightRequest {
* can complete.
*/
bool tryCompleteHeightRequest(
const CesiumAsync::AsyncSystem& asyncSystem,
TilesetContentManager& contentManager,
const TilesetOptions& options,
Tile::LoadedLinkedList& loadedTiles,
Expand Down

0 comments on commit 34cff71

Please sign in to comment.