Skip to content

Commit

Permalink
Merge branch 'master' of github.com:gwaldron/osgearth
Browse files Browse the repository at this point in the history
  • Loading branch information
gwaldron committed Sep 15, 2023
2 parents 69660dc + 9632aa1 commit 52e037e
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 15 deletions.
3 changes: 3 additions & 0 deletions docs/source/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ set PATH=%PATH%;path\to\build\vcpkg_installed\x64-windows\tools\osg
set PATH=%PATH%;[installroot]
```

## Building with support for cesium-native
See documentation at [here](cesium_native.html) for building osgEarth with support for cesium-native.

## Checking for an OpenGL Core Profile Context
Some situations require you to have an OpenGL Core Profile context. The ability to create a core context is available when OSG is built with OPENGL_PROFILE=GL3 or GLCORE. Environments such as Apple OSX and VMWare require it as does debugging with tools like NVidia NSight. You can check to see if you are running with an OpenGL Core Profile by running a command like this (Windows)
```
Expand Down
111 changes: 111 additions & 0 deletions docs/source/cesium_native.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@

# Building osgEarth with cesium-native

Pelican Mapping is proud to have been awarded a [Cesium Ecosystem Grant](https://cesium.com/cesium-ecosystem-grants/) to integrate [cesium-native](https://github.com/CesiumGS/cesium-native) into osgEarth!

cesium-native is a library developed by the Cesium team that provides support for loading 3d tiles datasets and as well as loading assets from Cesium Ion. cesium-native is what powers Cesium for Unreal and Cesium for Omniverse and it is now available in osgEarth.

## Building osgEarth with cesium-native support

### Building cesium-native
First, you need to build cesium-native. The official instructions for building cesium-native are [here](https://github.com/CesiumGS/cesium-native) but this is what it would generally look like
```
# Clone the cesium-native repo
git clone [email protected]:CesiumGS/cesium-native.git --recurse-submodules
# Configure cesium-native and disable tests
cmake -B build -S . -G "Visual Studio 16 2019" -A x64 -DCMAKE_INSTALL_PREFIX=install -DCESIUM_TESTS_ENABLED=OFF
# Build and install cesium-native. We generally use RelWithDebInfo on Windows but you can also build Release and Debug if you'd like.
cmake --build build --config RelWithDebInfo --install
```

The cesium-native libraries and headers are now located at cesium-native/install

You can follow the instructions for building osgEarth [here](install.html) but when you configure cmake pass in -DCESIUM_NATIVE_DIR=/path/to/cesium-native/install so that osgEarth knows how to find the cesium-native libraries and headers.

This will build the osgEarthCesium nodekit of osgEarth.

# Loading data using cesium-native
To load data from Cesium Ion, you need to tell osgEarth what your access key is so it can authenticate you. You do this by setting the OSGEARTH_CESIUMION_KEY environment variable.

On Windows
```
set OSGEARTH_CESIUMION_KEY=YOUR_KEY
```

On Linux
```
export OSGEARTH_CESIUMION_KEY=YOUR_KEY
```

cesium-native brings best in class 3d tiles streaming to osgEarth. This is exposed via the CesiumNative3DTiles layer in an earth file.

We can load a 3D tiles dataset that is not hosted on Cesium Ion by setting the url to the root tileset.
```xml
<CesiumNative3DTiles name="agi">
<url>https://pelican-public.s3.amazonaws.com/3dtiles/agi-hq/tileset.json</url>
</CesiumNative3DTiles>
```

To load an asset directly from Cesium Ion you will set the asset id like this
```xml
<CesiumNative3DTiles name="New York">
<asset_id>57587</asset_id>
</CesiumNative3DTiles>
```

Some assets, like the Cesium World Terrain, don't have any textures associated and it is useful to drape an
imagery dataset over it. To do that, use the raster_overlay setting. For example, this loads the Cesium World Terrain with the Bing imagery draped over it.
```xml
<CesiumNative3DTiles name="Cesium World Terrain and BING">
<asset_id>1</asset_id>
<raster_overlay>2</raster_overlay>
</CesiumNative3DTiles>
```

Google has also started serving out it's entire Google Earth dataset as 3D tiles. You can load all of Google Earth in osgEarth by simply adding this to your earth file. You can sign up and get a Google Maps key [here](https://developers.google.com/maps/documentation/embed/get-api-key)
```xml
<CesiumNative3DTiles name="Google Tiles">
<url>https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_GOOGLE_MAPS_KEY</url>
</CesiumNative3DTiles>
```


# Displaying Cesium Credits
cesium-native has a credit system that tells you what attribution is required to be displayed on screen based on what is currently being displayed on screen. To enable this in your application you need to add a
CesiumCreditsNode to your scene. A basic usage of the CesiumCredits node can be seen below

```c++
#include <osgViewer/Viewer>
#include <osgEarth/EarthManipulator>
#include <osgEarth/ExampleResources>
#include <osgEarth/MapNode>
#include <osgEarthCesium/CesiumCreditsNode>

using namespace osgEarth;

int
main(int argc, char** argv)
{
osgEarth::initialize();

osg::ArgumentParser arguments(&argc,argv);
osgViewer::Viewer viewer(arguments);
viewer.setCameraManipulator( new EarthManipulator(arguments) );

osg::Group* root = new osg::Group;

auto node = MapNodeHelper().load(arguments, &viewer);
if (node.valid())
{
root->addChild(node);
viewer.setSceneData(root);

auto creditsNode = new osgEarth::Cesium::CesiumCreditsNode(&viewer);
root->addChild(creditsNode);
return viewer.run();
}

return 0;
}
```
2 changes: 1 addition & 1 deletion src/osgEarth/HTTPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1553,7 +1553,7 @@ HTTPClient::doGet(const HTTPRequest& request,
// from the server each time it is it requested.
bool noCache = false;
std::string cacheControl = result.metadata().value("cache-control");
if (cacheControl.find_first_of("no-cache") != std::string::npos)
if (cacheControl.find("no-cache") != std::string::npos)
{
noCache = true;
}
Expand Down
8 changes: 8 additions & 0 deletions src/osgEarthCesium/AssetAccessor
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumAsync/IAssetResponse.h>
#include <osgDB/Options>
#include <osgEarth/Cache>

namespace osgEarth {
namespace Cesium
Expand Down Expand Up @@ -72,6 +74,8 @@ namespace osgEarth {
class AssetAccessor : public CesiumAsync::IAssetAccessor
{
public:
AssetAccessor();

virtual CesiumAsync::Future<std::shared_ptr<CesiumAsync::IAssetRequest>>
get(const CesiumAsync::AsyncSystem& asyncSystem,
const std::string& url,
Expand All @@ -87,6 +91,10 @@ namespace osgEarth {
const gsl::span<const std::byte>& contentPayload) override;

virtual void tick() noexcept override;

private:
osg::ref_ptr< osgDB::Options > _options;
osg::ref_ptr<CacheSettings> _cacheSettings;
};
}
}
Expand Down
17 changes: 14 additions & 3 deletions src/osgEarthCesium/AssetAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <osgEarth/Notify>
#include <osgEarth/URI>
#include <osgEarth/Registry>

using namespace osgEarth;
using namespace osgEarth::Cesium;
Expand Down Expand Up @@ -85,25 +86,35 @@ gsl::span<const std::byte> AssetResponse::data() const

/**********************************************/

AssetAccessor::AssetAccessor()
{
_options = new osgDB::Options;
_cacheSettings = new CacheSettings;
_cacheSettings->setCache(Registry::instance()->getDefaultCache());
_cacheSettings->store(_options.get());
}

CesiumAsync::Future<std::shared_ptr<CesiumAsync::IAssetRequest>>
AssetAccessor::get(const CesiumAsync::AsyncSystem& asyncSystem,
const std::string& url,
const std::vector<CesiumAsync::IAssetAccessor::THeader>& headers)
{
osg::ref_ptr<osgDB::Options> options = _options.get();
auto request = std::make_shared<AssetRequest>("GET", url, headers);
return asyncSystem.createFuture<std::shared_ptr<CesiumAsync::IAssetRequest>>(
[&](const auto& promise)
{
asyncSystem.runInWorkerThread([promise, request, url, headers]() {
asyncSystem.runInWorkerThread([promise, request, url, headers, options]() {
// This should run in another thread.
URIContext uriContext;
for (auto header : headers)
{
uriContext.addHeader(header.first, header.second);
}

URI uri(url, uriContext);
auto httpResponse = uri.readString();

auto httpResponse = uri.readString(options.get());
std::unique_ptr< AssetResponse > response = std::make_unique< AssetResponse >();

if (httpResponse.code() == ReadResult::RESULT_OK)
Expand Down
12 changes: 10 additions & 2 deletions src/osgEarthCesium/CesiumLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "CesiumLayer"
#include "Settings"

#include <osgEarth/Registry>

Expand Down Expand Up @@ -80,14 +81,21 @@ CesiumNative3DTilesLayer::openImplementation()

osg::ref_ptr< osgDB::Options > readOptions = osgEarth::Registry::instance()->cloneOrCreateOptions(this->getReadOptions());

std::string token = options().token().get();
if (token.empty())
{
token = getCesiumIonKey();

}

if (_options->url().isSet())
{
std::vector<int> overlays;
if (_options->rasterOverlay().isSet())
{
overlays.push_back(*_options->rasterOverlay());
}
_tilesetNode = new CesiumTilesetNode(_options->url()->full(), *_options->maximumScreenSpaceError(), overlays);
_tilesetNode = new CesiumTilesetNode(_options->url()->full(), token, *_options->maximumScreenSpaceError(), overlays);
}
else if (_options->assetId().isSet())
{
Expand All @@ -96,7 +104,7 @@ CesiumNative3DTilesLayer::openImplementation()
{
overlays.push_back(*_options->rasterOverlay());
}
_tilesetNode = new CesiumTilesetNode(*_options->assetId(), *_options->maximumScreenSpaceError(), overlays);
_tilesetNode = new CesiumTilesetNode(*_options->assetId(), token, *_options->maximumScreenSpaceError(), overlays);
}

if (!_tilesetNode.valid())
Expand Down
4 changes: 2 additions & 2 deletions src/osgEarthCesium/CesiumTilesetNode
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ namespace osgEarth { namespace Cesium
class OSGEARTHCESIUM_EXPORT CesiumTilesetNode : public osg::Group
{
public:
CesiumTilesetNode(unsigned int assetID, float maximumScreenSpaceError = 16.0f, std::vector<int> overlays = std::vector<int>());
CesiumTilesetNode(const std::string& url, float maximumScreenSpaceError = 16.0f, std::vector<int> overlays = std::vector<int>());
CesiumTilesetNode(unsigned int assetID, const std::string& token = "", float maximumScreenSpaceError = 16.0f, std::vector<int> overlays = std::vector<int>());
CesiumTilesetNode(const std::string& url, const std::string& token = "", float maximumScreenSpaceError = 16.0f, std::vector<int> overlays = std::vector<int>());

~CesiumTilesetNode();

Expand Down
10 changes: 5 additions & 5 deletions src/osgEarthCesium/CesiumTilesetNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

using namespace osgEarth::Cesium;

CesiumTilesetNode::CesiumTilesetNode(unsigned int assetID, float maximumScreenSpaceError, std::vector<int> overlays)
CesiumTilesetNode::CesiumTilesetNode(unsigned int assetID, const std::string& token, float maximumScreenSpaceError, std::vector<int> overlays)
{
Cesium3DTilesSelection::TilesetExternals externals{
Context::instance().assetAccessor, Context::instance().prepareRenderResources, Context::instance().asyncSystem, Context::instance().creditSystem, Context::instance().logger, nullptr
Expand All @@ -39,20 +39,20 @@ CesiumTilesetNode::CesiumTilesetNode(unsigned int assetID, float maximumScreenSp
options.forbidHoles = true;
options.enableOcclusionCulling = false;
options.maximumScreenSpaceError = maximumScreenSpaceError;
Cesium3DTilesSelection::Tileset* tileset = new Cesium3DTilesSelection::Tileset(externals, assetID, getCesiumIonKey(), options);
Cesium3DTilesSelection::Tileset* tileset = new Cesium3DTilesSelection::Tileset(externals, assetID, token, options);

for (auto& overlay = overlays.begin(); overlay != overlays.end(); ++overlay)
{
Cesium3DTilesSelection::RasterOverlayOptions rasterOptions;
const auto ionRasterOverlay = new Cesium3DTilesSelection::IonRasterOverlay("", *overlay, getCesiumIonKey(), rasterOptions);
const auto ionRasterOverlay = new Cesium3DTilesSelection::IonRasterOverlay("", *overlay, token, rasterOptions);
tileset->getOverlays().add(ionRasterOverlay);
}
_tileset = tileset;

setCullingActive(false);
}

CesiumTilesetNode::CesiumTilesetNode(const std::string& url, float maximumScreenSpaceError, std::vector<int> overlays)
CesiumTilesetNode::CesiumTilesetNode(const std::string& url, const std::string& token, float maximumScreenSpaceError, std::vector<int> overlays)
{
Cesium3DTilesSelection::TilesetExternals externals{
Context::instance().assetAccessor, Context::instance().prepareRenderResources, Context::instance().asyncSystem, Context::instance().creditSystem, Context::instance().logger, nullptr
Expand All @@ -66,7 +66,7 @@ CesiumTilesetNode::CesiumTilesetNode(const std::string& url, float maximumScreen
for (auto& overlay = overlays.begin(); overlay != overlays.end(); ++overlay)
{
Cesium3DTilesSelection::RasterOverlayOptions rasterOptions;
const auto ionRasterOverlay = new Cesium3DTilesSelection::IonRasterOverlay("", *overlay, getCesiumIonKey(), rasterOptions);
const auto ionRasterOverlay = new Cesium3DTilesSelection::IonRasterOverlay("", *overlay, token, rasterOptions);
tileset->getOverlays().add(ionRasterOverlay);
}
_tileset = tileset;
Expand Down
10 changes: 8 additions & 2 deletions src/osgEarthCesium/PrepareRenderResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <osgEarth/Notify>
#include <osgEarth/Registry>
#include <osg/MatrixTransform>
#include <osgUtil/SmoothingVisitor>
#include <glm/gtc/type_ptr.hpp>

using namespace osgEarth::Cesium;
Expand Down Expand Up @@ -467,6 +468,13 @@ class NodeBuilder
geom->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
}

// Generate normals automatically if we're not given any in the file itself.
if (!geom->getNormalArray())
{
osgUtil::SmoothingVisitor sv;
geode->accept(sv);
}


if (primitive.indices >= 0)
{
Expand Down Expand Up @@ -766,6 +774,4 @@ void PrepareRendererResources::detachRasterInMainThread(
const Cesium3DTilesSelection::RasterOverlayTile& rasterTile,
void* pMainThreadRendererResources) noexcept
{
// TODO:
OE_NOTICE << "detachRasterInMainThread" << std::endl;
}

0 comments on commit 52e037e

Please sign in to comment.