I found that some of the items that had been paged in were being expired on the first frame that they were not visible (as the cache was full). This resulted in excessive paging every time the view was moved. With the following changes I could only allow children to be expired if they had not been used for e.g. 30 seconds or 60 frames."
Fixes to race in DatabasePager where a parent PagedLOD
of newly loaded subgraph has been expired.
Clean up of visitor naming to make it clearer what role it has.
The DatabasePager now passes the Terrain pointer into the ReaderWriter's via osgDB::Options object,
rather than pushing a NodePath containing the Terrain onto NodeVisitor. This
change means that the DatabasePager nolonger needs to observer the whole NodePath and
will be lighter and quicker for it.
The change also means that ReadFileCallback can now run custom NodeVisitor's on the scene graph without
having to worry about TerrainTile's constructing scene graphs prior to the Terrain being assigned.
Also changed is the NodeVisitor::DatabaseRequestHandler which now requires a NodePath to the node that you wish
to add to rather than just the pointer to the node you wish to add to. This is more robust when handling scenes
with multiple parental paths, whereas previously errors could have occurred due to the default of picking the first
available parental path. This change means that subclasses of DatabasePager will need to be updated to use this new
function entry point.
Introduced a new callback osgDB::FindFileCallback that overrides the default behavior of findDataFile/findLibraryFile.
Introduced support for assigning ReaderWriter::Options directory to PagedLOD.
Introduced new osgDB::FileLocationCallback for assistancing the DatabasePager to know when a file is hosted on a local or remote file system.
New attribute DatabasePager::_expiryFrames sets number of frames a PagedLOD child is kept in memory. The attribute is set with DatabasePager::setExpiryFrames method or OSG_EXPIRY_FRAMES environmental variable.
New attribute PagedLOD::PerRangeData::_
frameNumber contains frame number of last cull traversal.
Children of PagedLOD are expired when time _AND_ number of frames since last cull traversal exceed OSG_EXPIRY_DELAY _AND_ OSG_EXPIRY_FRAMES respectively. By default OSG_EXPIRY_FRAMES = 1 which means that nodes from last cull/rendering
traversal will not be expired even if last cull time exceeds OSG_EXPIRY_DELAY. Setting OSG_EXPIRY_FRAMES = 0 revokes previous behaviour of PagedLOD.
Setting OSG_EXPIRY_FRAMES > 0 fixes problems of children reloading in lazy rendering applications. Required behaviour is achieved by manipulating OSG_EXPIRY_DELAY and OSG_EXPIRY_FRAMES together.
Two interface changes are made:
DatabasePager::updateSceneGraph(double currentFrameTime) is replaced by DatabasePager::updateSceneGraph(const osg::FrameStamp &frameStamp). The previous method is in #if 0 clause in the header file. Robert, decide if You want to include it.
PagedLOD::removeExpiredChildren(double expiryTime, NodeList &removedChildren) is deprecated (warning is printed), when subclassing use PagedLOD::removeExpiredChildren(double expiryTime, int expiryFrame, NodeList &removedChildren) instead. "
multi-threaded paging, where the Pager manages threads of reading local
and http files via seperate threads. This makes it possible to smoothly
browse large databases where parts of the data are locally cached while
others are on a remote server. Previously with this type of dataset
the pager would stall all paging while http requests were being served,
even when parts of the models are still loadable virtue of being in the
local cache.
Also as part of the refactoring the DatabaseRequest are now stored in the
ProxyNode/PagedLOD nodes to facilitate quite updating in the cull traversal,
with the new code avoiding mutex locks and searches. Previous on big
databases the overhead involved in make database requests could accumulate
to a point where it'd cause the cull traversal to break frame. The overhead
now is negligable.
Finally OSG_FILE_CACHE support has been moved from the curl plugin into
the DatabasePager. Eventually this functionality will be moved out into
osgDB for more general usage.
that removeChild(Node*), removeChild(uint) and equivilant Geode methods are
now inline methods, not designed to be overriden, and seperated out the
multiple remove method to be called removeChildren(uint, uint) which is
now the only virtual method. There removeChildren is now the method to
override in subclasses.
This reorganisation requires some call code to be rename removeChild usage
to removeChildren.
Spelling fixes in include/osg/LOD
Negated priority in PagedLOD when using _rangeMode==PIXEL_SIZE_ON_SCREEN
Added clampedPixelSize() methods to CullStack and CullingSet to return fabs()ed values.
Changed LOD and PagedLOD ::traverse to use clampedPixelSize() methods.
osg::PagedLOD::s/getDatabasePath() and support in PagedLOD::traverse().
osgDB::ReaderWriter::Options::s/getDatabasePath()
osgDB::Input::s/getOptions()
setting of osgDB::Input::setOptions() in ReaderWriterOSG.cpp
src/osgPlugins/ive/DataInputStream::s/getOptions()
setting of src/osgPlugins/ive/DataInputStream::setOptions() in ReaderWriterIVE.cpp
/** Set the object-space reference radius of the volume enclosed by the PagedLOD.
* Used to detmine the bounding sphere of the PagedLOD in the absense of any children.*/
inline void setRadius(float radius) { _radius = radius; }
/** Get the object-space radius of the volume enclosed by the PagedLOD.*/
inline float getRadius() const { return _radius; }
/** Set the number of children that the PagedLOD must keep around, even if thay are older than their expiry time.*/
inline void setNumChildrenThatCannotBeExpired(unsigned int num) { _numChildrenThatCannotBeExpired = num; }
/** Get the number of children that the PagedLOD must keep around, even if thay are older than their expiry time.*/
unsigned int getNumChildrenThatCannotBeExpired() const { return _numChildrenThatCannotBeExpired; }