osgEarth 2.1.1
|
Classes | |
struct | PerViewData |
struct | StarData |
Public Member Functions | |
SkyNode (Map *map, const std::string &starFile="") | |
void | attach (osg::View *view, int lightNum=0) |
void | setSunPosition (const osg::Vec3 &pos, osg::View *view=0L) |
void | setSunPosition (double lat_degrees, double lon_degrees, osg::View *view=0L) |
void | setDateTime (int year, int month, int date, double hoursUTC, osg::View *view=0L) |
void | setAmbientBrightness (float value, osg::View *view=0L) |
float | getAmbientBrightness (osg::View *view=0L) const |
void | setStarsVisible (bool value, osg::View *view=0L) |
bool | getStarsVisible (osg::View *view=0L) const |
virtual void | traverse (osg::NodeVisitor &nv) |
virtual osg::BoundingSphere | computeBound () const |
Private Types | |
typedef std::map< osg::View *, PerViewData > | PerViewDataMap |
Private Member Functions | |
void | makeAtmosphere (const osg::EllipsoidModel *) |
void | makeSun () |
void | makeStars (const std::string &starFile) |
osg::Geode * | buildStarGeometry (const std::vector< StarData > &stars) |
void | getDefaultStars (std::vector< StarData > &out_stars) |
bool | parseStarFile (const std::string &starFile, std::vector< StarData > &out_stars) |
void | setAmbientBrightness (PerViewData &data, float value) |
void | setSunPosition (PerViewData &data, const osg::Vec3 &pos) |
Private Attributes | |
PerViewData | _defaultPerViewData |
PerViewDataMap | _perViewData |
float | _innerRadius |
float | _outerRadius |
float | _sunDistance |
float | _starRadius |
osg::ref_ptr< osg::Node > | _sun |
osg::ref_ptr< osg::Node > | _stars |
osg::ref_ptr< osg::Node > | _atmosphere |
osg::ref_ptr< osg::Uniform > | _starAlpha |
osg::ref_ptr< osg::Uniform > | _starPointSize |
osg::ref_ptr< const osg::EllipsoidModel > | _ellipsoidModel |
typedef std::map<osg::View*, PerViewData> osgEarth::Util::SkyNode::PerViewDataMap [private] |
SkyNode::SkyNode | ( | Map * | map, |
const std::string & | starFile = "" |
||
) |
Creates a new sky node based on the provided map.
Definition at line 583 of file SkyNode.cpp.
{ // intialize the default settings: _defaultPerViewData._lightPos.set( osg::Vec3f(0.0f, 1.0f, 0.0f) ); _defaultPerViewData._light = new osg::Light( 0 ); _defaultPerViewData._light->setPosition( osg::Vec4( _defaultPerViewData._lightPos, 0 ) ); _defaultPerViewData._light->setAmbient( osg::Vec4(0.4f, 0.4f, 0.4f ,1.0) ); _defaultPerViewData._light->setDiffuse( osg::Vec4(1,1,1,1) ); _defaultPerViewData._light->setSpecular( osg::Vec4(0,0,0,1) ); _defaultPerViewData._starsVisible = true; // set up the astronomical parameters: _ellipsoidModel = map->getProfile()->getSRS()->getGeographicSRS()->getEllipsoid(); _innerRadius = _ellipsoidModel->getRadiusPolar(); _outerRadius = _innerRadius * 1.025f; _sunDistance = _innerRadius * 12000.0f; // make the ephemeris (note: order is important here) makeAtmosphere( _ellipsoidModel.get() ); makeSun(); makeStars(starFile); }
void SkyNode::attach | ( | osg::View * | view, |
int | lightNum = 0 |
||
) |
Attached this sky node to a view (placing a sky light).
Definition at line 640 of file SkyNode.cpp.
{ if ( !view ) return; // creates the new per-view if it does not already exist PerViewData& data = _perViewData[view]; data._light = osg::clone( _defaultPerViewData._light.get() ); data._light->setLightNum( lightNum ); data._light->setAmbient( _defaultPerViewData._light->getAmbient() ); data._lightPos = _defaultPerViewData._lightPos; // the cull callback has to be on a parent group-- won't work on the xforms themselves. data._cullContainer = new osg::Group(); data._sunXform = new osg::MatrixTransform(); data._sunMatrix = osg::Matrixd::translate( _sunDistance * data._lightPos.x(), _sunDistance * data._lightPos.y(), _sunDistance * data._lightPos.z() ); data._sunXform->setMatrix( data._sunMatrix ); data._sunXform->addChild( _sun.get() ); data._cullContainer->addChild( data._sunXform.get() ); data._starsXform = new osg::MatrixTransform(); data._starsMatrix = _defaultPerViewData._starsMatrix; data._starsXform->setMatrix( _defaultPerViewData._starsMatrix ); data._starsXform->addChild( _stars.get() ); data._cullContainer->addChild( data._starsXform.get() ); data._starsVisible = true; data._cullContainer->addChild( _atmosphere.get() ); data._lightPosUniform = osg::clone( _defaultPerViewData._lightPosUniform.get() ); view->setLightingMode( osg::View::SKY_LIGHT ); view->setLight( data._light.get() ); view->getCamera()->setClearColor( osg::Vec4(0,0,0,1) ); }
osg::Geode * SkyNode::buildStarGeometry | ( | const std::vector< StarData > & | stars | ) | [private] |
Definition at line 989 of file SkyNode.cpp.
{ double minMag = DBL_MAX, maxMag = DBL_MIN; osg::Vec3Array* coords = new osg::Vec3Array(); std::vector<StarData>::const_iterator p; for( p = stars.begin(); p != stars.end(); p++ ) { osg::Vec3 v = osg::Vec3(0,_starRadius,0) * osg::Matrix::rotate( p->declination, 1, 0, 0 ) * osg::Matrix::rotate( p->right_ascension, 0, 0, 1 ); coords->push_back( v ); if ( p->magnitude < minMag ) minMag = p->magnitude; if ( p->magnitude > maxMag ) maxMag = p->magnitude; } osg::Vec4Array* colors = new osg::Vec4Array(); for( p = stars.begin(); p != stars.end(); p++ ) { //float c = 0.5f + 0.5f * ( (p->magnitude-minMag) / (maxMag-minMag) ); float c = ( (p->magnitude-minMag) / (maxMag-minMag) ); colors->push_back( osg::Vec4(c,c,c,1.0f) ); } osg::Geometry* geometry = new osg::Geometry; geometry->setUseVertexBufferObjects( true ); geometry->setVertexArray( coords ); geometry->setColorArray( colors ); geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, coords->size())); osg::StateSet* sset = new osg::StateSet; sset->setMode( GL_VERTEX_PROGRAM_POINT_SIZE, osg::StateAttribute::ON ); osg::Program* program = new osg::Program; program->addShader( new osg::Shader(osg::Shader::VERTEX, s_starVertexSource) ); program->addShader( new osg::Shader(osg::Shader::FRAGMENT, s_starFragmentSource) ); sset->setAttributeAndModes( program, osg::StateAttribute::ON ); sset->setRenderBinDetails( BIN_STARS, "RenderBin"); sset->setAttributeAndModes( new osg::Depth(osg::Depth::ALWAYS, 0, 1, false), osg::StateAttribute::ON ); geometry->setStateSet( sset ); osg::Geode* starGeode = new osg::Geode; starGeode->addDrawable( geometry ); return starGeode; }
osg::BoundingSphere SkyNode::computeBound | ( | ) | const [virtual] |
Definition at line 607 of file SkyNode.cpp.
{
return osg::BoundingSphere();
}
float SkyNode::getAmbientBrightness | ( | osg::View * | view = 0L | ) | const |
Definition at line 697 of file SkyNode.cpp.
{ if ( view ) { PerViewDataMap::const_iterator i = _perViewData.find(view); if ( i != _perViewData.end() ) return i->second._light->getAmbient().r(); } return _defaultPerViewData._light->getAmbient().r(); }
void SkyNode::getDefaultStars | ( | std::vector< StarData > & | out_stars | ) | [private] |
Definition at line 1041 of file SkyNode.cpp.
{ out_stars.clear(); for(const char **sptr = s_defaultStarData; *sptr; sptr++) { std::stringstream ss(*sptr); out_stars.push_back(StarData(ss)); } }
bool SkyNode::getStarsVisible | ( | osg::View * | view = 0L | ) | const |
Definition at line 820 of file SkyNode.cpp.
{ PerViewDataMap::const_iterator i = _perViewData.find(view); if ( !view || i == _perViewData.end() ) { return _defaultPerViewData._starsVisible; } else { return i->second._starsVisible; } }
void SkyNode::makeAtmosphere | ( | const osg::EllipsoidModel * | em | ) | [private] |
Definition at line 835 of file SkyNode.cpp.
{ // create some skeleton geometry to shade: osg::Geometry* drawable = s_makeEllipsoidGeometry( em, _outerRadius ); osg::Geode* geode = new osg::Geode(); geode->addDrawable( drawable ); osg::StateSet* set = geode->getOrCreateStateSet(); // configure the state set: set->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); set->setMode( GL_CULL_FACE, osg::StateAttribute::ON ); set->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); //set->setBinNumber( 65 ); // todo, what? set->setBinNumber( BIN_ATMOSPHERE ); set->setAttributeAndModes( new osg::Depth( osg::Depth::LESS, 0, 1, false ) ); // no depth write set->setAttributeAndModes( new osg::BlendFunc( GL_ONE, GL_ONE ), osg::StateAttribute::ON ); set->setAttributeAndModes( new osg::FrontFace( osg::FrontFace::CLOCKWISE ), osg::StateAttribute::ON ); // next, create and add the shaders: osg::Program* program = new osg::Program(); osg::Shader* vs = new osg::Shader( osg::Shader::VERTEX, s_atmosphereVertexSource ); program->addShader( vs ); osg::Shader* fs = new osg::Shader( osg::Shader::FRAGMENT, s_atmosphereFragmentSource ); program->addShader( fs ); set->setAttributeAndModes( program, osg::StateAttribute::ON ); // apply the uniforms: float r_wl = ::powf( .65f, 4.0f ); float g_wl = ::powf( .57f, 4.0f ); float b_wl = ::powf( .475f, 4.0f ); osg::Vec3 RGB_wl( 1.0f/r_wl, 1.0f/g_wl, 1.0f/b_wl ); float Kr = 0.0025f; float Kr4PI = Kr * 4.0f * osg::PI; float Km = 0.0015f; float Km4PI = Km * 4.0f * osg::PI; float ESun = 15.0f; float MPhase = -.095f; float RayleighScaleDepth = 0.25f; int Samples = 2; float Weather = 1.0f; float Scale = 1.0f / (_outerRadius - _innerRadius); _defaultPerViewData._lightPosUniform = set->getOrCreateUniform( "atmos_v3LightPos", osg::Uniform::FLOAT_VEC3 ); _defaultPerViewData._lightPosUniform->set( _defaultPerViewData._lightPos / _defaultPerViewData._lightPos.length() ); set->getOrCreateUniform( "atmos_v3InvWavelength", osg::Uniform::FLOAT_VEC3 )->set( RGB_wl ); set->getOrCreateUniform( "atmos_fInnerRadius", osg::Uniform::FLOAT )->set( _innerRadius ); set->getOrCreateUniform( "atmos_fInnerRadius2", osg::Uniform::FLOAT )->set( _innerRadius * _innerRadius ); set->getOrCreateUniform( "atmos_fOuterRadius", osg::Uniform::FLOAT )->set( _outerRadius ); set->getOrCreateUniform( "atmos_fOuterRadius2", osg::Uniform::FLOAT )->set( _outerRadius * _outerRadius ); set->getOrCreateUniform( "atmos_fKrESun", osg::Uniform::FLOAT )->set( Kr * ESun ); set->getOrCreateUniform( "atmos_fKmESun", osg::Uniform::FLOAT )->set( Km * ESun ); set->getOrCreateUniform( "atmos_fKr4PI", osg::Uniform::FLOAT )->set( Kr4PI ); set->getOrCreateUniform( "atmos_fKm4PI", osg::Uniform::FLOAT )->set( Km4PI ); set->getOrCreateUniform( "atmos_fScale", osg::Uniform::FLOAT )->set( Scale ); set->getOrCreateUniform( "atmos_fScaleDepth", osg::Uniform::FLOAT )->set( RayleighScaleDepth ); set->getOrCreateUniform( "atmos_fScaleOverScaleDepth", osg::Uniform::FLOAT )->set( Scale / RayleighScaleDepth ); set->getOrCreateUniform( "atmos_g", osg::Uniform::FLOAT )->set( MPhase ); set->getOrCreateUniform( "atmos_g2", osg::Uniform::FLOAT )->set( MPhase * MPhase ); set->getOrCreateUniform( "atmos_nSamples", osg::Uniform::INT )->set( Samples ); set->getOrCreateUniform( "atmos_fSamples", osg::Uniform::FLOAT )->set( (float)Samples ); set->getOrCreateUniform( "atmos_fWeather", osg::Uniform::FLOAT )->set( Weather ); //geode->setCullCallback( new DoNotIncludeInNearFarComputationCallback() ); AddCallbackToDrawablesVisitor visitor( _innerRadius ); geode->accept( visitor ); _atmosphere = geode; }
void SkyNode::makeStars | ( | const std::string & | starFile | ) | [private] |
Definition at line 966 of file SkyNode.cpp.
{ _starRadius = 20000.0 * (_sunDistance > 0.0 ? _sunDistance : _outerRadius); std::vector<StarData> stars; if( starFile.empty() || parseStarFile(starFile, stars) == false ) { if( !starFile.empty() ) OE_WARN << "Warning: Unable to use star field defined in file \"" << starFile << "\", using default star data." << std::endl; getDefaultStars(stars); } osg::Node* starNode = buildStarGeometry(stars); AddCallbackToDrawablesVisitor visitor(_starRadius); starNode->accept(visitor); _stars = starNode; }
void SkyNode::makeSun | ( | ) | [private] |
Definition at line 909 of file SkyNode.cpp.
{ osg::Billboard* sun = new osg::Billboard(); sun->setMode( osg::Billboard::POINT_ROT_EYE ); sun->setNormal( osg::Vec3(0, 0, 1) ); float sunRadius = _innerRadius * 100.0f; sun->addDrawable( s_makeDiscGeometry( sunRadius*80.0f ) ); osg::StateSet* set = sun->getOrCreateStateSet(); set->getOrCreateUniform( "sunAlpha", osg::Uniform::FLOAT )->set( 1.0f ); // configure the stateset set->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); set->setMode( GL_CULL_FACE, osg::StateAttribute::OFF ); set->setRenderBinDetails( BIN_SUN, "RenderBin" ); set->setAttributeAndModes( new osg::Depth(osg::Depth::ALWAYS, 0, 1, false), osg::StateAttribute::ON ); set->setAttributeAndModes( new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), osg::StateAttribute::ON ); // create shaders osg::Program* program = new osg::Program(); osg::Shader* vs = new osg::Shader( osg::Shader::VERTEX, s_sunVertexSource ); program->addShader( vs ); osg::Shader* fs = new osg::Shader( osg::Shader::FRAGMENT, s_sunFragmentSource ); program->addShader( fs ); set->setAttributeAndModes( program, osg::StateAttribute::ON ); // make the sun's transform: // todo: move this? _defaultPerViewData._sunXform = new osg::MatrixTransform(); _defaultPerViewData._sunXform->setMatrix( osg::Matrix::translate( _sunDistance * _defaultPerViewData._lightPos.x(), _sunDistance * _defaultPerViewData._lightPos.y(), _sunDistance * _defaultPerViewData._lightPos.z() ) ); _defaultPerViewData._sunXform->addChild( sun ); AddCallbackToDrawablesVisitor visitor( _sunDistance ); sun->accept( visitor ); _sun = sun; }
bool SkyNode::parseStarFile | ( | const std::string & | starFile, |
std::vector< StarData > & | out_stars | ||
) | [private] |
Definition at line 1053 of file SkyNode.cpp.
{ out_stars.clear(); std::fstream in(starFile.c_str()); if (!in) { OE_WARN << "Warning: Unable to open file star file \"" << starFile << "\"" << std::endl; return false ; } while (!in.eof()) { std::string line; std::getline(in, line); if (in.eof()) break; if (line.empty() || line[0] == '#') continue; std::stringstream ss(line); out_stars.push_back(StarData(ss)); } in.close(); return true; }
void SkyNode::setAmbientBrightness | ( | float | value, |
osg::View * | view = 0L |
||
) |
The minimum brightness for non-sunlit areas.
Definition at line 681 of file SkyNode.cpp.
{ if ( !view ) { setAmbientBrightness( _defaultPerViewData, value ); for( PerViewDataMap::iterator i = _perViewData.begin(); i != _perViewData.end(); ++i ) setAmbientBrightness( i->second, value ); } else if ( _perViewData.find(view) != _perViewData.end() ) { setAmbientBrightness( _perViewData[view], value ); } }
void SkyNode::setAmbientBrightness | ( | PerViewData & | data, |
float | value | ||
) | [private] |
Definition at line 709 of file SkyNode.cpp.
{ value = osg::clampBetween( value, 0.0f, 1.0f ); data._light->setAmbient( osg::Vec4f(value, value, value, 1.0f) ); }
void SkyNode::setDateTime | ( | int | year, |
int | month, | ||
int | date, | ||
double | hoursUTC, | ||
osg::View * | view = 0L |
||
) |
Sets the sun's position based on a julian date.
Definition at line 767 of file SkyNode.cpp.
{ if ( _ellipsoidModel.valid() ) { // position the sun: Sun sun; osg::Vec3d pos = sun.getPosition( year, month, date, hoursUTC ); pos.normalize(); setSunPosition( pos, view ); // position the stars: double time_r = hoursUTC/24.0; // 0..1 double rot_z = -osg::PI + TWO_PI*time_r; osg::Matrixd starsMatrix = osg::Matrixd::rotate( -rot_z, 0, 0, 1 ); if ( !view ) { _defaultPerViewData._starsMatrix = starsMatrix; for( PerViewDataMap::iterator i = _perViewData.begin(); i != _perViewData.end(); ++i ) { i->second._starsMatrix = starsMatrix; i->second._starsXform->setMatrix( starsMatrix ); } } else if ( _perViewData.find(view) != _perViewData.end() ) { PerViewData& data = _perViewData[view]; data._starsMatrix = starsMatrix; data._starsXform->setMatrix( starsMatrix ); } } }
void SkyNode::setStarsVisible | ( | bool | value, |
osg::View * | view = 0L |
||
) |
Whether the stars are visible
Definition at line 801 of file SkyNode.cpp.
{ if ( !view ) { _defaultPerViewData._starsVisible = value; for( PerViewDataMap::iterator i = _perViewData.begin(); i != _perViewData.end(); ++i ) { i->second._starsVisible = value; i->second._starsXform->setNodeMask( value ? ~0 : 0 ); } } else if ( _perViewData.find(view) != _perViewData.end() ) { _perViewData[view]._starsVisible = value; _perViewData[view]._starsXform->setNodeMask( value ? ~0 : 0 ); } }
void SkyNode::setSunPosition | ( | PerViewData & | data, |
const osg::Vec3 & | pos | ||
) | [private] |
Definition at line 731 of file SkyNode.cpp.
{ data._lightPos = pos; if ( data._light.valid() ) data._light->setPosition( osg::Vec4( data._lightPos, 0 ) ); if ( data._lightPosUniform.valid() ) data._lightPosUniform->set( data._lightPos / data._lightPos.length() ); if ( data._sunXform.valid() ) { data._sunXform->setMatrix( osg::Matrix::translate( _sunDistance * data._lightPos.x(), _sunDistance * data._lightPos.y(), _sunDistance * data._lightPos.z() ) ); } }
void SkyNode::setSunPosition | ( | const osg::Vec3 & | pos, |
osg::View * | view = 0L |
||
) |
Sets the sun's position as a unit vector.
Definition at line 716 of file SkyNode.cpp.
{ if ( !view ) { setSunPosition( _defaultPerViewData, pos ); for( PerViewDataMap::iterator i = _perViewData.begin(); i != _perViewData.end(); ++i ) setSunPosition( i->second, pos ); } else if ( _perViewData.find(view) != _perViewData.end() ) { setSunPosition( _perViewData[view], pos ); } }
void SkyNode::setSunPosition | ( | double | lat_degrees, |
double | lon_degrees, | ||
osg::View * | view = 0L |
||
) |
Sets the sun's position as a latitude and longitude.
Definition at line 751 of file SkyNode.cpp.
{ if (_ellipsoidModel.valid()) { double x, y, z; _ellipsoidModel->convertLatLongHeightToXYZ( osg::RadiansToDegrees(lat_degrees), osg::RadiansToDegrees(long_degrees), 0, x, y, z); osg::Vec3d up = _ellipsoidModel->computeLocalUpVector(x, y, z); setSunPosition( up, view ); } }
void SkyNode::traverse | ( | osg::NodeVisitor & | nv | ) | [virtual] |
Definition at line 613 of file SkyNode.cpp.
{ osg::CullSettings::ComputeNearFarMode saveMode; osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>( &nv ); if ( cv ) { saveMode = cv->getComputeNearFarMode(); cv->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); osg::View* view = cv->getCurrentCamera()->getView(); PerViewDataMap::iterator i = _perViewData.find( view ); if ( i != _perViewData.end() ) { i->second._cullContainer->accept( nv ); } } osg::Group::traverse( nv ); if ( cv ) { cv->setComputeNearFarMode( saveMode ); } }
osg::ref_ptr<osg::Node> osgEarth::Util::SkyNode::_atmosphere [private] |
osg::ref_ptr< const osg::EllipsoidModel > osgEarth::Util::SkyNode::_ellipsoidModel [private] |
float osgEarth::Util::SkyNode::_innerRadius [private] |
float osgEarth::Util::SkyNode::_outerRadius [private] |
osg::ref_ptr<osg::Uniform> osgEarth::Util::SkyNode::_starAlpha [private] |
osg::ref_ptr<osg::Uniform> osgEarth::Util::SkyNode::_starPointSize [private] |
float osgEarth::Util::SkyNode::_starRadius [private] |
osg::ref_ptr<osg::Node> osgEarth::Util::SkyNode::_stars [private] |
osg::ref_ptr<osg::Node> osgEarth::Util::SkyNode::_sun [private] |
float osgEarth::Util::SkyNode::_sunDistance [private] |