|
osgEarth 2.1.1
|
Collaboration diagram for osgEarth::Util::SkyNode: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);
}
Here is the call graph for this function:| 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) );
}
Here is the caller graph for this function:| 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;
}
Here is the call graph for this function:| 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;
}
Here is the call graph for this function:| 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;
}
Here is the call graph for this function:| 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 );
}
}
}
Here is the caller graph for this function:| 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] |
1.7.3