OpenSceneGraph/include/osg/ProxyNode
Robert Osfield 8a230d42ed From Luc Frauciel, "You'll find attached a new option that allow, when using LOD in USER_DEFINED_CENTER mode to expand the radius of the node by the radius of loaded objets.
Motivation ;
When using PagedLODs, you don't always know the real size of loaded children,
If it occurs that they  are out of predefined bounds, picking on the parts that are out of bound will fail
They also can be culled out too soon.
The problem often  occurs with long object (roads).
I've modified LOD and ProxyNode to include this option."

and later email:

"Attached the UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED version
There are impacts on some serializers (dae, osgWrapper).
I haven't modified deprecated osg, since it's deprecated"
2011-09-19 10:34:31 +00:00

143 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_ProxyNode
#define OSG_ProxyNode 1
#include <osg/Group>
namespace osg {
/** ProxyNode.
*/
class OSG_EXPORT ProxyNode : public Group
{
public :
ProxyNode();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
ProxyNode(const ProxyNode&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Node(osg, ProxyNode);
typedef osg::BoundingSphere::vec_type vec_type;
typedef osg::BoundingSphere::value_type value_type;
virtual void traverse(NodeVisitor& nv);
virtual bool addChild(Node *child);
virtual bool addChild(Node *child, const std::string& filename);
virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove);
/** Set the optional database osgDB::Options object to use when loaded children.*/
void setDatabaseOptions(osg::Referenced* options) { _databaseOptions = options; }
/** Get the optional database osgDB::Options object used when loaded children.*/
osg::Referenced* getDatabaseOptions() { return _databaseOptions.get(); }
/** Get the optional database osgDB::Options object used when loaded children.*/
const osg::Referenced* getDatabaseOptions() const { return _databaseOptions.get(); }
/** 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; }
void setFileName(unsigned int childNo, const std::string& filename) { expandFileNameListTo(childNo); _filenameList[childNo].first=filename; }
const std::string& getFileName(unsigned int childNo) const { return _filenameList[childNo].first; }
unsigned int getNumFileNames() const { return _filenameList.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 _filenameList[childNo].second; }
/** Return the const DatabaseRequest object.*/
const osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) const { return _filenameList[childNo].second; }
/** Modes which control how the center of object should be determined when computed which child is active.*/
enum CenterMode
{
USE_BOUNDING_SPHERE_CENTER,
USER_DEFINED_CENTER,
UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED
};
/** Set how the center of object should be determined when computed which child is active.*/
void setCenterMode(CenterMode mode) { _centerMode=mode; }
/** Get how the center of object should be determined when computed which child is active.*/
CenterMode getCenterMode() const { return _centerMode; }
/** Modes which control how the proxynode external reference are loaded.*/
enum LoadingExternalReferenceMode
{
LOAD_IMMEDIATELY,
DEFER_LOADING_TO_DATABASE_PAGER,
NO_AUTOMATIC_LOADING
};
/** Set how the child loading is done.*/
void setLoadingExternalReferenceMode(LoadingExternalReferenceMode mode) { _loadingExtReference=mode; }
/** Get the setted mode of loading.*/
LoadingExternalReferenceMode getLoadingExternalReferenceMode() const { return _loadingExtReference; }
/** Sets the object-space point which defines the center of the osg::ProxyNode.
center is affected by any transforms in the hierarchy above the osg::ProxyNode.*/
inline void setCenter(const vec_type& center) { if (_centerMode!=UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED) { _centerMode=USER_DEFINED_CENTER; } _userDefinedCenter = center; }
/** return the ProxyNode center point. */
inline const vec_type& getCenter() const { if ((_centerMode==USER_DEFINED_CENTER)||(_centerMode==UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED)) return _userDefinedCenter; else return getBound().center(); }
/** Set the object-space reference radius of the volume enclosed by the ProxyNode.
* Used to determine the bounding sphere of the ProxyNode in the absence of any children.*/
inline void setRadius(value_type radius) { _radius = radius; }
/** Get the object-space radius of the volume enclosed by the ProxyNode.*/
inline value_type getRadius() const { return _radius; }
virtual BoundingSphere computeBound() const;
protected :
virtual ~ProxyNode() {}
void expandFileNameListTo(unsigned int pos);
typedef std::pair< std::string, osg::ref_ptr<osg::Referenced> > FileNameDatabaseRequestPair;
typedef std::vector<FileNameDatabaseRequestPair> FileNameDatabaseRequestList;
FileNameDatabaseRequestList _filenameList;
ref_ptr<Referenced> _databaseOptions;
std::string _databasePath;
LoadingExternalReferenceMode _loadingExtReference;
CenterMode _centerMode;
vec_type _userDefinedCenter;
value_type _radius;
};
}
#endif