#include "cloudfield.hxx"
#include "newcloud.hxx"
-#include <simgear/math/sg_random.h>
#include <simgear/scene/util/RenderConstants.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
+#include <simgear/sg_inlines.h>
#include <osg/StateSet>
#include <osg/Depth>
preStateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0.0, 1.0,
false));
pre_root->setStateSet(preStateSet);
- cloud_root = new osg::Group;
+ cloud_root = new osg::Switch;
cloud_root->setNodeMask(simgear::MODEL_BIT);
-
- pre_selector = new osg::Switch;
+ cloud_root->setName("SGSky-cloud-root");
pre_transform = new osg::Group;
-
_ephTransform = new osg::MatrixTransform;
+
+ // Set up a RNG that is repeatable within 10 minutes to ensure that clouds
+ // are synced up in multi-process deployments.
+ mt_init_time_10(&seed);
}
// initialize the sky and connect the components to the scene graph at
// the provided branch
-void SGSky::build( double h_radius_m, double v_radius_m,
- double sun_size, double moon_size,
- const SGEphemeris& eph, SGPropertyNode *property_tree_node )
+void SGSky::build( double h_radius_m,
+ double v_radius_m,
+ double sun_size,
+ double moon_size,
+ const SGEphemeris& eph,
+ SGPropertyNode *property_tree_node,
+ simgear::SGReaderWriterOptions* options )
{
dome = new SGSkyDome;
- pre_transform->addChild( dome->build( h_radius_m, v_radius_m ) );
+ pre_transform->addChild( dome->build( h_radius_m, v_radius_m, options ) );
pre_transform->addChild(_ephTransform.get());
planets = new SGStars;
oursun = new SGSun;
_ephTransform->addChild( oursun->build(tex_path, sun_size, property_tree_node ) );
- pre_selector->addChild( pre_transform.get() );
-
- pre_root->addChild( pre_selector.get() );
+ pre_root->addChild( pre_transform.get() );
}
// 180 degrees = darkest midnight
bool SGSky::repaint( const SGSkyColor &sc, const SGEphemeris& eph )
{
- if ( effective_visibility > 1000.0 ) {
- enable();
dome->repaint( sc.adj_sky_color, sc.sky_color, sc.fog_color,
sc.sun_angle, effective_visibility );
cloud_layers[i]->repaint( sc.cloud_color );
}
}
- } else {
- // turn off sky
- disable();
- }
+
SGCloudField::updateFog((double)effective_visibility,
osg::Vec4f(toOsg(sc.fog_color), 1.0f));
return true;
SGGeod geodZeroViewPos = SGGeod::fromGeodM(st.pos_geod, 0);
zero_elev = toVec3f( SGVec3d::fromGeod(geodZeroViewPos) );
- view_up = toVec3f( st.ori.backTransform(SGVec3d::e2()) );
+
+ // calculate the scenery up vector
+ SGQuatd hlOr = SGQuatd::fromLonLat(st.pos_geod);
+ view_up = toVec3f(hlOr.backTransform(-SGVec3d::e3()));
+
+ // viewer location
lon = st.pos_geod.getLongitudeRad();
lat = st.pos_geod.getLatitudeRad();
alt = st.pos_geod.getElevationM();
moon->reposition( moon_ra, moon_dec, st.moon_dist );
for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
- if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ) {
+ if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ||
+ cloud_layers[i]->get_layer3D()->isDefined3D() ) {
cloud_layers[i]->reposition( zero_elev, view_up, lon, lat, alt, dt);
- } else
+ } else {
cloud_layers[i]->getNode()->setAllChildrenOff();
}
+ }
return true;
}
+void
+SGSky::set_visibility( float v )
+{
+ visibility = std::max(v, 25.0f);
+}
+
void
SGSky::add_cloud_layer( SGCloudLayer * layer )
{
cloud_layers.push_back(layer);
- cloud_root->addChild(layer->getNode());
+ cloud_root->addChild(layer->getNode(), true);
layer->set_enable3dClouds(clouds_3d_enabled);
}
{
SGCloudField::setVisRange(vis);
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
- cloud_layers[i]->get_layer3D()->applyVisRange();
+ cloud_layers[i]->get_layer3D()->applyVisAndLoDRange();
+ }
+}
+
+float SGSky::get_3dCloudImpostorDistance() const {
+ return SGCloudField::getImpostorDistance();
+}
+
+void SGSky::set_3dCloudImpostorDistance(float vis)
+{
+ SGCloudField::setImpostorDistance(vis);
+ for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
+ cloud_layers[i]->get_layer3D()->applyVisAndLoDRange();
+ }
+}
+
+float SGSky::get_3dCloudLoD1Range() const {
+ return SGCloudField::getLoD1Range();
+}
+
+void SGSky::set_3dCloudLoD1Range(float vis)
+{
+ SGCloudField::setLoD1Range(vis);
+ for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
+ cloud_layers[i]->get_layer3D()->applyVisAndLoDRange();
}
}
-void SGSky::texture_path( const string& path ) {
+float SGSky::get_3dCloudLoD2Range() const {
+ return SGCloudField::getLoD2Range();
+}
+
+void SGSky::set_3dCloudLoD2Range(float vis)
+{
+ SGCloudField::setLoD2Range(vis);
+ for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
+ cloud_layers[i]->get_layer3D()->applyVisAndLoDRange();
+ }
+}
+
+bool SGSky::get_3dCloudWrap() const {
+ return SGCloudField::getWrap();
+}
+
+void SGSky::set_3dCloudWrap(bool wrap)
+{
+ SGCloudField::setWrap(wrap);
+}
+
+bool SGSky::get_3dCloudUseImpostors() const {
+ return SGCloudField::getUseImpostors();
+}
+
+void SGSky::set_3dCloudUseImpostors(bool imp)
+{
+ SGCloudField::setUseImpostors(imp);
+}
+
+void SGSky::texture_path( const std::string& path ) {
tex_path = SGPath( path );
}
}
if ( cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_CLEAR ||
- cloud_layers[i]->get_layer3D()->defined3D) {
+ cloud_layers[i]->get_layer3D()->isDefined3D()) {
// do nothing, clear layers aren't drawn, don't affect
// visibility andn dont' need to be faded in or out.
} else if ( (cloud_layers[i]->getCoverage() ==
if ( ratio < 1.0 ) {
if ( ! in_puff ) {
// calc chance of entering cloud puff
- double rnd = sg_random();
+ double rnd = mt_rand(&seed);
double chance = rnd * rnd * rnd;
if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) {
in_puff = true;
- puff_length = sg_random() * 2.0; // up to 2 seconds
+ puff_length = mt_rand(&seed) * 2.0; // up to 2 seconds
puff_progression = 0.0;
}
}
}
#endif
- // never let visibility drop below 25 meters
- if ( effvis <= 25.0 ) {
- effvis = 25.0;
- }
+ // never let visibility drop below the layer's configured visibility
+ effvis = SG_MAX2<float>(cloud_layers[i]->getVisibility_m(), effvis );
} // for
effective_visibility = effvis;
}
-
+void SGSky::set_clouds_enabled(bool enabled)
+{
+ if (enabled) {
+ cloud_root->setAllChildrenOn();
+ } else {
+ cloud_root->setAllChildrenOff();
+ }
+}