OpenSceneGraph/include/osg/PagedLOD
Robert Osfield 7b003b24ea Refactored DatabasePager and related classes to introduce support for
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.
2008-05-21 21:09:45 +00:00

138 lines
6.1 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_PagedLOD
#define OSG_PagedLOD 1
#include <osg/LOD>
namespace osg {
/** PagedLOD.
*/
class OSG_EXPORT PagedLOD : public LOD
{
public :
PagedLOD();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
PagedLOD(const PagedLOD&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Node(osg, PagedLOD);
virtual void traverse(NodeVisitor& nv);
virtual bool addChild(Node *child);
virtual bool addChild(Node *child, float min, float max);
virtual bool addChild(Node *child, float min, float max,const std::string& filename, float priorityOffset=0.0f, float priorityScale=1.0f);
virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove=1);
/** Set the database path to prepend to children's filenames.*/
void setDatabasePath(const std::string& path);
/** Get the database path used to prepend to children's filenames.*/
inline const std::string& getDatabasePath() const { return _databasePath; }
struct OSG_EXPORT PerRangeData
{
PerRangeData();
PerRangeData(const PerRangeData& prd);
PerRangeData& operator = (const PerRangeData& prd);
std::string _filename;
float _priorityOffset;
float _priorityScale;
double _timeStamp;
osg::ref_ptr<osg::Referenced> _databaseRequest;
};
typedef std::vector<PerRangeData> PerRangeDataList;
void setFileName(unsigned int childNo, const std::string& filename) { expandPerRangeDataTo(childNo); _perRangeDataList[childNo]._filename=filename; }
const std::string& getFileName(unsigned int childNo) const { return _perRangeDataList[childNo]._filename; }
unsigned int getNumFileNames() const { return _perRangeDataList.size(); }
void setPriorityOffset(unsigned int childNo, float priorityOffset) { expandPerRangeDataTo(childNo); _perRangeDataList[childNo]._priorityOffset=priorityOffset; }
float getPriorityOffset(unsigned int childNo) const { return _perRangeDataList[childNo]._priorityOffset; }
unsigned int getNumPriorityOffsets() const { return _perRangeDataList.size(); }
void setPriorityScale(unsigned int childNo, float priorityScale) { expandPerRangeDataTo(childNo); _perRangeDataList[childNo]._priorityScale=priorityScale; }
float getPriorityScale(unsigned int childNo) const { return _perRangeDataList[childNo]._priorityScale; }
unsigned int getNumPriorityScales() const { return _perRangeDataList.size(); }
void setTimeStamp(unsigned int childNo, double timeStamp) { expandPerRangeDataTo(childNo); _perRangeDataList[childNo]._timeStamp=timeStamp; }
double getTimeStamp(unsigned int childNo) const { return _perRangeDataList[childNo]._timeStamp; }
unsigned int getNumTimeStamps() const { return _perRangeDataList.size(); }
/** Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests
* being carried on behalf of the DatabasePager.
* Note, in normal OSG usage you should not set this value yourself, as this will be managed by
* the osgDB::DatabasePager.*/
osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) { return _perRangeDataList[childNo]._databaseRequest; }
/** Return the const DatabaseRequest object.*/
const osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) const { return _perRangeDataList[childNo]._databaseRequest; }
/** Set the frame number of the last time that this PageLOD node was traversed.
* Note, this frame number is automatically set by the traverse() method for all traversals (update, cull etc.).
*/
inline void setFrameNumberOfLastTraversal(int frameNumber) { _frameNumberOfLastTraversal=frameNumber; }
/** Get the frame number of the last time that this PageLOD node was traversed.*/
inline int getFrameNumberOfLastTraversal() const { return _frameNumberOfLastTraversal; }
/** Set the number of children that the PagedLOD must keep around, even if they 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 they are older than their expiry time.*/
unsigned int getNumChildrenThatCannotBeExpired() const { return _numChildrenThatCannotBeExpired; }
/** Remove the children from the PagedLOD which haven't been visited since specified expiry time.
* The removed children are added to the removeChildren list passed into the method,
* this allows the children to be deleted later at the caller's discretion.
* Return true if children are removed, false otherwise. */
virtual bool removeExpiredChildren(double expiryTime,NodeList& removedChildren);
protected :
virtual ~PagedLOD() {}
void expandPerRangeDataTo(unsigned int pos);
std::string _databasePath;
int _frameNumberOfLastTraversal;
unsigned int _numChildrenThatCannotBeExpired;
PerRangeDataList _perRangeDataList;
};
}
#endif