|
osgEarth 2.1.1
|
Inheritance diagram for MultiPassTerrainTechnique:
Collaboration diagram for MultiPassTerrainTechnique:Public Member Functions | |
| MultiPassTerrainTechnique (TextureCompositor *texCompositor=0L) | |
| MultiPassTerrainTechnique (const MultiPassTerrainTechnique &, const osg::CopyOp ©op=osg::CopyOp::SHALLOW_COPY) | |
| META_Object (osgEarth, MultiPassTerrainTechnique) | |
| virtual void | init () |
| virtual osgTerrain::Locator * | computeMasterLocator () |
| virtual osg::Vec3d | computeCenterModel (osgTerrain::Locator *masterLocator) |
| virtual void | generateGeometry (osgTerrain::Locator *masterLocator, const osg::Vec3d ¢erModel) |
| virtual osg::Geometry * | createGeometryPrototype (osgTerrain::Locator *masterLocator, const osg::Vec3d ¢erModel) |
| osg::Geode * | createPass (unsigned int order, const CustomColorLayer *layer, osgTerrain::Locator *masterLocator, const osg::Vec3d ¢erModel, osg::Geometry *geometry) |
| virtual void | traverse (osg::NodeVisitor &nv) |
| virtual void | releaseGLObjects (osg::State *=0) const |
Private Member Functions | |
| void | updateTransparency () |
| void | updateGeometry () |
| virtual | ~MultiPassTerrainTechnique () |
Private Attributes | |
| osg::ref_ptr < osg::MatrixTransform > | _transform |
| osg::ref_ptr< osg::Group > | _passes |
| bool | _terrainTileInitialized |
| osg::ref_ptr< TextureCompositor > | _texCompositor |
Definition at line 36 of file MultiPassTerrainTechnique.
| MultiPassTerrainTechnique::MultiPassTerrainTechnique | ( | TextureCompositor * | texCompositor = 0L | ) |
Definition at line 68 of file MultiPassTerrainTechnique.cpp.
: TerrainTechnique(), //osgTerrain::TerrainTechnique(), _terrainTileInitialized(false), _texCompositor( texCompositor ) { this->setThreadSafeRefUnref( true ); }
| MultiPassTerrainTechnique::MultiPassTerrainTechnique | ( | const MultiPassTerrainTechnique & | mt, |
| const osg::CopyOp & | copyop = osg::CopyOp::SHALLOW_COPY |
||
| ) |
Copy constructor using CopyOp to manage deep vs shallow copy.
Definition at line 77 of file MultiPassTerrainTechnique.cpp.
: TerrainTechnique(mt,copyop) { _terrainTileInitialized = mt._terrainTileInitialized; _texCompositor = mt._texCompositor.get(); }
| MultiPassTerrainTechnique::~MultiPassTerrainTechnique | ( | ) | [private, virtual] |
Definition at line 84 of file MultiPassTerrainTechnique.cpp.
{
}
| osg::Vec3d MultiPassTerrainTechnique::computeCenterModel | ( | osgTerrain::Locator * | masterLocator | ) | [virtual] |
Definition at line 128 of file MultiPassTerrainTechnique.cpp.
{
if (!masterLocator) return osg::Vec3d(0.0,0.0,0.0);
osgTerrain::Layer* elevationLayer = _tile->getElevationLayer();
osgTerrain::Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
osgTerrain::Locator* colorLocator = 0L;
if (!elevationLocator) elevationLocator = masterLocator;
if (!colorLocator) colorLocator = masterLocator;
osg::Vec3d bottomLeftNDC(DBL_MAX, DBL_MAX, 0.0);
osg::Vec3d topRightNDC(-DBL_MAX, -DBL_MAX, 0.0);
if (elevationLayer)
{
if (elevationLocator!= masterLocator)
{
masterLocator->computeLocalBounds(*elevationLocator, bottomLeftNDC, topRightNDC);
}
else
{
bottomLeftNDC.x() = osg::minimum(bottomLeftNDC.x(), 0.0);
bottomLeftNDC.y() = osg::minimum(bottomLeftNDC.y(), 0.0);
topRightNDC.x() = osg::maximum(topRightNDC.x(), 1.0);
topRightNDC.y() = osg::maximum(topRightNDC.y(), 1.0);
}
}
//if (colorLayer)
//{
// if (colorLocator!= masterLocator)
// {
// masterLocator->computeLocalBounds(*colorLocator, bottomLeftNDC, topRightNDC);
// }
// else
// {
// bottomLeftNDC.x() = osg::minimum(bottomLeftNDC.x(), 0.0);
// bottomLeftNDC.y() = osg::minimum(bottomLeftNDC.y(), 0.0);
// topRightNDC.x() = osg::maximum(topRightNDC.x(), 1.0);
// topRightNDC.y() = osg::maximum(topRightNDC.y(), 1.0);
// }
//}
//OE_DEBUG<<"bottomLeftNDC = "<<bottomLeftNDC<<std::endl;
//OE_DEBUG<<"topRightNDC = "<<topRightNDC<<std::endl;
_transform = new osg::MatrixTransform;
osg::Vec3d centerNDC = (bottomLeftNDC + topRightNDC)*0.5;
osg::Vec3d centerModel = (bottomLeftNDC + topRightNDC)*0.5;
masterLocator->convertLocalToModel(centerNDC, centerModel);
_transform->setMatrix(osg::Matrix::translate(centerModel));
return centerModel;
}
Here is the call graph for this function:
Here is the caller graph for this function:| osgTerrain::Locator * MultiPassTerrainTechnique::computeMasterLocator | ( | ) | [virtual] |
Definition at line 114 of file MultiPassTerrainTechnique.cpp.
{
osgTerrain::Layer* elevationLayer = _tile->getElevationLayer();
osgTerrain::Locator* locator = elevationLayer ? elevationLayer->getLocator() : 0L;
if ( !locator )
{
OE_NOTICE << "Problem, no locator found in any of the terrain layers"<<std::endl;
return 0;
}
return locator;
}
Here is the call graph for this function:
Here is the caller graph for this function:| osg::Geometry * MultiPassTerrainTechnique::createGeometryPrototype | ( | osgTerrain::Locator * | masterLocator, |
| const osg::Vec3d & | centerModel | ||
| ) | [virtual] |
Definition at line 187 of file MultiPassTerrainTechnique.cpp.
{
osgTerrain::Layer* elevationLayer = _tile->getElevationLayer();
osg::Geometry* geometry = new osg::Geometry;
unsigned int numRows = 20;
unsigned int numColumns = 20;
if (elevationLayer)
{
numColumns = elevationLayer->getNumColumns();
numRows = elevationLayer->getNumRows();
}
float sampleRatio = _tile->getTerrain() ? _tile->getTerrain()->getSampleRatio() : 1.0f;
double i_sampleFactor = 1.0;
double j_sampleFactor = 1.0;
// OE_NOTICE<<"Sample ratio="<<sampleRatio<<std::endl;
if (sampleRatio!=1.0f)
{
unsigned int originalNumColumns = numColumns;
unsigned int originalNumRows = numRows;
numColumns = osg::maximum((unsigned int) (float(originalNumColumns)*sqrtf(sampleRatio)), 4u);
numRows = osg::maximum((unsigned int) (float(originalNumRows)*sqrtf(sampleRatio)),4u);
i_sampleFactor = double(originalNumColumns-1)/double(numColumns-1);
j_sampleFactor = double(originalNumRows-1)/double(numRows-1);
}
//bool treatBoundariesToValidDataAsDefaultValue = _tile->getTreatBoundariesToValidDataAsDefaultValue();
//OE_DEBUG<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl;
float skirtHeight = 0.0f;
osgTerrain::HeightFieldLayer* hfl = dynamic_cast<osgTerrain::HeightFieldLayer*>(elevationLayer);
if (hfl && hfl->getHeightField())
{
skirtHeight = hfl->getHeightField()->getSkirtHeight();
}
bool createSkirt = skirtHeight != 0.0f;
unsigned int numVerticesInBody = numColumns*numRows;
unsigned int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0;
unsigned int numVertices = numVerticesInBody+numVerticesInSkirt;
// allocate and assign vertices
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
vertices->reserve(numVertices);
geometry->setVertexArray(vertices.get());
// allocate and assign normals
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
if (normals.valid()) normals->reserve(numVertices);
geometry->setNormalArray(normals.get());
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
//float minHeight = 0.0;
float scaleHeight = _tile->getTerrain() ? _tile->getTerrain()->getVerticalScale() : 1.0f;
//Reserve space for the elevations
osg::ref_ptr<osg::FloatArray> elevations = new osg::FloatArray;
if (elevations.valid()) elevations->reserve(numVertices);
// allocate and assign color
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
geometry->setColorArray(colors.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
typedef std::vector<int> Indices;
Indices indices(numVertices, -1);
// populate vertex and tex coord arrays
unsigned int i, j;
for(j=0; j<numRows; ++j)
{
for(i=0; i<numColumns; ++i)
{
unsigned int iv = j*numColumns + i;
osg::Vec3d ndc( ((double)i)/(double)(numColumns-1), ((double)j)/(double)(numRows-1), 0.0);
bool validValue = true;
unsigned int i_equiv = i_sampleFactor==1.0 ? i : (unsigned int) (double(i)*i_sampleFactor);
unsigned int j_equiv = i_sampleFactor==1.0 ? j : (unsigned int) (double(j)*j_sampleFactor);
if (elevationLayer)
{
float value = 0.0f;
validValue = elevationLayer->getValidValue(i_equiv,j_equiv, value);
// OE_INFO<<"i="<<i<<" j="<<j<<" z="<<value<<std::endl;
ndc.z() = value*scaleHeight;
}
if (validValue)
{
indices[iv] = vertices->size();
osg::Vec3d model;
masterLocator->convertLocalToModel(ndc, model);
(*vertices).push_back(model - centerModel);
if (elevations.valid())
{
(*elevations).push_back(ndc.z());
}
// compute the local normal
osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0;
osg::Vec3d model_one;
masterLocator->convertLocalToModel(ndc_one, model_one);
model_one = model_one - model;
model_one.normalize();
(*normals).push_back(model_one);
}
else
{
indices[iv] = -1;
}
}
}
// populate primitive sets
// bool optimizeOrientations = elevations!=0;
bool swapOrientation = !(masterLocator->orientationOpenGL());
osg::ref_ptr<osg::DrawElementsUInt> elements = new osg::DrawElementsUInt(GL_TRIANGLES);
elements->reserve((numRows-1) * (numColumns-1) * 6);
geometry->addPrimitiveSet(elements.get());
for(j=0; j<numRows-1; ++j)
{
for(i=0; i<numColumns-1; ++i)
{
int i00;
int i01;
if (swapOrientation)
{
i01 = j*numColumns + i;
i00 = i01+numColumns;
}
else
{
i00 = j*numColumns + i;
i01 = i00+numColumns;
}
int i10 = i00+1;
int i11 = i01+1;
// remap indices to final vertex positions
i00 = indices[i00];
i01 = indices[i01];
i10 = indices[i10];
i11 = indices[i11];
unsigned int numValid = 0;
if (i00>=0) ++numValid;
if (i01>=0) ++numValid;
if (i10>=0) ++numValid;
if (i11>=0) ++numValid;
if (numValid==4)
{
float e00 = (*elevations)[i00];
float e10 = (*elevations)[i10];
float e01 = (*elevations)[i01];
float e11 = (*elevations)[i11];
if (fabsf(e00-e11)<fabsf(e01-e10))
{
elements->push_back(i01);
elements->push_back(i00);
elements->push_back(i11);
elements->push_back(i00);
elements->push_back(i10);
elements->push_back(i11);
}
else
{
elements->push_back(i01);
elements->push_back(i00);
elements->push_back(i10);
elements->push_back(i01);
elements->push_back(i10);
elements->push_back(i11);
}
}
else if (numValid==3)
{
if (i00>=0) elements->push_back(i00);
if (i01>=0) elements->push_back(i01);
if (i11>=0) elements->push_back(i11);
if (i10>=0) elements->push_back(i10);
}
}
}
osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*normals));
if (elevationLayer)
{
osgUtil::SmoothingVisitor smoother;
smoother.smooth(*geometry);
normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
if (!normals) createSkirt = false;
}
if (createSkirt)
{
osg::ref_ptr<osg::DrawElementsUShort> skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
// create bottom skirt vertices
int r,c;
r=0;
for(c=0;c<static_cast<int>(numColumns);++c)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
unsigned int new_i = vertices->size(); // index of new index of added skirt point
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
}
else
{
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
}
}
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
// create right skirt vertices
c=numColumns-1;
for(r=0;r<static_cast<int>(numRows);++r)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
unsigned int new_i = vertices->size(); // index of new index of added skirt point
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
}
else
{
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
}
}
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
// create top skirt vertices
r=numRows-1;
for(c=numColumns-1;c>=0;--c)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
unsigned int new_i = vertices->size(); // index of new index of added skirt point
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
}
else
{
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
}
}
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
// create left skirt vertices
c=0;
for(r=numRows-1;r>=0;--r)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
unsigned int new_i = vertices->size(); // index of new index of added skirt point
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
}
else
{
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
}
}
if (!skirtDrawElements->empty())
{
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
}
geometry->setUseDisplayList(false);
geometry->setUseVertexBufferObjects(true);
return geometry;
}
Here is the call graph for this function:
Here is the caller graph for this function:| osg::Geode * MultiPassTerrainTechnique::createPass | ( | unsigned int | order, |
| const CustomColorLayer * | layer, | ||
| osgTerrain::Locator * | masterLocator, | ||
| const osg::Vec3d & | centerModel, | ||
| osg::Geometry * | geometry | ||
| ) |
Definition at line 549 of file MultiPassTerrainTechnique.cpp.
{
OE_DEBUG << "osgEarth::MultiPassTerrainTechnique createPass " << order << std::endl;
unsigned int binNumber = 1000;
binNumber += order;
osgTerrain::Layer* elevationLayer = _tile->getElevationLayer();
//Create a new geode to store the geometry
osg::Geode* geode = new osg::Geode;
//Set up the pass
geode->getOrCreateStateSet()->setRenderBinDetails(binNumber, "RenderBin");
geode->addDrawable(geometry);
unsigned int numRows = 20;
unsigned int numColumns = 20;
if (elevationLayer)
{
numColumns = elevationLayer->getNumColumns();
numRows = elevationLayer->getNumRows();
}
float sampleRatio = _tile->getTerrain() ? _tile->getTerrain()->getSampleRatio() : 1.0f;
double i_sampleFactor = 1.0;
double j_sampleFactor = 1.0;
// OE_NOTICE<<"Sample ratio="<<sampleRatio<<std::endl;
if (sampleRatio!=1.0f)
{
unsigned int originalNumColumns = numColumns;
unsigned int originalNumRows = numRows;
numColumns = osg::maximum((unsigned int) (float(originalNumColumns)*sqrtf(sampleRatio)), 4u);
numRows = osg::maximum((unsigned int) (float(originalNumRows)*sqrtf(sampleRatio)),4u);
i_sampleFactor = double(originalNumColumns-1)/double(numColumns-1);
j_sampleFactor = double(originalNumRows-1)/double(numRows-1);
}
//bool treatBoundariesToValidDataAsDefaultValue = _terrainTile->getTreatBoundariesToValidDataAsDefaultValue();
//OE_DEBUG<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl;
float skirtHeight = 0.0f;
osgTerrain::HeightFieldLayer* hfl = dynamic_cast<osgTerrain::HeightFieldLayer*>(elevationLayer);
if (hfl && hfl->getHeightField())
{
skirtHeight = hfl->getHeightField()->getSkirtHeight();
}
bool createSkirt = skirtHeight != 0.0f;
unsigned int numVerticesInBody = numColumns*numRows;
unsigned int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0;
unsigned int numVertices = numVerticesInBody+numVerticesInSkirt;
//float minHeight = 0.0;
float scaleHeight = _tile->getTerrain() ? _tile->getTerrain()->getVerticalScale() : 1.0f;
osg::ref_ptr<osg::Vec2Array> texCoords;
const osgTerrain::Locator* locator = colorLayer ? colorLayer->getLocator() : 0L;
if ( locator )
{
texCoords = new osg::Vec2Array;
texCoords->reserve(numVertices);
_texCompositor->assignTexCoordArray( geometry, colorLayer->getUID(), texCoords.get() );
}
const osgTerrain::Locator* colorLocator = locator ? locator : masterLocator;
// allocate and assign color
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
geometry->setColorArray(colors.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
typedef std::vector<int> Indices;
Indices indices(numVertices, -1);
// populate vertex and tex coord arrays
unsigned int i, j;
int vindex = 0;
for(j=0; j<numRows; ++j)
{
for(i=0; i<numColumns; ++i)
{
unsigned int iv = j*numColumns + i;
osg::Vec3d ndc( ((double)i)/(double)(numColumns-1), ((double)j)/(double)(numRows-1), 0.0);
bool validValue = true;
unsigned int i_equiv = i_sampleFactor==1.0 ? i : (unsigned int) (double(i)*i_sampleFactor);
unsigned int j_equiv = i_sampleFactor==1.0 ? j : (unsigned int) (double(j)*j_sampleFactor);
if (elevationLayer)
{
float value = 0.0f;
validValue = elevationLayer->getValidValue(i_equiv,j_equiv, value);
// OE_INFO<<"i="<<i<<" j="<<j<<" z="<<value<<std::endl;
ndc.z() = value*scaleHeight;
}
if (validValue)
{
indices[iv] = vindex++;
if (texCoords.valid())
{
osg::Vec3d model;
masterLocator->convertLocalToModel(ndc, model);
if (colorLocator != masterLocator)
{
osg::Vec3d color_ndc;
osgTerrain::Locator::convertLocalCoordBetween(*masterLocator, ndc, *colorLocator, color_ndc);
texCoords->push_back(osg::Vec2(color_ndc.x(), color_ndc.y()));
}
else
{
texCoords->push_back(osg::Vec2(ndc.x(), ndc.y()));
}
}
}
else
{
indices[iv] = -1;
}
}
}
// populate primitive sets
// bool optimizeOrientations = elevations!=0;
// bool swapOrientation = !(masterLocator->orientationOpenGL());
if (createSkirt)
{
// create bottom skirt vertices
int r,c;
r=0;
for(c=0;c<static_cast<int>(numColumns);++c)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
if (texCoords.valid()) texCoords->push_back((*texCoords)[orig_i]);
}
}
// create right skirt vertices
c=numColumns-1;
for(r=0;r<static_cast<int>(numRows);++r)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
if (texCoords.valid()) texCoords->push_back((*texCoords)[orig_i]);
}
}
// create top skirt vertices
r=numRows-1;
for(c=numColumns-1;c>=0;--c)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
if (texCoords.valid()) texCoords->push_back((*texCoords)[orig_i]);
}
}
// create left skirt vertices
c=0;
for(r=numRows-1;r>=0;--r)
{
int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
if (orig_i>=0)
{
if (texCoords.valid()) texCoords->push_back((*texCoords)[orig_i]);
}
}
}
geometry->setUseDisplayList(false);
geometry->setUseVertexBufferObjects(true);
//TODO: Should we do this for each geode?
if (osgDB::Registry::instance()->getBuildKdTreesHint()==osgDB::ReaderWriter::Options::BUILD_KDTREES &&
osgDB::Registry::instance()->getKdTreeBuilder())
{
//osg::Timer_t before = osg::Timer::instance()->tick();
//OE_NOTICE<<"osgTerrain::GeometryTechnique::build kd tree"<<std::endl;
osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
//buffer._geode->accept(*builder);
geode->accept(*builder);
//osg::Timer_t after = osg::Timer::instance()->tick();
//OE_NOTICE<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
}
//Apply the appropriate color layer to the pass
if (colorLayer)
{
const osg::Image* image = colorLayer->getImage();
if (image)
{
//osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
//osgTerrain::ContourLayer* contourLayer = dynamic_cast<osgTerrain::ContourLayer*>(colorLayer);
//if (imageLayer)
//{
osg::StateSet* stateset = geode->getOrCreateStateSet();
//Compress the image if it's not compressed and it is requested that we compress textures
osg::Image* img = const_cast<osg::Image*>(image);
osg::Texture2D* texture2D = new osg::Texture2D;
texture2D->setImage( img );
texture2D->setMaxAnisotropy(16.0f);
texture2D->setResizeNonPowerOfTwoHint(false);
texture2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
if (ImageUtils::isPowerOfTwo( img ) && !(!img->isMipmap() && ImageUtils::isCompressed(img)))
{
texture2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
}
else
{
OE_DEBUG<<"[osgEarth::MultiPassTerrainTechnique] Disabling mipmapping for non power of two tile size("<<image->s()<<", "<<image->t()<<")"<<std::endl;
texture2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR );
}
texture2D->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
stateset->setTextureAttributeAndModes(0, texture2D, osg::StateAttribute::ON);
}
// }
// else if (contourLayer)
// {
// osg::StateSet* stateset = geode->getOrCreateStateSet();
// osg::Texture1D* texture1D = new osg::Texture1D;
// texture1D->setImage(image);
// texture1D->setResizeNonPowerOfTwoHint(false);
// texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
// texture1D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
// stateset->setTextureAttributeAndModes(0, texture1D, osg::StateAttribute::ON);
// }
//}
}
//geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
geode->getOrCreateStateSet()->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL), osg::StateAttribute::ON);
return geode;
}
Here is the call graph for this function:
Here is the caller graph for this function:| void MultiPassTerrainTechnique::generateGeometry | ( | osgTerrain::Locator * | masterLocator, |
| const osg::Vec3d & | centerModel | ||
| ) | [virtual] |
Definition at line 816 of file MultiPassTerrainTechnique.cpp.
{
_passes = new osg::Group;
if (_transform.valid())
{
_transform->removeChildren( 0, _transform->getNumChildren() );
_transform->addChild(_passes.get());
}
typedef std::map<int, osg::ref_ptr<osg::Geode> > OrderedGeodes;
OrderedGeodes order;
osg::ref_ptr<osg::Geometry> prototype = createGeometryPrototype( masterLocator, centerModel );
// take a thread-safe snapshot of the layer stack:
TileFrame tilef( _tile );
if ( tilef._colorLayers.size() == 0 )
{
// if there's no data, just make a placeholder pass
osg::Geode* geode = createPass(0, 0L, masterLocator, centerModel, prototype.get());
_passes->addChild( geode );
}
else
{
int defaultLayerOrder = 0;
// create a pass for each layer, and then add them in the proper order:
for( ColorLayersByUID::const_iterator i = tilef._colorLayers.begin(); i != tilef._colorLayers.end(); ++i )
{
const CustomColorLayer& layer = i->second;
osg::Geometry* passGeom = new osg::Geometry( *prototype.get() );
int index = _texCompositor->getRenderOrder( layer.getUID() );
if ( index < 0 ) // true on first-time initialization
index = defaultLayerOrder++;
osg::Geode* geode = createPass( index, &layer, masterLocator, centerModel, passGeom );
order[index] = geode;
// record the UID in the geode for lookup later:
geode->setUserData( new LayerData( layer.getUID() ) );
}
for( OrderedGeodes::const_iterator j = order.begin(); j != order.end(); ++j )
{
_passes->addChild( j->second.get() );
}
}
osg::StateSet* stateset = _transform->getOrCreateStateSet();
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
Here is the call graph for this function:
Here is the caller graph for this function:| void MultiPassTerrainTechnique::init | ( | ) | [virtual] |
Implements TerrainTechnique.
Definition at line 98 of file MultiPassTerrainTechnique.cpp.
{
OE_DEBUG<<"Doing MultiPassTerrainTechnique::init()"<<std::endl;
if (!_tile) return;
osgTerrain::Locator* masterLocator = computeMasterLocator();
osg::Vec3d centerModel = computeCenterModel(masterLocator);
generateGeometry(masterLocator, centerModel);
if (_transform.valid()) _transform->setThreadSafeReferenceCounting(true);
}
Here is the call graph for this function:| MultiPassTerrainTechnique::META_Object | ( | osgEarth | , |
| MultiPassTerrainTechnique | |||
| ) |
| void MultiPassTerrainTechnique::releaseGLObjects | ( | osg::State * | state = 0 | ) | const [virtual] |
If State is non-zero, this function releases any associated OpenGL objects for the specified graphics context. Otherwise, releases OpenGL objects for all graphics contexts.
Implements TerrainTechnique.
Definition at line 936 of file MultiPassTerrainTechnique.cpp.
{
if (_transform.valid()) _transform->releaseGLObjects( state );
}
| void MultiPassTerrainTechnique::traverse | ( | osg::NodeVisitor & | nv | ) | [virtual] |
Traverse the terain subgraph.
Implements TerrainTechnique.
Definition at line 869 of file MultiPassTerrainTechnique.cpp.
{
if (!_tile) return;
// initialize the terrain tile on startup
if (_tile->getDirty() && !_terrainTileInitialized)
{
_tile->init();
_terrainTileInitialized = true;
#if 0
#if OSG_MIN_VERSION_REQUIRED(2,9,8)
_terrainTile->init(~0x0, true);
#else
_terrainTile->init();
#endif
_terrainTileInitialized = true;
#endif
}
if ( nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR )
{
updateTransparency();
}
// traverse the dynamically-generated geometry.
if (_transform.valid())
_transform->accept(nv);
}
Here is the call graph for this function:| void MultiPassTerrainTechnique::updateGeometry | ( | ) | [private] |
| void MultiPassTerrainTechnique::updateTransparency | ( | ) | [private] |
Definition at line 900 of file MultiPassTerrainTechnique.cpp.
{
if ( _passes.valid() )
{
ColorLayersByUID colorLayers;
_tile->getCustomColorLayers( colorLayers );
for( ColorLayersByUID::const_iterator i = colorLayers.begin(); i != colorLayers.end(); ++i )
{
const CustomColorLayer& colorLayer = i->second;
float opacity = colorLayer.getMapLayer()->getOpacity();
osg::Geode* geode = s_findGeodeByUID( _passes.get(), colorLayer.getUID() );
if (geode)
{
osg::Geometry* geometry = geode->getDrawable(0)->asGeometry();
osg::Vec4Array* colors = static_cast<osg::Vec4Array*>(geometry->getColorArray());
if ( (*colors)[0].a() != opacity )
{
(*colors)[0] = osg::Vec4(1.0f, 1.0f, 1.0f, opacity);
colors->dirty();
}
if (colorLayer.getMapLayer()->getEnabled())
{
geode->setNodeMask(0xffffffff);
}
else
{
geode->setNodeMask(0x0);
}
}
}
}
}
Here is the call graph for this function:
Here is the caller graph for this function:osg::ref_ptr<osg::Group> MultiPassTerrainTechnique::_passes [private] |
Definition at line 76 of file MultiPassTerrainTechnique.
bool MultiPassTerrainTechnique::_terrainTileInitialized [private] |
Definition at line 77 of file MultiPassTerrainTechnique.
osg::ref_ptr<TextureCompositor> MultiPassTerrainTechnique::_texCompositor [private] |
Definition at line 78 of file MultiPassTerrainTechnique.
osg::ref_ptr<osg::MatrixTransform> MultiPassTerrainTechnique::_transform [private] |
Definition at line 75 of file MultiPassTerrainTechnique.
1.7.3