274 lines
9.2 KiB
Plaintext
274 lines
9.2 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.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||
|
* IN THE SOFTWARE.
|
||
|
*
|
||
|
* 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 OSGEARTHUTIL_SKY
|
||
|
#define OSGEARTHUTIL_SKY
|
||
|
|
||
|
#include <osgEarth/Common>
|
||
|
#include <osgEarth/Ephemeris>
|
||
|
#include <osgEarth/DateTime>
|
||
|
#include <osgEarth/GeoData>
|
||
|
#include <osgEarth/Config>
|
||
|
#include <osgEarth/SpatialReference>
|
||
|
#include <osg/Group>
|
||
|
#include <osg/Uniform>
|
||
|
#include <osg/View>
|
||
|
#include <osg/ArgumentParser>
|
||
|
#include <osgDB/ReaderWriter>
|
||
|
|
||
|
namespace osgDB {
|
||
|
class Options;
|
||
|
}
|
||
|
|
||
|
namespace osgEarth
|
||
|
{
|
||
|
/**
|
||
|
* Base Options structure for loading an environment node from
|
||
|
* a plugin.
|
||
|
*/
|
||
|
class SkyOptions : public DriverConfigOptions
|
||
|
{
|
||
|
public:
|
||
|
enum CoordinateSystem
|
||
|
{
|
||
|
COORDSYS_ECEF,
|
||
|
COORDSYS_ECI
|
||
|
};
|
||
|
|
||
|
enum Quality
|
||
|
{
|
||
|
QUALITY_UNSET,
|
||
|
QUALITY_DEFAULT,
|
||
|
QUALITY_LOW,
|
||
|
QUALITY_MEDIUM,
|
||
|
QUALITY_HIGH,
|
||
|
QUALITY_BEST
|
||
|
};
|
||
|
|
||
|
static Quality parseQuality(osg::ArgumentParser& args) {
|
||
|
return
|
||
|
args.read("--sky") ? QUALITY_DEFAULT :
|
||
|
args.read("--sky-low") ? QUALITY_LOW :
|
||
|
args.read("--sky-medium") ? QUALITY_MEDIUM :
|
||
|
args.read("--sky-high") ? QUALITY_HIGH :
|
||
|
args.read("--sky-best") ? QUALITY_BEST :
|
||
|
QUALITY_UNSET;
|
||
|
}
|
||
|
|
||
|
//! Coordinate system for whole-earth maps (default = ECEF)
|
||
|
OE_OPTION(CoordinateSystem, coordinateSystem);
|
||
|
|
||
|
/** Time of day - Hours [0..24] component of DateTime */
|
||
|
OE_OPTION(float, hours);
|
||
|
|
||
|
OE_OPTION(float, ambient);
|
||
|
OE_OPTION(Quality, quality);
|
||
|
|
||
|
public:
|
||
|
SkyOptions( const ConfigOptions& options =ConfigOptions() ) : DriverConfigOptions(options) {
|
||
|
coordinateSystem().setDefault(COORDSYS_ECEF);
|
||
|
quality().setDefault(QUALITY_DEFAULT);
|
||
|
ambient().setDefault(0.033f);
|
||
|
hours().setDefault(12.0f);
|
||
|
fromConfig(_conf);
|
||
|
}
|
||
|
virtual ~SkyOptions() { }
|
||
|
virtual Config getConfig() const {
|
||
|
Config conf = DriverConfigOptions::getConfig();
|
||
|
conf.set("coordsys", "ecef", coordinateSystem(), COORDSYS_ECEF);
|
||
|
conf.set("coordsys", "eci", coordinateSystem(), COORDSYS_ECI);
|
||
|
conf.set("hours", hours());
|
||
|
conf.set("ambient", ambient());
|
||
|
conf.set("quality", "default", quality(), QUALITY_DEFAULT);
|
||
|
conf.set("quality", "low", quality(), QUALITY_LOW);
|
||
|
conf.set("quality", "medium", quality(), QUALITY_MEDIUM);
|
||
|
conf.set("quality", "high", quality(), QUALITY_HIGH);
|
||
|
conf.set("quality", "best", quality(), QUALITY_BEST);
|
||
|
return conf;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void mergeConfig( const Config& conf ) {
|
||
|
ConfigOptions::mergeConfig( conf );
|
||
|
fromConfig( conf );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
void fromConfig( const Config& conf ) {
|
||
|
conf.get("coordsys", "ecef", coordinateSystem(), COORDSYS_ECEF);
|
||
|
conf.get("coordsys", "eci", coordinateSystem(), COORDSYS_ECI);
|
||
|
conf.get("hours", hours());
|
||
|
conf.get("ambient", ambient());
|
||
|
conf.get("quality", "default", quality(), QUALITY_DEFAULT);
|
||
|
conf.get("quality", "low", quality(), QUALITY_LOW);
|
||
|
conf.get("quality", "medium", quality(), QUALITY_MEDIUM);
|
||
|
conf.get("quality", "high", quality(), QUALITY_HIGH);
|
||
|
conf.get("quality", "best", quality(), QUALITY_BEST);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Interface for classes that provide sky, lighting, and other
|
||
|
* environmental effect.
|
||
|
*/
|
||
|
class OSGEARTH_EXPORT SkyNode : public osg::Group
|
||
|
{
|
||
|
public:
|
||
|
//! Creates a SkyNode with the default implementation.
|
||
|
static SkyNode* create();
|
||
|
|
||
|
//! Creates a SkyNode with custom options.
|
||
|
static SkyNode* create(const SkyOptions&);
|
||
|
|
||
|
//! Creates a SkyNode from a raw driver name.
|
||
|
static SkyNode* create(const std::string& driver);
|
||
|
|
||
|
protected:
|
||
|
// CTOR (abstract base class)
|
||
|
SkyNode();
|
||
|
|
||
|
// CTOR (abstract base class)
|
||
|
SkyNode(const SkyOptions& options);
|
||
|
|
||
|
// protected DTOR (heap-only)
|
||
|
virtual ~SkyNode();
|
||
|
|
||
|
public:
|
||
|
/**
|
||
|
* The ephemeris reference point for projected maps. Not applicable
|
||
|
* for geocentric maps. Setting this also informs the skynode that is
|
||
|
* should operate in projected-map mode if possible.
|
||
|
*/
|
||
|
void setReferencePoint(const GeoPoint& point);
|
||
|
const GeoPoint& getReferencePoint() const { return *_refpoint; }
|
||
|
|
||
|
/**
|
||
|
* Gets/Sets the Ephemeris used to position the sun and the moon
|
||
|
* based on date/time.
|
||
|
*/
|
||
|
void setEphemeris(Ephemeris* ephemeris);
|
||
|
const Ephemeris* getEphemeris() const;
|
||
|
|
||
|
/**
|
||
|
* Whether the sky lights its subgraph.
|
||
|
*/
|
||
|
void setLighting(osg::StateAttribute::OverrideValue value);
|
||
|
osg::StateAttribute::OverrideValue getLighting() const { return _lightingValue; }
|
||
|
|
||
|
/**
|
||
|
* Gets the date/time for which the environment is configured.
|
||
|
* Pass in an optional View to get the date/time specific to
|
||
|
* that View.
|
||
|
*/
|
||
|
void setDateTime(const DateTime& dt);
|
||
|
const DateTime& getDateTime() const { return _dateTime; }
|
||
|
|
||
|
//! Whether the traversal framestamp simulation time should
|
||
|
//! be set to the sky's date time. Default is false.
|
||
|
void setSimulationTimeTracksDateTime(bool value);
|
||
|
bool getSimulationTimeTracksDateTime() const;
|
||
|
|
||
|
/** Whether the sun is visible */
|
||
|
void setSunVisible(bool value);
|
||
|
bool getSunVisible() const { return _sunVisible; }
|
||
|
|
||
|
/** Whether the moon is visible */
|
||
|
void setMoonVisible(bool value);
|
||
|
bool getMoonVisible() const { return _moonVisible; }
|
||
|
|
||
|
/** Whether the stars are visible */
|
||
|
void setStarsVisible(bool value);
|
||
|
bool getStarsVisible() const { return _starsVisible; }
|
||
|
|
||
|
/** Whether the atmosphere is visible */
|
||
|
void setAtmosphereVisible(bool value);
|
||
|
bool getAtmosphereVisible() const { return _atmosphereVisible; }
|
||
|
|
||
|
/** Access the osg::Light representing the sun */
|
||
|
virtual osg::Light* getSunLight() const = 0;
|
||
|
|
||
|
public:
|
||
|
|
||
|
/** Attaches this sky node to a view (placing a sky light). Optional */
|
||
|
virtual void attach(osg::View* view, int lightNum) { }
|
||
|
void attach(osg::View* view) { attach(view, 0); }
|
||
|
|
||
|
public: // osg::Node
|
||
|
|
||
|
virtual void traverse(osg::NodeVisitor& nv) override;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
// impl class can override these events.
|
||
|
virtual void onSetEphemeris() { }
|
||
|
virtual void onSetDateTime() { }
|
||
|
virtual void onSetReferencePoint() { }
|
||
|
virtual void onSetMoonVisible() { }
|
||
|
virtual void onSetStarsVisible() { }
|
||
|
virtual void onSetSunVisible() { }
|
||
|
virtual void onSetAtmosphereVisible() { }
|
||
|
|
||
|
private:
|
||
|
|
||
|
osg::ref_ptr<Ephemeris> _ephemeris;
|
||
|
DateTime _dateTime;
|
||
|
bool _sunVisible;
|
||
|
bool _moonVisible;
|
||
|
bool _starsVisible;
|
||
|
bool _atmosphereVisible;
|
||
|
osg::Vec4f _minimumAmbient;
|
||
|
optional<GeoPoint> _refpoint;
|
||
|
bool _simTimeTracksDateTime;
|
||
|
|
||
|
osg::StateAttribute::OverrideValue _lightingValue;
|
||
|
osg::ref_ptr<osg::Uniform> _lightingUniform;
|
||
|
|
||
|
void baseInit(const SkyOptions&);
|
||
|
};
|
||
|
|
||
|
namespace Util
|
||
|
{
|
||
|
/**
|
||
|
* Base class for an sky driver plugin implementation.
|
||
|
*/
|
||
|
class OSGEARTH_EXPORT SkyDriver : public osgDB::ReaderWriter
|
||
|
{
|
||
|
protected:
|
||
|
const SkyOptions& getSkyOptions(const osgDB::Options* opt) const;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Factory interface that sky extensions need to implement. Someday we will
|
||
|
* convert the sky extensions into proper NodeKits, at which point this method
|
||
|
* will probably be no longer necessary since you can just link with the library
|
||
|
* and create the SkyNode normally.
|
||
|
*/
|
||
|
class /*header-only*/ SkyNodeFactory
|
||
|
{
|
||
|
public:
|
||
|
virtual SkyNode* createSkyNode() =0;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // OSGEARTHUTIL_SKY
|