Hi,

I added a user-definable mask functionallity to FFTOceanSurface. The mask 
applies a height offset to the ocean tiles which allows the usage of the 
FFTOceanSurface as rivers and lakes on different altitudes in the same scene 
without having it protrude the ground (I plan to combine this with osgEarth). 

Its currently more of a dirty hack, but still its quite usable. 

In the FFTOceanSurface Header I added 2 variables and changed the ctor:

Code:

osg::Image *_surfMask;
float _sufMaskMaxDist;

public:
FFTOceanSurface(unsigned int FFTGridSize = 64,
 unsigned int resolution = 256,
 unsigned int numTiles = 17, 
 const osg::Vec2f& windDirection = osg::Vec2f(1.1f, 1.1f),
 float windSpeed = 12.f,
 float depth = 1000.f,
 float reflectionDamping = 0.35f,
 float waveScale = 1e-8f,
 bool isChoppy = true,
 float choppyFactor = -2.5f,
 float animLoopTime = 10.f,
 unsigned int numFrames = 256,
 osg::Image *_surfMask=NULL,
 float _sufMaskMaxDist=100.0f
);




In FFTOceanSurface.cpp I added this to the computeSea method:

Before the frame loop:

Code:

int imgDim = 0;
int imgBytesPerLine = 0;
int imgBytePerPixel = 0;

if(_surfMask)
{
 imgDim =__min(_surfMask->s(),_surfMask->t());
 imgBytePerPixel = _surfMask->computeNumComponents(_surfMask->getPixelFormat());
 imgBytesPerLine = _surfMask->s()*imgBytePerPixel;
}




Within the frame loop before calling OceanTile() for level 0:


Code:

int sizeHeights = heights->size();
int dimHeights = (int)floor(sqrt((float)sizeHeights)+0.5f);

if(_surfMask && imgDim>0 && dimHeights>0) // Apply surface mask
{
  //Handle scaling difference between 
  if(dimHeights >= imgDim)
  {
    int imgScaling = dimHeights/imgDim;
    int scaledImgDim = imgDim*imgScaling;
    for(int y= 0; y < dimHeights;y++)
    {
      int yRow = dimHeights*y;
      unsigned char* pImgOsgLine = ((unsigned char*)_surfMask->data())+ 
imgBytesPerLine * (y/imgScaling);
      for(int x = 0; x < dimHeights;x++)
      {
        if((x < scaledImgDim) &&(y < scaledImgDim))
        {
          float alpha =(float)*((unsigned 
char*)(pImgOsgLine+(x/imgScaling)*imgBytePerPixel))/255.0f;
          float oldVal = heights->at(yRow+x);
          heights->at(yRow+x) = alpha*oldVal - _sufMaskMaxDist*(1.0f-alpha);
        }
        else
        {
          heights->at(yRow+x) = -_sufMaskMaxDist;
        }
      }
    }
  }
  else
  {
    int imgScaling_d1 = imgDim/dimHeights;
    int scaledImgDim = imgDim/imgScaling_d1;
    for(int y= 0; y < dimHeights;y++)
    {
      int yRow = dimHeights*y;
      unsigned char* pImgOsgLine = ((unsigned char*)_surfMask->data()) + 
imgBytesPerLine * y*imgScaling_d1;
      for(int x = 0; x < dimHeights;x++)
      {
        if((x < scaledImgDim) &&(y < scaledImgDim) )
        {
          float alpha =(float)*((unsigned 
char*)(pImgOsgLine+x*imgScaling_d1*imgBytePerPixel))/255.0f;
          float oldVal = heights->at(yRow+x);
          heights->at(yRow+x) = alpha*oldVal - _sufMaskMaxDist*(1.0f-alpha);
        }
        else
        {
          heights->at(yRow+x) = -_sufMaskMaxDist;
        }
      }
    }
  }
}




Greetings,
Oliver

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=47939#47939




Attachments: 
http://forum.openscenegraph.org//files/ocean_masked_157.png


_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to