DYT/Tool/OpenSceneGraph-3.6.5/include/osgEarth/Sky
2024-12-25 07:49:36 +08:00

274 lines
9.2 KiB
C++

/* -*-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