Add VectorTilesRasterOverlay#1365
Conversation
|
Hey @kring! Are you able to take a glance from an architectural level for this PR? |
Problem is that the dataset I'm using has a bunch of polygons in one primitive...
|
If I can try to summarize how this works... Every time we need a raster image for a terrain tile, we call
The futures returned by The This is potentially a lot of traversals. For vector tilesets with a small number of tiles, it probably isn't too bad. But I think it'll get pretty expensive for bigger ones. Another more subtle problem is that a single call to I don't have any easy solution to this. Probably the ideal approach is more polling-based and incremental. That is, perhaps So I'd say it's reasonable to move forward with the current approach, and just keep an eye on how much time we're spending in this process as users start to work with larger vector tilesets. |
| */ | ||
| size_t size() const noexcept; | ||
|
|
||
| void tick() noexcept; |
There was a problem hiding this comment.
This doesn't appear to be used. The Tileset just calls ActivateRasterOverlay::tick directly.
|
|
||
| void tick(); | ||
|
|
||
| bool isTickable() const noexcept; |
There was a problem hiding this comment.
Not used, other than by the ticking system in RasterOverlayCollection, which is itself unused.
| // part 1 - selecting from scratch | ||
| if (this->_pTilesetContentManager->getRootTile() == nullptr) { | ||
| return this->_pTilesetContentManager->getRootTileAvailableEvent() | ||
| .thenInWorkerThread([this, |
There was a problem hiding this comment.
Two problems here:
- I think the root tile available event can resolve while the root tile is still nullptr, e.g., if there's an error. If it does, this will be an endless promise cycle.
- It's not valid to call
loadTileImageFromTilesetin a worker thread, because it accesses theTilesetContentManager.
| nullptr}; | ||
|
|
||
| this->_pTilesetContentManager = | ||
| TilesetContentManager::createFromUrl(externals, TilesetOptions{}, url); |
There was a problem hiding this comment.
What if we had a single tileset that had both normal meshes and vector data? For example, what if Google Photorealistic 3D Tiles also contained vector roads or points of interest?
I think in that case it would be really important to have just a single TilesetContentManager. Otherwise, we'd end up loading every tile twice.
| // external content and now we need to check their children. | ||
| return this | ||
| ->addLoadRequest(this->getAsyncSystem(), loadInfo.tileLoadTasks) | ||
| .thenImmediately([this, tileRectangle, textureSize]() mutable { |
There was a problem hiding this comment.
You can't call findAndLoadTiles anywhere but the main thread, so this should be thenInMainThread.
There was a problem hiding this comment.
There is an interesting possibility here... rather than strictly running the selection algorithm in the main thread, it is theoretically possible to run it in a worker thread instead. However, in that case, we need to be very careful that it's always called from the same worker thread. We could do that with a thread pool with one thread, as we do with the request cache. Also, this will break down if a VectorTilesRasterOverlay ever uses a Tileset that is also used for normal rendering.
| CesiumAsync::Future<void> future = request.promise.getFuture(); | ||
|
|
||
| std::scoped_lock<std::mutex> lock( | ||
| this->_pSharedTileSelectionState->loadRequestsMutex); |
There was a problem hiding this comment.
I can't see any reason to use a mutex. All accesses of loadRequests are (and must be) on the main thread.
| */ | ||
| VectorTilesRasterOverlay( | ||
| const std::string& name, | ||
| const TilesetSource& source, |
There was a problem hiding this comment.
I'd suggest an overload rather than a variant here.
|
|
||
| #include "RasterOverlayUpsampler.h" | ||
|
|
||
| #include <Cesium3DTilesSelection/CesiumIonTilesetContentLoaderFactory.h> |
There was a problem hiding this comment.
I'd prefer not to make TilesetContentManager part of the public API. Almost everything you need it for can also be achieved through Tileset. Expand and refactor that class, if necessary.
I guess it's worth considering what is the actual separation of concerns here. Originally, there was no TilesetContentManager; everything was in Tileset. When Bao introduced the TilesetContentManager, he described it like this:
Previously Tileset and Tile are used to set the state machine of Tile. Now only TilesetContentManager will take care of that. Its responsibilities consists of loading tile content (by using TilesetContentLoader), managing tile loading state machine, and unloading tile. No ones except the TilesetContentManager can set the state of the tile now
So the content manager handled tile content state transitions (loading/unloading, basically) and the Tileset handled the rest. Where "the rest" was mostly the selection algorithm and the public entry points to the content manager.
Now with #1342, we're talking about moving the selection algorith out of Tileset, too.
What's left? Not much I guess, but I think it's still serving a useful purpose as the public API representation of a Tileset, even if almost everything it does is delegated. By exposing TilesetContentManager, we a) need to give a lot more thought to its public API, because very little has gone into it, and b) are committing to maintaining it (yes, our deprecation policy doesn't strictly require we avoid breakage, but we still should avoid it wherever possibe).
|
|
||
| struct LoadRequest { | ||
| CesiumAsync::Promise<void> promise; | ||
| std::set<Tile*> requestedTiles; |
There was a problem hiding this comment.
I think it might be better to use a sorted std::vector<Tile*> here instead of a std::set. Similar time complexity, far fewer memory allocations and better cache locality.
This PR adds support for rendering vector tilesets as a raster overlay. It uses a rasterization approach similar to the existing
GeoJsonDocumentRasterOverlay, but instead of working from a single document, it works from a 3D Tiles tileset.There are many things that need to get done before this PR is final:
Polygons should be supported.✅Should work as long as they haveEXT_mesh_polygon.VectorTilesRasterOverlaythat isn't inCesium3DTilesSelection. It can't be inCesiumRasterOverlaysas it currently uses the internalTilesetContentManagerinCesium3DTilesSelection.Also for the future:
GeoJsonDocumentRasterOverlaywe got away with letting users customize the styles on elements directly in the document before the raster overlay was loaded, so users can accomplish any kind of metadata styling or other sort of styling they're looking for. But we'll need a different approach for a 3D Tiles tileset. Is it finally time to handle style expressions? (Support for 3D Tiles Styling language #1208)