openscenegraph
LOD
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_LOD
15#define OSG_LOD 1
16
17#include <osg/Group>
18
19namespace osg {
20
21/** LOD - Level Of Detail group node which allows switching between children
22 depending on distance from eye point.
23 Typical uses are for load balancing - objects further away from
24 the eye point are rendered at a lower level of detail, and at times
25 of high stress on the graphics pipeline lower levels of detail can
26 also be chosen by adjusting the viewers's Camera/CullSettings LODScale value.
27 Each child has a corresponding valid range consisting of a minimum
28 and maximum distance. Given a distance to the viewer (d), LOD displays
29 a child if min <= d < max. LOD may display multiple children simultaneously
30 if their corresponding ranges overlap. Children can be in any order,
31 and don't need to be sorted by range or amount of detail. If the number of
32 ranges (m) is less than the number of children (n), then children m+1 through
33 n are ignored.
34*/
35class OSG_EXPORT LOD : public Group
36{
37 public :
38
39 /** Default constructor
40 * The default constructor sets
41 * - the center mode to USE_BOUNDING_SPHERE,
42 * - the radius to a value smaller than zero and
43 * - the range mode to DISTANCE_FROM_EYE_POINT. */
44 LOD();
45
46 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
47 LOD(const LOD&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
48
49 META_Node(osg, LOD);
50
51 typedef osg::BoundingSphere::vec_type vec_type;
52 typedef osg::BoundingSphere::value_type value_type;
53
54 virtual void traverse(NodeVisitor& nv);
55
56 using osg::Group::addChild;
57
58 virtual bool addChild(Node *child);
59
60 virtual bool addChild(Node *child, float rmin, float rmax);
61
62 template<class T> bool addChild( const ref_ptr<T>& child, float rmin, float rmax) { return addChild(child.get(), rmin, rmax); }
63
64 virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove=1);
65
66 typedef std::pair<float,float> MinMaxPair;
67 typedef std::vector<MinMaxPair> RangeList;
68
69 /** Modes which control how the center of object should be determined when computing which child is active.
70 * Furthermore it determines how the bounding sphere is calculated. */
71 enum CenterMode
72 {
73 USE_BOUNDING_SPHERE_CENTER, ///< Uses the bounding sphere's center as the center of object and the geometrical bounding sphere of the node's children
74 USER_DEFINED_CENTER, ///< Uses the user defined center as the center of object; the bounding sphere is determined by the user defined center and user defined radius
75 UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED ///< Uses the user defined center as the center of object; the bounding sphere is the user defined bounding sphere expanded by the geometrical bounding sphere of the node's children
76 };
77
78 /** Set how the center of object should be determined when computing which child is active.*/
79 void setCenterMode(CenterMode mode) { _centerMode=mode; }
80
81 /** Get how the center of object should be determined when computing which child is active.*/
82 CenterMode getCenterMode() const { return _centerMode; }
83
84 /** Sets the object-space point which defines the center of the osg::LOD.
85 * center is affected by any transforms in the hierarchy above the osg::LOD.
86 * @note This method also changes the center mode to USER_DEFINED_CENTER
87 * if the current center mode does not use a user defined center!
88 * @sa setRadius */
89 inline void setCenter(const vec_type& center) { if (_centerMode!=UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED) { _centerMode=USER_DEFINED_CENTER; } _userDefinedCenter = center; }
90
91 /** return the LOD center point. */
92 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(); }
93
94
95 /** Set the object-space reference radius of the volume enclosed by the LOD.
96 * @param radius Radius must be larger or equal to zero. If the radius is smaller than zero the geometrical bounding sphere
97 * of the node's children is used as the LOD's bounding sphere regardless of the center mode setting.
98 * @remark The radius is only used to calculate the bounding sphere.
99 * @sa setCenter */
100 inline void setRadius(value_type radius) { _radius = radius; }
101
102 /** Get the object-space radius of the volume enclosed by the LOD.*/
103 inline value_type getRadius() const { return _radius; }
104
105 /** Modes that control how the range values should be interpreted when computing which child is active.*/
106 enum RangeMode
107 {
108 DISTANCE_FROM_EYE_POINT,
109 PIXEL_SIZE_ON_SCREEN
110 };
111
112 /** Set how the range values should be interpreted when computing which child is active.*/
113 void setRangeMode(RangeMode mode) { _rangeMode = mode; }
114
115 /** Get how the range values should be interpreted when computing which child is active.*/
116 RangeMode getRangeMode() const { return _rangeMode; }
117
118
119 /** Sets the min and max visible ranges of range of specific child.
120 Values are floating point distance specified in local objects coordinates.*/
121 void setRange(unsigned int childNo, float min,float max);
122
123 /** returns the min visible range for specified child.*/
124 inline float getMinRange(unsigned int childNo) const { return _rangeList[childNo].first; }
125
126 /** returns the max visible range for specified child.*/
127 inline float getMaxRange(unsigned int childNo) const { return _rangeList[childNo].second; }
128
129 /** returns the number of ranges currently set.
130 * An LOD which has been fully set up will have getNumChildren()==getNumRanges(). */
131 inline unsigned int getNumRanges() const { return static_cast<unsigned int>(_rangeList.size()); }
132
133 /** set the list of MinMax ranges for each child.*/
134 inline void setRangeList(const RangeList& rangeList) { _rangeList=rangeList; }
135
136 /** return the list of MinMax ranges for each child.*/
137 inline const RangeList& getRangeList() const { return _rangeList; }
138
139 virtual BoundingSphere computeBound() const;
140
141 protected :
142 virtual ~LOD() {}
143
144 CenterMode _centerMode;
145 vec_type _userDefinedCenter;
146 value_type _radius;
147
148 RangeMode _rangeMode;
149 RangeList _rangeList;
150
151};
152
153}
154
155#endif