|
osgEarth 2.1.1
|
Collaboration diagram for osgEarth::Util::OceanSurfaceNode:Public Member Functions | |
| OceanSurfaceNode () | |
| void | setOceanMaskImageLayer (const ImageLayer *layer) |
| const ImageLayer * | getOceanMaskImageLayer () const |
| float | getWaveHeight () const |
| void | setWaveHeight (float waveHeight) |
| float | getMaxRange () const |
| void | setMaxRange (float maxRange) |
| float | getPeriod () const |
| void | setPeriod (float period) |
| bool | getEnabled () const |
| void | setEnabled (bool enabled) |
| bool | getInvertMask () const |
| void | setInvertMask (bool invertMask) |
| void | setModulationColor (const osg::Vec4f &color) |
| osg::Vec4f | getModulationColor () const |
| float | getOceanAnimationPeriod () const |
| void | setOceanAnimationPeriod (float oceanAnimationPeriod) |
| osg::Image * | getOceanSurfaceImage () const |
| void | setOceanSurfaceImage (osg::Image *image) |
| float | getOceanSurfaceImageSizeRadians () const |
| void | setOceanSurfaceImageSizeRadians (float size) |
| void | setAdjustToMSL (bool adjustToMSL) |
| bool | getAdjustToMSL () const |
| virtual void | traverse (osg::NodeVisitor &nv) |
Private Member Functions | |
| void | rebuildShaders () |
| void | shadersDirty (bool value) |
Private Attributes | |
| bool | _shadersDirty |
| float | _maxRange |
| UID | _oceanMaskLayerUID |
| int | _oceanSurfaceTextureUnit |
| bool | _oceanSurfaceTextureApplied |
| float | _waveHeight |
| float | _period |
| bool | _enabled |
| bool | _invertMask |
| bool | _adjustToMSL |
| osg::observer_ptr < osg::CoordinateSystemNode > | _csn |
| optional< osg::Vec4f > | _oceanColor |
| float | _oceanAnimationPeriod |
| float | _oceanSurfaceImageSizeRadians |
| osg::ref_ptr< osg::Image > | _oceanSurfaceImage |
| osg::ref_ptr< osg::Texture3D > | _oceanSurfaceTexture |
| osg::observer_ptr< const ImageLayer > | _maskLayer |
OceanSurfaceNode is a decorator node that animates the surface of the globe to simulate simple waves. Note: This only works with multitextured maps, not multipass.
Definition at line 38 of file OceanSurfaceNode.
| OceanSurfaceNode::OceanSurfaceNode | ( | ) |
Creates a new OceanSurfaceNode
Definition at line 43 of file OceanSurfaceNode.cpp.
: _shadersDirty(false), _maxRange(800000), _oceanMaskLayerUID(-1), _oceanSurfaceTextureUnit(-1), _oceanSurfaceTextureApplied(false), _waveHeight(100), _period(1024), _enabled(true), _invertMask(false), _adjustToMSL(true), _oceanColor(osg::Vec4f(0,0,1,0)), _oceanAnimationPeriod(6.0), _oceanSurfaceImageSizeRadians(osg::PI/500.0) { rebuildShaders(); getOrCreateStateSet()->getOrCreateUniform("osgearth_OceanPeriod", osg::Uniform::FLOAT)->set(_period); getOrCreateStateSet()->getOrCreateUniform("osgearth_OceanAnimationPeriod", osg::Uniform::FLOAT)->set(_oceanAnimationPeriod); osg::Uniform* oceanHeightUniform = getOrCreateStateSet()->getOrCreateUniform("osgearth_OceanHeight", osg::Uniform::FLOAT); oceanHeightUniform->set( _waveHeight); oceanHeightUniform->setDataVariance( osg::Object::DYNAMIC); //Initialize the ocean surface texture _oceanSurfaceTexture = new osg::Texture3D(); _oceanSurfaceTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT); _oceanSurfaceTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT); _oceanSurfaceTexture->setWrap(osg::Texture::WRAP_R,osg::Texture::REPEAT); _oceanSurfaceTexture->setFilter(osg::Texture3D::MIN_FILTER,osg::Texture3D::LINEAR); _oceanSurfaceTexture->setFilter(osg::Texture3D::MAG_FILTER,osg::Texture3D::LINEAR); }
Here is the call graph for this function:| bool OceanSurfaceNode::getAdjustToMSL | ( | ) | const |
Gets whether or not to adjust the height of the ocean to always be at MSL 0 and ignore the current vert height
Definition at line 97 of file OceanSurfaceNode.cpp.
{
return _adjustToMSL;
}
| bool OceanSurfaceNode::getEnabled | ( | ) | const |
Gets whether the ocean effect is enabled
Definition at line 181 of file OceanSurfaceNode.cpp.
{
return _enabled;
}
| bool OceanSurfaceNode::getInvertMask | ( | ) | const |
Gets whether to invert the mask ocean mask.
Definition at line 197 of file OceanSurfaceNode.cpp.
{
return _invertMask;
}
| float OceanSurfaceNode::getMaxRange | ( | ) | const |
Gets the range at which the effect starts to show.
Definition at line 148 of file OceanSurfaceNode.cpp.
{
return _maxRange;
}
| osg::Vec4f OceanSurfaceNode::getModulationColor | ( | ) | const |
Definition at line 223 of file OceanSurfaceNode.cpp.
{
return _oceanColor.value();
}
Here is the call graph for this function:| float OceanSurfaceNode::getOceanAnimationPeriod | ( | ) | const |
Gets the period of the ocean animation effect in seconds
Definition at line 229 of file OceanSurfaceNode.cpp.
{
return _oceanAnimationPeriod;
}
| const ImageLayer* osgEarth::Util::OceanSurfaceNode::getOceanMaskImageLayer | ( | ) | const [inline] |
Gets the image layer being used as an ocean mask.
Definition at line 54 of file OceanSurfaceNode.
{ return _maskLayer.get(); }
| osg::Image * OceanSurfaceNode::getOceanSurfaceImage | ( | ) | const |
Gets the ocean surface image to the given 3D image.
Definition at line 113 of file OceanSurfaceNode.cpp.
{
return _oceanSurfaceImage.get();
}
| float OceanSurfaceNode::getOceanSurfaceImageSizeRadians | ( | ) | const |
Gets the size of the ocean surface image in radians
Definition at line 246 of file OceanSurfaceNode.cpp.
{
return _oceanSurfaceImageSizeRadians;
}
| float OceanSurfaceNode::getPeriod | ( | ) | const |
Gets the period of the wave
Definition at line 164 of file OceanSurfaceNode.cpp.
{
return _period;
}
| float OceanSurfaceNode::getWaveHeight | ( | ) | const |
| void OceanSurfaceNode::rebuildShaders | ( | ) | [private] |
Definition at line 276 of file OceanSurfaceNode.cpp.
{
// need the terrain engine so we can get at the compositor.
TerrainEngineNode* engine = osgEarth::findTopMostNodeOfType<TerrainEngineNode>( this );
if ( !engine ) {
OE_DEBUG << LC << "No terrain engine found in the map node; abort" << std::endl;
return;
}
// access the compositor because we are going to be sampling map layers.
TextureCompositor* comp = engine->getTextureCompositor();
if ( !comp ) {
OE_INFO << LC << "No texture compositor found in the terrain engine; abort" << std::endl;
return;
}
// reserve a texture unit for the surface texture (if we haven't already)
if ( !_oceanSurfaceTextureApplied && _oceanSurfaceTextureUnit < 0 && _oceanSurfaceTexture.valid() )
{
if ( comp->reserveTextureImageUnit( _oceanSurfaceTextureUnit ) )
{
getOrCreateStateSet()->setTextureAttributeAndModes(
_oceanSurfaceTextureUnit, _oceanSurfaceTexture.get(), osg::StateAttribute::ON);
_oceanSurfaceTextureApplied = true;
}
else
{
OE_WARN << LC << "Sorry, failed to allocate a texture image unit for the surface texture." << std::endl;
}
}
// create a VP to store our custom shader components.
osgEarth::VirtualProgram* vp = new osgEarth::VirtualProgram();
getOrCreateStateSet()->setAttributeAndModes( vp, osg::StateAttribute::ON );
// if the ocean is disabled, just return without injecting any shaders.
if ( !_enabled )
return;
// build the sampler function if necessary
osg::ref_ptr<const ImageLayer> safeMaskLayer = _maskLayer.get();
osg::Shader* maskSampler = 0L;
if ( safeMaskLayer.valid() )
{
maskSampler = comp->createSamplerFunction( safeMaskLayer->getUID(), MASK_SAMPLER_FUNC, osg::Shader::VERTEX );
if ( maskSampler )
vp->setShader( MASK_SAMPLER_FUNC, maskSampler );
}
// make the helper functions.
{
std::stringstream buf;
buf << "vec3 xyz_to_lat_lon_height(in vec3 xyz) \n"
<< "{ \n"
<< " float X = xyz.x;\n"
<< " float Y = xyz.y;\n"
<< " float Z = xyz.z;\n"
<< " float _radiusEquator = 6378137.0;\n"
<< " float _radiusPolar = 6356752.3142;\n"
<< " float flattening = (_radiusEquator-_radiusPolar)/_radiusEquator;\n"
<< " float _eccentricitySquared = 2.0*flattening - flattening*flattening;\n"
<< " float p = sqrt(X*X + Y*Y);\n"
<< " float theta = atan(Z*_radiusEquator , (p*_radiusPolar));\n"
<< " float eDashSquared = (_radiusEquator*_radiusEquator - _radiusPolar*_radiusPolar)/(_radiusPolar*_radiusPolar);\n"
<< " float sin_theta = sin(theta);\n"
<< " float cos_theta = cos(theta);\n"
<< " float latitude = atan( (Z + eDashSquared*_radiusPolar*sin_theta*sin_theta*sin_theta), (p - _eccentricitySquared*_radiusEquator*cos_theta*cos_theta*cos_theta) );\n"
<< " float longitude = atan(Y,X);\n"
<< " float sin_latitude = sin(latitude);\n"
<< " float N = _radiusEquator / sqrt( 1.0 - _eccentricitySquared*sin_latitude*sin_latitude);\n"
<< " float height = p/cos(latitude) - N;\n"
<< " return vec3(longitude, latitude, height);\n"
<< "} \n"
<< "\n";
std::string str = buf.str();
vp->setShader( "xyz_to_lat_lon_height", new osg::Shader(osg::Shader::VERTEX, str) );
}
// next make the vertex shader function that will morph the ocean verts and prepare
// the texture coordinates for the surface effects.
{
std::stringstream buf;
buf << std::fixed;
buf << "uniform float osg_SimulationTime; \n"
<< "uniform mat4 osg_ViewMatrixInverse;\n"
<< "uniform mat4 osg_ViewMatrix;\n"
<< "uniform float osgearth_OceanHeight;\n"
<< "uniform float osgearth_OceanPeriod;\n"
<< "uniform float osgearth_OceanAnimationPeriod;\n"
<< "varying float osgearth_OceanAlpha;\n"
<< "varying float osgearth_CameraRange; \n"
<< "vec3 xyz_to_lat_lon_height(in vec3 xyz); \n";
if ( _oceanSurfaceTextureApplied )
{
buf << "varying vec3 osgearth_oceanSurfaceTexCoord; \n";
}
if ( maskSampler )
{
buf << "vec4 " << MASK_SAMPLER_FUNC << "(); \n";
}
buf << "void osgearth_ocean_morphSurface() \n"
<< "{ \n"
<< " mat4 modelMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix; \n"
<< " vec4 vert = modelMatrix * gl_Vertex; \n"
<< " vec3 vert3 = vec3(vert.x, vert.y, vert.z); \n"
<< " vec3 latlon = xyz_to_lat_lon_height(vert3); \n"
<< " osgearth_OceanAlpha = 1.0; \n";
if ( maskSampler )
{
buf << " osgearth_OceanAlpha = 1.0 - (" << MASK_SAMPLER_FUNC << "()).a; \n";
}
if ( _invertMask )
buf << " osgearth_OceanAlpha = 1.0 - osgearth_OceanAlpha; \n";
buf << " if ( osgearth_CameraRange <= " << _maxRange << " ) \n"
<< " { \n"
<< " float s = mix(1.0, 0.0, osgearth_CameraRange / " << _maxRange << "); \n" //Invert so it's between 0 and 1
<< " osgearth_OceanAlpha *= s; \n"
<< " } \n"
<< " else \n"
<< " { \n"
<< " osgearth_OceanAlpha = 0.0; \n"
<< " } \n"
<< " if (osgearth_OceanAlpha > 0.0) \n"
<< " { \n"
<< " float PI_2 = 3.14158 * 2.0; \n"
<< " float period = PI_2/osgearth_OceanPeriod; \n"
<< " float half_period = period / 2.0; \n"
<< " vec3 n = normalize(vert3);\n"
<< " float theta = (mod(latlon.x, period) / period) * PI_2; \n"
<< " float phi = (mod(latlon.y, half_period) / half_period) * PI_2; \n"
<< " float phase1 = osg_SimulationTime * 2.0; \n"
<< " float phase2 = osg_SimulationTime * 4.0; \n"
<< " float waveHeight = (osgearth_OceanAlpha) * osgearth_OceanHeight; \n"
<< " float scale1 = sin(theta + phase1) * waveHeight; \n"
<< " float scale2 = cos(phi + phase2) * waveHeight; \n"
<< " float scale3 = sin(theta + phase2) * cos(phi + phase1) * waveHeight * 1.6; \n"
<< " float scale = (scale1 + scale2 + scale3)/3.0; \n";
// flatten verts to MSL:
if ( _adjustToMSL )
{
buf << " vec3 offset = n * -latlon.z; \n"
<< " vert += vec4( offset.xyz, 0 ); \n";
}
// apply the save scale:
buf << " n = n * scale; \n"
<< " vert += vec4(n.x, n.y,n.z,0); \n"
<< " vert = osg_ViewMatrix * vert; \n"
<< " gl_Position = gl_ProjectionMatrix * vert; \n"
<< " }\n";
// set up the coords for the surface texture:
if ( _oceanSurfaceTextureApplied )
{
buf << " osgearth_oceanSurfaceTexCoord.x = latlon.x / " << _oceanSurfaceImageSizeRadians << "; \n"
<< " osgearth_oceanSurfaceTexCoord.y = latlon.y / " << _oceanSurfaceImageSizeRadians << "; \n"
<< " osgearth_oceanSurfaceTexCoord.z = fract(osg_SimulationTime/osgearth_OceanAnimationPeriod); \n";
}
buf << "}\n";
// add as a custom user function in the shader composition:
std::string vertSource = buf.str();
vp->setFunction( "osgearth_ocean_morphSurface", vertSource, osgEarth::ShaderComp::LOCATION_VERTEX_PRE_TEXTURING );
}
// now we need a fragment function that will apply the ocean surface texture.
if ( _oceanSurfaceTextureApplied )
{
getOrCreateStateSet()->getOrCreateUniform( "osgearth_oceanSurfaceTex", osg::Uniform::SAMPLER_3D )->set( _oceanSurfaceTextureUnit );
std::stringstream buf;
buf << "uniform sampler3D osgearth_oceanSurfaceTex; \n"
<< "varying vec3 osgearth_oceanSurfaceTexCoord; \n"
<< "varying float osgearth_OceanAlpha; \n"
<< "void osgearth_ocean_applySurfaceTex( inout vec4 color ) \n"
<< "{ \n"
<< " vec4 texel = texture3D(osgearth_oceanSurfaceTex, osgearth_oceanSurfaceTexCoord); \n"
<< " color = vec4( mix( color.rgb, texel.rgb, texel.a * osgearth_OceanAlpha ), color.a); \n"
<< "} \n";
std::string str = buf.str();
vp->setFunction( "osgearth_ocean_applySurfaceTex", str, osgEarth::ShaderComp::LOCATION_FRAGMENT_PRE_LIGHTING );
}
}
Here is the call graph for this function:
Here is the caller graph for this function:| void OceanSurfaceNode::setAdjustToMSL | ( | bool | adjustToMSL | ) |
Sets whether or not to adjust the height of the ocean to always be at MSL 0 and ignore the current vert height
Definition at line 103 of file OceanSurfaceNode.cpp.
{
if (_adjustToMSL != adjustToMSL)
{
_adjustToMSL = adjustToMSL;
shadersDirty( true );
}
}
Here is the call graph for this function:| void OceanSurfaceNode::setEnabled | ( | bool | enabled | ) |
Sets whether the ocean effect is enabled
Definition at line 187 of file OceanSurfaceNode.cpp.
{
if (_enabled != enabled)
{
_enabled = enabled;
shadersDirty(true);
}
}
Here is the call graph for this function:| void OceanSurfaceNode::setInvertMask | ( | bool | invertMask | ) |
Sets whether to invert the mask ocean mask. Normally, transparant areas are considered ocean. When inverted, transparent areas are considered land.
Definition at line 203 of file OceanSurfaceNode.cpp.
{
if (_invertMask != invertMask)
{
_invertMask = invertMask;
shadersDirty( true );
}
}
Here is the call graph for this function:
Here is the caller graph for this function:| void OceanSurfaceNode::setMaxRange | ( | float | maxRange | ) |
Sets the max range at which the effect starts to show
Definition at line 154 of file OceanSurfaceNode.cpp.
{
if (_maxRange != maxRange)
{
_maxRange = maxRange;
shadersDirty(true);
}
}
Here is the call graph for this function:| void OceanSurfaceNode::setModulationColor | ( | const osg::Vec4f & | color | ) |
Sets an optional ocean color. The ocean will take on this color based on the alpha values in the masking texture.
Definition at line 213 of file OceanSurfaceNode.cpp.
{
if ( !_oceanColor.isSetTo( color ) )
{
_oceanColor = color;
shadersDirty( true );
}
}
Here is the call graph for this function:| void OceanSurfaceNode::setOceanAnimationPeriod | ( | float | oceanAnimationPeriod | ) |
Sets the period of the ocean animation effect in seconds
Definition at line 235 of file OceanSurfaceNode.cpp.
{
if (_oceanAnimationPeriod != oceanAnimationPeriod)
{
_oceanAnimationPeriod = oceanAnimationPeriod;
getOrCreateStateSet()->getOrCreateUniform("osgearth_OceanAnimationPeriod", osg::Uniform::FLOAT)->set(oceanAnimationPeriod);
//TODO: consider rebuildShaders() instead..
}
}
| void OceanSurfaceNode::setOceanMaskImageLayer | ( | const ImageLayer * | layer | ) |
Sets the image layer to use as an ocean mask.
Definition at line 87 of file OceanSurfaceNode.cpp.
{
if ( _maskLayer.get() != layer )
{
_maskLayer = layer;
shadersDirty(true);
}
}
Here is the call graph for this function:
Here is the caller graph for this function:| void OceanSurfaceNode::setOceanSurfaceImage | ( | osg::Image * | image | ) |
Sets the ocean surface image to the given 3D image.
Definition at line 119 of file OceanSurfaceNode.cpp.
{
if (_oceanSurfaceImage.get() != image)
{
_oceanSurfaceImage = image;
_oceanSurfaceTexture->setImage( _oceanSurfaceImage.get() );
shadersDirty( true );
}
}
Here is the call graph for this function:
Here is the caller graph for this function:| void OceanSurfaceNode::setOceanSurfaceImageSizeRadians | ( | float | size | ) |
Sets the size of the ocean surface image in radians
Definition at line 252 of file OceanSurfaceNode.cpp.
{
if (_oceanSurfaceImageSizeRadians != size)
{
_oceanSurfaceImageSizeRadians = size;
shadersDirty( true );
}
}
Here is the call graph for this function:| void OceanSurfaceNode::setPeriod | ( | float | period | ) |
Sets the period of the wave
Definition at line 170 of file OceanSurfaceNode.cpp.
| void OceanSurfaceNode::setWaveHeight | ( | float | waveHeight | ) |
Sets the wave height
Definition at line 137 of file OceanSurfaceNode.cpp.
{
if (_waveHeight != waveHeight)
{
_waveHeight = waveHeight;
getOrCreateStateSet()->getOrCreateUniform("osgearth_OceanHeight", osg::Uniform::FLOAT)->set(_waveHeight);
//TODO: consider rebuildShaders() instead..
}
}
| void OceanSurfaceNode::shadersDirty | ( | bool | value | ) | [private] |
Definition at line 77 of file OceanSurfaceNode.cpp.
{
if ( _shadersDirty != value )
{
_shadersDirty = value;
ADJUST_UPDATE_TRAV_COUNT( this, _shadersDirty ? 1 : -1 );
}
}
Here is the caller graph for this function:| void OceanSurfaceNode::traverse | ( | osg::NodeVisitor & | nv | ) | [virtual] |
Definition at line 262 of file OceanSurfaceNode.cpp.
{
if ( _shadersDirty && nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR )
{
rebuildShaders();
shadersDirty( false );
}
osg::Group::traverse( nv );
}
Here is the call graph for this function:bool osgEarth::Util::OceanSurfaceNode::_adjustToMSL [private] |
Definition at line 172 of file OceanSurfaceNode.
osg::observer_ptr<osg::CoordinateSystemNode> osgEarth::Util::OceanSurfaceNode::_csn [private] |
Definition at line 173 of file OceanSurfaceNode.
bool osgEarth::Util::OceanSurfaceNode::_enabled [private] |
Definition at line 170 of file OceanSurfaceNode.
bool osgEarth::Util::OceanSurfaceNode::_invertMask [private] |
Definition at line 171 of file OceanSurfaceNode.
osg::observer_ptr< const ImageLayer > osgEarth::Util::OceanSurfaceNode::_maskLayer [private] |
Definition at line 179 of file OceanSurfaceNode.
float osgEarth::Util::OceanSurfaceNode::_maxRange [private] |
Definition at line 164 of file OceanSurfaceNode.
float osgEarth::Util::OceanSurfaceNode::_oceanAnimationPeriod [private] |
Definition at line 175 of file OceanSurfaceNode.
optional<osg::Vec4f> osgEarth::Util::OceanSurfaceNode::_oceanColor [private] |
Definition at line 174 of file OceanSurfaceNode.
Definition at line 165 of file OceanSurfaceNode.
osg::ref_ptr< osg::Image > osgEarth::Util::OceanSurfaceNode::_oceanSurfaceImage [private] |
Definition at line 177 of file OceanSurfaceNode.
float osgEarth::Util::OceanSurfaceNode::_oceanSurfaceImageSizeRadians [private] |
Definition at line 176 of file OceanSurfaceNode.
osg::ref_ptr< osg::Texture3D > osgEarth::Util::OceanSurfaceNode::_oceanSurfaceTexture [private] |
Definition at line 178 of file OceanSurfaceNode.
Definition at line 167 of file OceanSurfaceNode.
Definition at line 166 of file OceanSurfaceNode.
float osgEarth::Util::OceanSurfaceNode::_period [private] |
Definition at line 169 of file OceanSurfaceNode.
bool osgEarth::Util::OceanSurfaceNode::_shadersDirty [private] |
Definition at line 162 of file OceanSurfaceNode.
float osgEarth::Util::OceanSurfaceNode::_waveHeight [private] |
Definition at line 168 of file OceanSurfaceNode.
1.7.3