Reorginized the TerrainTile/TerrainTechnique dirty mechanism so that TerrainTile

now holds the dirty flag and enables/disables event traversal in response dirty
being set/unset.  This allows terrain to be automatically updated in response
to Terrain scale and sample ratio changes.
This commit is contained in:
Robert Osfield
2008-05-27 15:30:20 +00:00
parent aee0e8dc37
commit 4d60d73eca
7 changed files with 59 additions and 53 deletions

View File

@@ -57,10 +57,6 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique
virtual void cleanSceneGraph();
virtual void dirty();
void setFilterBias(float filterBias);
float getFilterBias() const { return _filterBias; }

View File

@@ -51,20 +51,15 @@ class OSGTERRAIN_EXPORT TerrainTechnique : public osg::Object
/** Traverse the terrain subgraph.*/
virtual void traverse(osg::NodeVisitor& nv);
/** Dirty so that cached data structures will be updated on next use.*/
virtual void dirty();
/** Return true if cached data structures need updating.*/
virtual bool isDirty() const { return _dirty; }
protected:
void setDirty(bool dirty);
virtual ~TerrainTechnique();
friend class osgTerrain::TerrainTile;
TerrainTile* _terrainTile;
bool _dirty;
};

View File

@@ -160,6 +160,11 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
/** Get whether the TeatBoundariesToValidDataAsDefaultValue hint.*/
bool getTreatBoundariesToValidDataAsDefaultValue() const { return _treatBoundariesToValidDataAsDefaultValue; }
/** Set the dirty flag on/off.*/
void setDirty(bool dirty);
/** return true if the tile is dirty and needs to be updated,*/
bool getDirty() const { return _dirty; }
/** Compute the bounding volume of the terrain by computing the union of the bounding volumes of all layers.*/
virtual osg::BoundingSphere computeBound() const;
@@ -168,12 +173,14 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
virtual ~TerrainTile();
typedef std::vector< osg::ref_ptr<Layer> > Layers;
friend class Terrain;
Terrain* _terrain;
bool _dirty;
bool _hasBeenTraversal;
TileID _tileID;

View File

@@ -101,7 +101,7 @@ void GeometryTechnique::setFilterMatrixAs(FilterType filterType)
void GeometryTechnique::init()
{
// osg::notify(osg::NOTICE)<<"Doing GeometryTechnique::init()"<<std::endl;
osg::notify(osg::INFO)<<"Doing GeometryTechnique::init()"<<std::endl;
if (!_terrainTile) return;
@@ -120,8 +120,6 @@ void GeometryTechnique::init()
if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true);
_dirty = false;
swapBuffers();
}
@@ -777,7 +775,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv)
// if app traversal update the frame count.
if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
{
if (_dirty) _terrainTile->init();
if (_terrainTile->getDirty()) _terrainTile->init();
osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
if (uv)
@@ -798,7 +796,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv)
}
if (_dirty)
if (_terrainTile->getDirty())
{
osg::notify(osg::INFO)<<"******* Doing init ***********"<<std::endl;
_terrainTile->init();
@@ -813,8 +811,3 @@ void GeometryTechnique::cleanSceneGraph()
{
}
void GeometryTechnique::dirty()
{
TerrainTechnique::dirty();
}

View File

@@ -79,14 +79,7 @@ void Terrain::dirtyRegisteredTiles()
itr != _terrainTileSet.end();
++itr)
{
TerrainTechnique* tt = const_cast<TerrainTile*>(*itr)->getTerrainTechnique();
if(tt)
{
tt->dirty();
// Force recreation of Geometry
// const_cast<TerrainTile*>(*itr)->init();
}
(const_cast<TerrainTile*>(*itr))->setDirty(true);
}
}

View File

