// Written by Curtis Olson, started December 1997.
// SSG-ified by Curtis Olson, February 2000.
//
-// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org
+// Copyright (C) 1997-2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the
-// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-// Boston, MA 02111-1307, USA.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#define _SG_SKY_HXX
-#ifndef __cplusplus
-# error This library requires C++
-#endif
-
-
-#include <plib/ssg.h> // plib include
-
#include <simgear/compiler.h>
+#include <simgear/math/sg_random.h>
#include <simgear/misc/sg_path.hxx>
+#include <simgear/props/props.hxx>
#include <vector>
-#include <simgear/sky/cloud.hxx>
-#include <simgear/sky/dome.hxx>
-#include <simgear/sky/moon.hxx>
-#include <simgear/sky/oursun.hxx>
-#include <simgear/sky/stars.hxx>
-
-SG_USING_STD(vector);
-
+#include <osg/ref_ptr>
+#include <osg/MatrixTransform>
+#include <osg/Node>
+
+#include <simgear/ephemeris/ephemeris.hxx>
+#include <simgear/math/SGMath.hxx>
+
+#include <simgear/scene/sky/cloud.hxx>
+#include <simgear/scene/sky/dome.hxx>
+#include <simgear/scene/sky/moon.hxx>
+#include <simgear/scene/sky/oursun.hxx>
+#include <simgear/scene/sky/stars.hxx>
+
+namespace simgear {
+class SGReaderWriterOptions;
+}
+
+struct SGSkyState
+{
+ SGVec3d pos; //!< View position in world Cartesian coordinates.
+ SGGeod pos_geod;
+ SGQuatd ori;
+ double spin; //!< An offset angle for orienting the sky effects with the
+ // sun position so sunset and sunrise effects look correct.
+ double gst; //!< GMT side real time.
+ double sun_dist; //!< the sun's distance from the current view point
+ // (to keep it inside your view volume).
+ double moon_dist;//!< The moon's distance from the current view point.
+ double sun_angle;
+};
-typedef vector < SGCloudLayer* > layer_list_type;
-typedef layer_list_type::iterator layer_list_iterator;
-typedef layer_list_type::const_iterator layer_list_const_iterator;
+struct SGSkyColor
+{
+ SGVec3f sky_color;
+ SGVec3f adj_sky_color;
+ SGVec3f fog_color;
+ SGVec3f cloud_color;
+ double sun_angle,
+ moon_angle;
+};
/**
+ * \anchor SGSky-details
+ *
* A class to model a realistic (time/date/position) based sky.
*
- * Introduction
+ * Introduction
*
* The SGSky class models a blended sky dome, a haloed sun, a textured
* moon with phase that properly matches the date, stars and planets,
* texture_path() method.
* The arguments you pass to the build() method allow you to specify
- * the size of your sun sphere and moon sphere, a number of planets,
- * and a multitude of stars. For the planets and stars you pass in an
- * array of right ascensions, declinations, magnitudes, and the
- * distance from the view point.
+ * the horizontal and vertical radiuses of the sky dome, the size of
+ * your sun sphere and moon sphere, a number of planets, and a
+ * multitude of stars. For the planets and stars you pass in an array
+ * of right ascensions, declinations, and magnitudes.
* Cloud Layers
* Rendering the Sky
- * The sky is designed to be rendered in two stages. The first stage
+ * The sky is designed to be rendered in three stages. The first stage
* renders the parts that form your back drop - the sky dome, the
* stars and planets, the sun, and the moon. These should be rendered
* before the rest of your scene by calling the preDraw() method. The
- * second stage renders the clouds which are likely to be translucent
- * (depending on type) and should be drawn after your scene has been
- * rendered. Use the postDraw() method to draw the second stage of
- * the sky.
+ * second stage renders the clouds that are above the viewer. This stage
+ * is done before translucent objects in the main scene are drawn. It
+ * is seperated from the preDraw routine to enable to implement a
+ * multi passes technique and is located in the drawUpperClouds() method.
+ * The third stage renders the clouds that are below the viewer an which
+ * are likely to be translucent (depending on type) and should be drawn
+ * after your scene has been rendered. Use the drawLowerClouds() method
+ * to draw the second stage of the sky.
* A typical application might do the following:
- * <li> thesky->preDraw();
- * <li> ssgCullAndDraw ( myscene ) ;
- * <li> thesky->postDraw( my_altitude );
+ * \li thesky->preDraw( my_altitude );
+ * \li thesky->drawUpperClouds();
+ * \li ssgCullAndDraw ( myscene ) ;
+ * \li thesky->drawLowerClouds();
- * The current altitude in meters is passed to the postDraw() method
+ * The current altitude in meters is passed to the preDraw() method
* so the clouds layers can be rendered correction from most distant
* to closest.
class SGSky {
private:
+ typedef std::vector<SGSharedPtr<SGCloudLayer> > layer_list_type;
+ typedef layer_list_type::iterator layer_list_iterator;
+ typedef layer_list_type::const_iterator layer_list_const_iterator;
// components of the sky
- SGSkyDome *dome;
- SGSun *oursun;
- SGMoon *moon;
- SGStars *planets;
- SGStars *stars;
+ SGSharedPtr<SGSkyDome> dome;
+ SGSharedPtr<SGSun> oursun;
+ SGSharedPtr<SGMoon> moon;
+ SGSharedPtr<SGStars> planets;
+ SGSharedPtr<SGStars> stars;
layer_list_type cloud_layers;
- ssgRoot *pre_root, *post_root;
+ osg::ref_ptr<osg::Group> pre_root, pre_transform;
+ osg::ref_ptr<osg::Switch> cloud_root;
- ssgSelector *pre_selector, *post_selector;
- ssgTransform *pre_transform, *post_transform;
+ osg::ref_ptr<osg::MatrixTransform> _ephTransform;
SGPath tex_path;
float visibility;
float effective_visibility;
+ int in_cloud;
+
// near cloud visibility state variables
bool in_puff;
double puff_length; // in seconds
double ramp_up; // in seconds
double ramp_down; // in seconds
+ // 3D clouds enabled
+ bool clouds_3d_enabled;
+
+ // 3D cloud density
+ double clouds_3d_density;
+
+ // RNG seed
+ mt seed;
+
public:
/** Constructor */
/**
* Initialize the sky and connect the components to the scene
- * graph at the provided branch. See discussion in detailed class
- * description.
- * @param sun_size size of sun
- * @param moon_size size of moon
- * @param nplanets number of planets
- * @param planet_data an array of planet right ascensions, declinations,
- * and magnitudes
- * @param planet_dist distance from viewer to put the planets
- * @param nstars number of stars
- * @param star_data an array of star right ascensions, declinations,
- * and magnitudes
- * @param star_dist distance from viewer to put the stars */
- void build( double sun_size, double moon_size,
- int nplanets, sgdVec3 *planet_data, double planet_dist,
- int nstars, sgdVec3 *star_data, double star_dist );
+ * graph at the provided branch.
+ *
+ * @note See discussion in \ref SGSky-details "detailed class description".
+ *
+ * @param h_radius_m Horizontal radius of sky dome
+ * @param v_radius_m Vertical radius of sky dome
+ * @param sun_size Size of sun
+ * @param moon_size Size of moon
+ * @param eph Current positions of planets and stars
+ * @param node Property node connecting sun with environment
+ * @param options
+ */
+ void build( double h_radius_m,
+ double v_radius_m,
+ double sun_size,
+ double moon_size,
+ const SGEphemeris& eph,
+ SGPropertyNode *node,
+ simgear::SGReaderWriterOptions* options );
/**
- * Repaint the sky components based on current value of sun_angle,
- * sky, and fog colors. You can also specify new star and planet
- * data so that we can optionally change the magnitude of these
- * (for day/night transitions.) See discussion in detailed
- * class description.
+ * Repaint the sky components based on current sun angle, and sky and fog
+ * colors.
+ *
+ * @note See discussion in \ref SGSky-details "detailed class description".
*
- * Sun and moon angles are specified in degrees relative to local up
- * <li> 0 degrees = high noon
- * <li> 90 degrees = sun rise/set
- * <li> 180 degrees = darkest midnight
- * @param sky_color the base sky color (for the top of the dome)
- * @param fog_color the fog color (for the horizon)
- * @param sun_angle the sun angle with the horizon (for sunrise/sunset
- * effects)
- * @param moon_angle the moon angle (so we can make it more yellow
- * at the horizon)
- * @param nplanets number of planets
- * @param planet_data an array of planet right ascensions, declinations,
- * and magnitudes
- * @param nstars number of stars
- * @param star_data an array of star right ascensions, declinations,
- * and magnitudes
+ * @param sky_color The base sky color (for the top of the dome)
+ * @param eph Current positions of planets and stars
*/
- bool repaint( sgVec4 sky_color, sgVec4 fog_color,
- double sun_angle, double moon_angle,
- int nplanets, sgdVec3 *planet_data,
- int nstars, sgdVec3 *star_data );
+ bool repaint( const SGSkyColor &sky_color,
+ const SGEphemeris& eph );
/**
- * Reposition the sky at the specified origin and orientation
+ * Reposition the sky at the specified origin and orientation.
+ *
+ * @note See discussion in \ref SGSky-details "detailed class description".
*
- * lon specifies a rotation about the Z axis
- * lat specifies a rotation about the new Y axis
- * spin specifies a rotation about the new Z axis (this allows
- * additional orientation for the sunrise/set effects and is used
- * by the skydome and perhaps clouds. See discussion in detailed
- * class description.
- * @param view_pos specify your view position in world Cartesian
- * coordinates
- * @param zero_elev the zero elevation position in world Cartesian
- * coordinates
- * @param view_up the up vector in world Cartesian coordinates
- * @param lon current longitude
- * @param lat current latitude
- * @param alt current altitude
- * @param spin an offset angle for orienting the sky effects with the
- * sun position so sunset and sunrise effects look correct.
- * @param gst GMT side real time
- * @param sun_ra the sun's current right ascension
- * @param sun_dec the sun's current declination
- * @param sun_dist the sun's distance from the current view point
- * (to keep it inside your view volume.)
- * @param moon_ra the moon's current right ascension
- * @param moon_dec the moon's current declination
- * @param moon_dist the moon's distance from the current view point.
*/
- bool reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up,
- double lon, double lat, double alt, double spin,
- double gst,
- double sun_ra, double sun_dec, double sun_dist,
- double moon_ra, double moon_dec, double moon_dist );
+ bool reposition( const SGSkyState& sky_state,
+ const SGEphemeris& eph,
+ double dt = 0.0 );
/**
* Modify the given visibility based on cloud layers, thickness,
- * transition range, and simulated "puffs". See discussion in detailed
- * class description.
+ * transition range, and simulated "puffs".
+ *
+ * @note See discussion in \ref SGSky-details "detailed class description".
+ *
* @param alt current altitude
* @param time_factor amount of time since modify_vis() last called so
* we can scale effect rates properly despite variable frame rates.
*/
void modify_vis( float alt, float time_factor );
- /**
- * Draw background portions of the sky ... do this before you draw
- * the rest of your scene. See discussion in detailed
- * class description.
- */
- void preDraw();
-
- /**
- * Draw translucent clouds ... do this after you've drawn all the
- * oapaque elements of your scene. See discussion in detailed
- * class description.
- * @param alt current altitude
- */
- void postDraw( float alt );
+ osg::Group* getPreRoot() { return pre_root.get(); }
+ osg::Group* getCloudRoot() { return cloud_root.get(); }
/**
* Specify the texture path (optional, defaults to current directory)
- * @param path base path to texture locations
+ *
+ * @param path Base path to texture locations
*/
- inline void texture_path( const string& path ) {
- tex_path = SGPath( path );
- }
-
- /** Enable drawing of the sky. */
- inline void enable() {
- pre_selector->select( 1 );
- post_selector->select( 1 );
- }
+ void texture_path( const std::string& path );
/**
- * Disable drawing of the sky in the scene graph. The leaf node is still
- * there, how ever it won't be traversed on by ssgCullandRender()
+ * Get the current sun color
*/
- inline void disable() {
- pre_selector->select( 0 );
- post_selector->select( 0 );
- }
-
+ inline SGVec4f get_sun_color() { return oursun->get_color(); }
/**
- * Get the current sun color
+ * Get the current scene color
*/
- inline float *get_sun_color() { return oursun->get_color(); }
-
+ inline SGVec4f get_scene_color() { return oursun->get_scene_color(); }
/**
* Add a cloud layer.
/** @return current effective visibility */
- inline float get_visibility() const { return effective_visibility; }
+ float get_visibility() const { return effective_visibility; }
/** Set desired clear air visibility.
* @param v visibility in meters
*/
- inline void set_visibility( float v ) {
- effective_visibility = visibility = v;
- }
-};
+ void set_visibility( float v );
+
+ /** Get 3D cloud density */
+ double get_3dCloudDensity() const;
+
+ /** Set 3D cloud density
+ * @param density 3D cloud density
+ */
+ void set_3dCloudDensity(double density);
+
+ /** Get 3D cloud visibility range*/
+ float get_3dCloudVisRange() const;
+
+ /** Set 3D cloud visibility range
+ *
+ * @param vis 3D cloud visibility range
+ */
+ void set_3dCloudVisRange(float vis);
+
+ /** Get 3D cloud impostor distance*/
+ float get_3dCloudImpostorDistance() const;
+
+ /** Set 3D cloud impostor distance
+ *
+ * @param vis 3D cloud impostor distance
+ */
+ void set_3dCloudImpostorDistance(float vis);
+ /** Get 3D cloud LoD1 Range*/
+ float get_3dCloudLoD1Range() const;
+ /** Set 3D cloud LoD1 Range
+ * @param vis LoD1 Range
+ */
+ void set_3dCloudLoD1Range(float vis);
+
+ /** Get 3D cloud LoD2 Range*/
+ float get_3dCloudLoD2Range() const;
+
+ /** Set 3D cloud LoD2 Range
+ * @param vis LoD2 Range
+ */
+ void set_3dCloudLoD2Range(float vis);
+
+ /** Get 3D cloud impostor usage */
+ bool get_3dCloudUseImpostors() const;
+
+ /** Set 3D cloud impostor usage
+ *
+ * @param imp whether use impostors for 3D clouds
+ */
+ void set_3dCloudUseImpostors(bool imp);
+
+ /** Get 3D cloud wrapping */
+ bool get_3dCloudWrap() const;
+
+ /** Set 3D cloud wrapping
+ * @param wrap whether to wrap 3D clouds
+ */
+ void set_3dCloudWrap(bool wrap);
+
+ void set_clouds_enabled(bool enabled);
+
+};
#endif // _SG_SKY_HXX