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