@@ -17,16 +17,14 @@
using namespace osgTerrain;
TerrainTechnique::TerrainTechnique():
_terrainTile(0),
_dirty(true)
_terrainTile(0)
{
setThreadSafeRefUnref(true);
}
TerrainTechnique::TerrainTechnique(const TerrainTechnique& TerrainTechnique,const osg::CopyOp& copyop):
osg::Object(TerrainTechnique,copyop),
_terrainTile(0),
_dirty(true)
_terrainTile(0)
{
}
@@ -37,8 +35,6 @@ TerrainTechnique::~TerrainTechnique()
void TerrainTechnique::init()
{
osg::notify(osg::NOTICE)<<className()<<"::initialize(..) not implementated yet"<<std::endl;
_dirty = false;
}
void TerrainTechnique::update(osgUtil::UpdateVisitor* uv)
@@ -58,12 +54,6 @@ void TerrainTechnique::cleanSceneGraph()
osg::notify(osg::NOTICE)<<className()<<"::cleanSceneGraph(..) not implementated yet"<<std::endl;
}
void TerrainTechnique::dirty()
{
// osg::notify(osg::NOTICE)<<className()<<"::dirty(..) not implemented yet"<<std::endl;
_dirty = true;
}
void TerrainTechnique::traverse(osg::NodeVisitor& nv)
{
if (!_terrainTile) return;
@@ -71,7 +61,7 @@ void TerrainTechnique::traverse(osg::NodeVisitor& nv)
// if app traversal update the frame count.
if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
{
if (_dirty) _terrainTile->init();
if (_terrainTile->getDirty()) _terrainTile->init();
osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
if (uv)
@@ -91,7 +81,7 @@ void TerrainTechnique::traverse(osg::NodeVisitor& nv)
}
}
if (_dirty) _terrainTile->init();
if (_terrainTile->getDirty()) _terrainTile->init();
// otherwise fallback to the Group::traverse()
_terrainTile->osg::Group::traverse(nv);

View File

@@ -23,9 +23,9 @@ TerrainTile::TerrainTile():
_terrain(0),
_hasBeenTraversal(false),
_requiresNormals(true),
_treatBoundariesToValidDataAsDefaultValue(false)
_treatBoundariesToValidDataAsDefaultValue(false),
_dirty(false)
{
//setNumChildrenRequiringUpdateTraversal(1);
setThreadSafeRefUnref(true);
}
@@ -36,11 +36,13 @@ TerrainTile::TerrainTile(const TerrainTile& terrain,const osg::CopyOp& copyop):
_elevationLayer(terrain._elevationLayer),
_colorLayers(terrain._colorLayers),
_requiresNormals(terrain._requiresNormals),
_treatBoundariesToValidDataAsDefaultValue(terrain._treatBoundariesToValidDataAsDefaultValue)
_treatBoundariesToValidDataAsDefaultValue(terrain._treatBoundariesToValidDataAsDefaultValue),
_dirty(false)
{
//setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
if (terrain.getTerrainTechnique()) setTerrainTechnique(dynamic_cast<TerrainTechnique*>(terrain.getTerrainTechnique()->cloneType()));
if (terrain.getTerrainTechnique())
{
setTerrainTechnique(dynamic_cast<TerrainTechnique*>(terrain.getTerrainTechnique()->cloneType()));
}
}
TerrainTile::~TerrainTile()
@@ -118,9 +120,11 @@ void TerrainTile::traverse(osg::NodeVisitor& nv)
void TerrainTile::init()
{
if (_terrainTechnique.valid() && _terrainTechnique->isDirty())
if (_terrainTechnique.valid() && getDirty())
{
_terrainTechnique->init();
setDirty(false);
}
}
@@ -128,14 +132,42 @@ void TerrainTile::setTerrainTechnique(TerrainTechnique* terrainTechnique)
{
if (_terrainTechnique == terrainTechnique) return;
if (_terrainTechnique.valid()) _terrainTechnique->_terrainTile = 0;
int dirtyDelta = _dirty ? -1 : 0;
if (_terrainTechnique.valid())
{
_terrainTechnique->_terrainTile = 0;
}
_terrainTechnique = terrainTechnique;
if (_terrainTechnique.valid()) _terrainTechnique->_terrainTile = this;
if (_terrainTechnique.valid())
{
_terrainTechnique->_terrainTile = this;
++dirtyDelta;
}
if (dirtyDelta>0) setDirty(true);
else if (dirtyDelta<0) setDirty(false);
}
void TerrainTile::setDirty(bool dirty)
{
if (_dirty==dirty) return;
_dirty = dirty;
if (_dirty)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
}
else if (getNumChildrenRequiringUpdateTraversal()>0)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
}
}
void TerrainTile::setElevationLayer(Layer* layer)
{