diff --git a/src/osgEarthCesium/CesiumCreditsNode b/src/osgEarthCesium/CesiumCreditsNode index dd65a6a612..ce7c435b0a 100644 --- a/src/osgEarthCesium/CesiumCreditsNode +++ b/src/osgEarthCesium/CesiumCreditsNode @@ -26,6 +26,7 @@ #include #include #include +#include namespace osgEarth { namespace Cesium @@ -35,7 +36,7 @@ namespace osgEarth { class OSGEARTHCESIUM_EXPORT CesiumCreditsNode : public osg::Group { public: - CesiumCreditsNode(osg::View* view); + CesiumCreditsNode(osg::View* view, CesiumUtility::CreditSystem* creditSystem); virtual void traverse(osg::NodeVisitor& nv); @@ -51,6 +52,7 @@ namespace osgEarth { std::vector< std::string > _credits; osg::Camera* _camera; osg::observer_ptr< osg::View > _view; + std::shared_ptr< CesiumUtility::CreditSystem > _creditSystem; }; } } diff --git a/src/osgEarthCesium/CesiumCreditsNode.cpp b/src/osgEarthCesium/CesiumCreditsNode.cpp index 6818516659..d09aeec0a5 100644 --- a/src/osgEarthCesium/CesiumCreditsNode.cpp +++ b/src/osgEarthCesium/CesiumCreditsNode.cpp @@ -144,11 +144,12 @@ namespace } } -CesiumCreditsNode::CesiumCreditsNode(osg::View* view) +CesiumCreditsNode::CesiumCreditsNode(osg::View* view, CesiumUtility::CreditSystem* creditSystem) { setNumChildrenRequiringUpdateTraversal(1); _view = view; + _creditSystem = std::shared_ptr< CesiumUtility::CreditSystem >(creditSystem); _camera = new osg::Camera; _camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); @@ -165,15 +166,14 @@ CesiumCreditsNode::CesiumCreditsNode(osg::View* view) void CesiumCreditsNode::nextFrame() { - auto creditSystem = Context::instance().creditSystem; - creditSystem->startNextFrame(); + _creditSystem->startNextFrame(); } void CesiumCreditsNode::updateCredits() { std::vector< ParsedCredit > parsedCredits; - auto creditSystem = Context::instance().creditSystem; + auto creditSystem = _creditSystem; auto credits = creditSystem->getCreditsToShowThisFrame(); for (auto& credit : credits) { diff --git a/src/osgEarthCesium/CesiumIon b/src/osgEarthCesium/CesiumIon index b7032f1bbb..fee4e93b61 100644 --- a/src/osgEarthCesium/CesiumIon +++ b/src/osgEarthCesium/CesiumIon @@ -23,12 +23,15 @@ #define OSGEARTH_CESIUM_CESIUMION_H #include "Export" -#include +#include #include +#include +#include namespace osgEarth { namespace Cesium { + class Context; using namespace osgEarth; struct OSGEARTHCESIUM_EXPORT CesiumIonAsset @@ -48,10 +51,19 @@ namespace osgEarth { { public: CesiumIon(); + ~CesiumIon(); void refresh(); + static CesiumIon& instance(); + + Context* getContext(const std::string& server); + void shutdown(); + std::vector< CesiumIonAsset > assets; + + private: + std::map< std::string, Context* > contexts; }; } } diff --git a/src/osgEarthCesium/CesiumIon.cpp b/src/osgEarthCesium/CesiumIon.cpp index 59d11d7090..2ef41cf8d6 100644 --- a/src/osgEarthCesium/CesiumIon.cpp +++ b/src/osgEarthCesium/CesiumIon.cpp @@ -34,42 +34,78 @@ CesiumIon::CesiumIon() refresh(); } -void CesiumIon::refresh() +CesiumIon::~CesiumIon() { - ApplicationData data; - data.authenticationMode = AuthenticationMode::SingleUser; + shutdown(); +} - Connection connection(Context::instance().asyncSystem, Context::instance().assetAccessor, getCesiumIonKey(), data); +osgEarth::Cesium::CesiumIon& CesiumIon::instance() +{ + static CesiumIon s_cesiumIon; + return s_cesiumIon; +} - bool loaded = false; +void CesiumIon::shutdown() +{ + for (auto& c : contexts) + { + delete c.second; + } + contexts.clear(); +} - connection.assets().thenInMainThread([&](Response&& result) { - assets.clear(); +Context* CesiumIon::getContext(const std::string& server) +{ + if (contexts.find(server) != contexts.end()) { + return contexts[server]; + } + else { + Context* context = new Context(); - loaded = true; + ApplicationData data; + data.authenticationMode = AuthenticationMode::SingleUser; - if (result.value.has_value()) - { - for (auto& a : result.value->items) + context->connection = std::unique_ptr(new Connection(context->asyncSystem, context->assetAccessor, getCesiumIonKey(), data, server)); + + contexts[server] = context; + + bool loaded = false; + + context->connection->assets().thenInMainThread([&](Response&& result) { + + loaded = true; + + if (result.value.has_value()) { - CesiumIonAsset asset; - asset.attribution = a.attribution; - asset.bytes = a.bytes; - asset.dateAdded = a.dateAdded; - asset.description = a.description; - asset.id = a.id; - asset.name = a.name; - asset.percentComplete = a.percentComplete; - asset.status = a.status; - asset.type = a.type; - assets.emplace_back(std::move(asset)); + for (auto& a : result.value->items) + { + CesiumIonAsset asset; + asset.attribution = a.attribution; + asset.bytes = a.bytes; + asset.dateAdded = a.dateAdded; + asset.description = a.description; + asset.id = a.id; + asset.name = a.name; + asset.percentComplete = a.percentComplete; + asset.status = a.status; + asset.type = a.type; + assets.emplace_back(std::move(asset)); + } } + }); + + // Wait for the assets to be loaded. + while (!loaded) + { + context->asyncSystem.dispatchMainThreadTasks(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - }); - // Wait for the assets to be loaded. - while (!loaded) - { - Context::instance().asyncSystem.dispatchMainThreadTasks(); - } + return context; + } +} + +void CesiumIon::refresh() +{ + } \ No newline at end of file diff --git a/src/osgEarthCesium/CesiumLayer b/src/osgEarthCesium/CesiumLayer index 1a5e7e024c..cf329ac689 100644 --- a/src/osgEarthCesium/CesiumLayer +++ b/src/osgEarthCesium/CesiumLayer @@ -35,6 +35,7 @@ namespace osgEarth class OSGEARTHCESIUM_EXPORT Options : public VisibleLayer::Options { public: META_LayerOptions(osgEarthCesium, Options, VisibleLayer::Options); + OE_OPTION(URI, server); OE_OPTION(URI, url); OE_OPTION(unsigned int, assetId); OE_OPTION(std::string, token); diff --git a/src/osgEarthCesium/CesiumLayer.cpp b/src/osgEarthCesium/CesiumLayer.cpp index 4a26742dd4..feb3d70590 100644 --- a/src/osgEarthCesium/CesiumLayer.cpp +++ b/src/osgEarthCesium/CesiumLayer.cpp @@ -34,6 +34,7 @@ Config CesiumNative3DTilesLayer::Options::getConfig() const { Config conf = VisibleLayer::Options::getConfig(); + conf.set("server", _server); conf.set("url", _url); conf.set("asset_id", _assetId); conf.set("token", _token); @@ -47,8 +48,10 @@ CesiumNative3DTilesLayer::Options::getConfig() const void CesiumNative3DTilesLayer::Options::fromConfig(const Config& conf) { + _server.init("https://api.cesium.com/"); _maximumScreenSpaceError.setDefault(16.0f); _forbidHoles.setDefault(false); + conf.get("server", _server); conf.get("url", _url); conf.get("asset_id", _assetId); conf.get("token", _token); @@ -98,7 +101,7 @@ CesiumNative3DTilesLayer::openImplementation() { overlays.push_back(*_options->rasterOverlay()); } - _tilesetNode = new CesiumTilesetNode(_options->url()->full(), token, *_options->maximumScreenSpaceError(), overlays); + _tilesetNode = new CesiumTilesetNode(_options->url()->full(), _options->server()->full(), token, *_options->maximumScreenSpaceError(), overlays); } else if (_options->assetId().isSet()) { @@ -107,7 +110,7 @@ CesiumNative3DTilesLayer::openImplementation() { overlays.push_back(*_options->rasterOverlay()); } - _tilesetNode = new CesiumTilesetNode(*_options->assetId(), token, *_options->maximumScreenSpaceError(), overlays); + _tilesetNode = new CesiumTilesetNode(*_options->assetId(), _options->server()->full(), token, *_options->maximumScreenSpaceError(), overlays); } if (!_tilesetNode.valid()) diff --git a/src/osgEarthCesium/CesiumTilesetNode b/src/osgEarthCesium/CesiumTilesetNode index 899b62b1e8..d13c8d0b3f 100644 --- a/src/osgEarthCesium/CesiumTilesetNode +++ b/src/osgEarthCesium/CesiumTilesetNode @@ -32,8 +32,8 @@ namespace osgEarth { namespace Cesium class OSGEARTHCESIUM_EXPORT CesiumTilesetNode : public osg::Group { public: - CesiumTilesetNode(unsigned int assetID, const std::string& token = "", float maximumScreenSpaceError = 16.0f, std::vector overlays = std::vector()); - CesiumTilesetNode(const std::string& url, const std::string& token = "", float maximumScreenSpaceError = 16.0f, std::vector overlays = std::vector()); + CesiumTilesetNode(unsigned int assetID, const std::string& server = "", const std::string& token = "", float maximumScreenSpaceError = 16.0f, std::vector overlays = std::vector()); + CesiumTilesetNode(const std::string& url, const std::string& server = "", const std::string& token = "", float maximumScreenSpaceError = 16.0f, std::vector overlays = std::vector()); ~CesiumTilesetNode(); diff --git a/src/osgEarthCesium/CesiumTilesetNode.cpp b/src/osgEarthCesium/CesiumTilesetNode.cpp index dc9b813a54..80b34b01d4 100644 --- a/src/osgEarthCesium/CesiumTilesetNode.cpp +++ b/src/osgEarthCesium/CesiumTilesetNode.cpp @@ -21,6 +21,7 @@ */ #include "CesiumTilesetNode" #include "Context" +#include "CesiumIon" #include "Settings" #include @@ -29,16 +30,18 @@ using namespace osgEarth::Cesium; -CesiumTilesetNode::CesiumTilesetNode(unsigned int assetID, const std::string& token, float maximumScreenSpaceError, std::vector overlays) +CesiumTilesetNode::CesiumTilesetNode(unsigned int assetID, const std::string& server, const std::string& token, float maximumScreenSpaceError, std::vector overlays) { + Context* context = CesiumIon::instance().getContext(server); + Cesium3DTilesSelection::TilesetExternals externals{ - Context::instance().assetAccessor, Context::instance().prepareRenderResources, Context::instance().asyncSystem, Context::instance().creditSystem, Context::instance().logger, nullptr + context->assetAccessor, context->prepareRenderResources, context->asyncSystem, context->creditSystem, context->logger, nullptr }; Cesium3DTilesSelection::TilesetOptions options; options.maximumScreenSpaceError = maximumScreenSpaceError; options.contentOptions.generateMissingNormalsSmooth = true; - Cesium3DTilesSelection::Tileset* tileset = new Cesium3DTilesSelection::Tileset(externals, assetID, token, options); + Cesium3DTilesSelection::Tileset* tileset = new Cesium3DTilesSelection::Tileset(externals, assetID, token, options, server); for (auto overlay: overlays) { @@ -51,10 +54,12 @@ CesiumTilesetNode::CesiumTilesetNode(unsigned int assetID, const std::string& to setCullingActive(false); } -CesiumTilesetNode::CesiumTilesetNode(const std::string& url, const std::string& token, float maximumScreenSpaceError, std::vector overlays) +CesiumTilesetNode::CesiumTilesetNode(const std::string& url, const std::string& server, const std::string& token, float maximumScreenSpaceError, std::vector overlays) { + Context* context = CesiumIon::instance().getContext(server); + Cesium3DTilesSelection::TilesetExternals externals{ - Context::instance().assetAccessor, Context::instance().prepareRenderResources, Context::instance().asyncSystem, Context::instance().creditSystem, Context::instance().logger, nullptr + context->assetAccessor, context->prepareRenderResources, context->asyncSystem, context->creditSystem, context->logger, nullptr }; Cesium3DTilesSelection::TilesetOptions options; @@ -64,7 +69,7 @@ CesiumTilesetNode::CesiumTilesetNode(const std::string& url, const std::string& for (auto overlay : overlays) { CesiumRasterOverlays::RasterOverlayOptions rasterOptions; - const auto ionRasterOverlay = new CesiumRasterOverlays::IonRasterOverlay("", overlay, token, rasterOptions); + const auto ionRasterOverlay = new CesiumRasterOverlays::IonRasterOverlay("", overlay, token, rasterOptions, server); tileset->getOverlays().add(ionRasterOverlay); } _tileset = tileset; diff --git a/src/osgEarthCesium/Context b/src/osgEarthCesium/Context index 3aec8eec8d..759ca82de0 100644 --- a/src/osgEarthCesium/Context +++ b/src/osgEarthCesium/Context @@ -23,7 +23,6 @@ #define OSGEARTH_CESIUM_CONTEXT_H #include "CesiumTilesetNode" -#include #include "AssetAccessor" #include "PrepareRenderResources" @@ -33,9 +32,11 @@ #include #include #include +#include #include #include #include +#include #include @@ -51,20 +52,18 @@ namespace osgEarth { public: Context(); - ~Context(); void shutdown(); - static Context& instance(); - std::shared_ptr< PrepareRendererResources > prepareRenderResources; std::shared_ptr assetAccessor; std::shared_ptr taskProcessor; std::shared_ptr< spdlog::logger > logger; std::shared_ptr< CesiumUtility::CreditSystem > creditSystem; CesiumAsync::AsyncSystem asyncSystem; - std::unique_ptr context; + + std::unique_ptr< CesiumIonClient::Connection > connection; }; } } diff --git a/src/osgEarthCesium/Context.cpp b/src/osgEarthCesium/Context.cpp index b7fb944036..0653f0cfaf 100644 --- a/src/osgEarthCesium/Context.cpp +++ b/src/osgEarthCesium/Context.cpp @@ -40,6 +40,7 @@ Context::Context(): Context::~Context() { + shutdown(); } void Context::shutdown() @@ -52,8 +53,3 @@ void Context::shutdown() asyncSystem.dispatchMainThreadTasks(); } -Context& Context::instance() -{ - static Context s_context; - return s_context; -} \ No newline at end of file diff --git a/src/osgEarthCesium/Settings.cpp b/src/osgEarthCesium/Settings.cpp index b0c3cee3c6..6af0b7eeb6 100644 --- a/src/osgEarthCesium/Settings.cpp +++ b/src/osgEarthCesium/Settings.cpp @@ -21,7 +21,7 @@ */ #include "Settings" -#include "Context" +#include "CesiumIon" // TODO: Replace this with the default key from Cesium static std::string CESIUM_KEY = ""; @@ -57,5 +57,5 @@ void osgEarth::Cesium::setCesiumIonKey(const std::string& key) void osgEarth::Cesium::shutdown() { - Context::instance().shutdown(); + CesiumIon::instance().shutdown(); } \ No newline at end of file