185 lines
5.4 KiB
Plaintext
185 lines
5.4 KiB
Plaintext
|
/* -*-c++-*- */
|
||
|
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||
|
* Copyright 2020 Pelican Mapping
|
||
|
* http://osgearth.org
|
||
|
*
|
||
|
* osgEarth is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||
|
* the Free Software Foundation; either version 2 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||
|
*/
|
||
|
|
||
|
#ifndef OSGEARTH_PATCH_LAYER_H
|
||
|
#define OSGEARTH_PATCH_LAYER_H 1
|
||
|
|
||
|
#include <osgEarth/VisibleLayer>
|
||
|
#include <osgEarth/TerrainTileNode>
|
||
|
#include <osg/RenderInfo>
|
||
|
#include <osg/Texture>
|
||
|
|
||
|
namespace osgEarth
|
||
|
{
|
||
|
class TileBatch;
|
||
|
class TileRenderer;
|
||
|
|
||
|
/**
|
||
|
* PatchLayer is a layer that can render terrain tiles using either
|
||
|
* a geometry shader patch (GL_PATCHES) or a custom draw callback.
|
||
|
*/
|
||
|
class OSGEARTH_EXPORT PatchLayer : public VisibleLayer
|
||
|
{
|
||
|
public: // serialization
|
||
|
class OSGEARTH_EXPORT Options : public VisibleLayer::Options {
|
||
|
public:
|
||
|
META_LayerOptions(osgEarth, Options, VisibleLayer::Options);
|
||
|
virtual Config getConfig() const;
|
||
|
private:
|
||
|
void fromConfig(const Config& conf);
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
META_Layer(osgEarth, PatchLayer, Options, VisibleLayer, Patch);
|
||
|
|
||
|
//! API providing access to patch geometry
|
||
|
class OSGEARTH_EXPORT TileInfoProvider
|
||
|
{
|
||
|
public:
|
||
|
//! Bounding box of the actual tile geometry (could be cropped by a mask)
|
||
|
virtual const osg::BoundingBox& getGeomBoundingBox() const = 0;
|
||
|
|
||
|
//! Bounding box of the full tile
|
||
|
virtual const osg::BoundingBox& getTileBoundingBox() const = 0;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Callback that the terrain engine will call to decide whether to
|
||
|
* render a tile in this layer.
|
||
|
*/
|
||
|
struct AcceptCallback : public osg::Referenced
|
||
|
{
|
||
|
/** Whether to accept the entire layer. Invoked during Cull. */
|
||
|
virtual bool acceptLayer(osg::NodeVisitor& nv, const osg::Camera* camera) const { return true; }
|
||
|
|
||
|
/** Whether to accept a specific tile. Invoked during Cull. */
|
||
|
virtual bool acceptKey(const TileKey& key) const { return true; }
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
|
||
|
//! Static bounding box buffer that the culling engine will use to
|
||
|
//! expand the corresponding terrain tile's axis-asligned bbox
|
||
|
//! during culling. This is necessary to account for the geometry that
|
||
|
//! may exist in the patch tile before it gets created.
|
||
|
const osg::BoundingBox& getBuffer() {
|
||
|
return _buffer;
|
||
|
}
|
||
|
|
||
|
virtual void cull(
|
||
|
const TileKey& key,
|
||
|
osg::NodeVisitor& nv) const { }
|
||
|
|
||
|
virtual void cull(
|
||
|
const TileBatch& batch,
|
||
|
osg::NodeVisitor& nv) const { }
|
||
|
|
||
|
virtual void draw(
|
||
|
osg::RenderInfo& ri) const { }
|
||
|
|
||
|
virtual TileRenderer* getRenderer() const {
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
//! Callback that decides which tiles to accept for rendering
|
||
|
void setAcceptCallback(AcceptCallback* value) { _acceptCallback = value; }
|
||
|
AcceptCallback* getAcceptCallback() const { return _acceptCallback.get(); }
|
||
|
|
||
|
|
||
|
protected:
|
||
|
|
||
|
// default destructor
|
||
|
virtual ~PatchLayer() { }
|
||
|
|
||
|
//! post-ctor initialization, chain to super/subclasses.
|
||
|
virtual void init();
|
||
|
|
||
|
//! Culling buffer to account for layer geometry.
|
||
|
osg::BoundingBox _buffer = { 0,0,0,0,0,0 };
|
||
|
|
||
|
private:
|
||
|
osg::ref_ptr<AcceptCallback> _acceptCallback;
|
||
|
};
|
||
|
|
||
|
using PatchLayerVector = std::vector<osg::ref_ptr<PatchLayer>>;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Interface for a patchlayer to access information and state
|
||
|
* about a terrain tile
|
||
|
*/
|
||
|
class TileState
|
||
|
{
|
||
|
public:
|
||
|
virtual const TileKey& getKey() const = 0;
|
||
|
|
||
|
virtual int getRevision() const = 0;
|
||
|
|
||
|
virtual const osg::BoundingBox& getBBox() const = 0;
|
||
|
|
||
|
virtual const osg::Matrix& getModelViewMatrix() const = 0;
|
||
|
|
||
|
virtual const osg::Matrix& getLocalToWorld() const = 0;
|
||
|
|
||
|
virtual int getSequence() const = 0;
|
||
|
|
||
|
virtual float getMorphStartRange() const = 0;
|
||
|
|
||
|
virtual float getMorphEndRange() const = 0;
|
||
|
|
||
|
virtual bool apply(
|
||
|
osg::RenderInfo& ri,
|
||
|
void* implData) const = 0;
|
||
|
|
||
|
virtual void debug(
|
||
|
osg::RenderInfo& ri,
|
||
|
void* implData) const { }
|
||
|
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Collection of tiles for a patchlayer to render
|
||
|
*/
|
||
|
class TileBatch
|
||
|
{
|
||
|
public:
|
||
|
TileBatch(void* env) : _env(env) { }
|
||
|
|
||
|
const std::vector<const TileState*>& tiles() const { return _tiles; }
|
||
|
void* env() const { return _env; }
|
||
|
|
||
|
std::vector<const TileState*> _tiles;
|
||
|
void* _env;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Interface for rendering a tile batch (patchlayer)
|
||
|
*/
|
||
|
class TileRenderer
|
||
|
{
|
||
|
public:
|
||
|
virtual void draw(
|
||
|
osg::RenderInfo& ri,
|
||
|
const TileBatch& tiles) = 0;
|
||
|
};
|
||
|
|
||
|
} // namespace osgEarth
|
||
|
|
||
|
#endif // OSGEARTH_PATCH_LAYER_H
|