| 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 | |
|---|
| 19 | namespace 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 | */ |
|---|
| 35 | class OSG_EXPORT LOD : public Group |
|---|
| 36 | { |
|---|
| 37 | public : |
|---|
| 38 | |
|---|
| 39 | LOD(); |
|---|
| 40 | |
|---|
| 41 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 42 | LOD(const LOD&,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 43 | |
|---|
| 44 | META_Node(osg, LOD); |
|---|
| 45 | |
|---|
| 46 | typedef osg::BoundingSphere::vec_type vec_type; |
|---|
| 47 | typedef osg::BoundingSphere::value_type value_type; |
|---|
| 48 | |
|---|
| 49 | virtual void traverse(NodeVisitor& nv); |
|---|
| 50 | |
|---|
| 51 | virtual bool addChild(Node *child); |
|---|
| 52 | |
|---|
| 53 | virtual bool addChild(Node *child, float min, float max); |
|---|
| 54 | |
|---|
| 55 | virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove=1); |
|---|
| 56 | |
|---|
| 57 | typedef std::pair<float,float> MinMaxPair; |
|---|
| 58 | typedef std::vector<MinMaxPair> RangeList; |
|---|
| 59 | |
|---|
| 60 | /** Modes which control how the center of object should be determined when computing which child is active.*/ |
|---|
| 61 | enum CenterMode |
|---|
| 62 | { |
|---|
| 63 | USE_BOUNDING_SPHERE_CENTER, |
|---|
| 64 | USER_DEFINED_CENTER, |
|---|
| 65 | UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED |
|---|
| 66 | }; |
|---|
| 67 | |
|---|
| 68 | /** Set how the center of object should be determined when computing which child is active.*/ |
|---|
| 69 | void setCenterMode(CenterMode mode) { _centerMode=mode; } |
|---|
| 70 | |
|---|
| 71 | /** Get how the center of object should be determined when computing which child is active.*/ |
|---|
| 72 | CenterMode getCenterMode() const { return _centerMode; } |
|---|
| 73 | |
|---|
| 74 | /** Sets the object-space point which defines the center of the osg::LOD. |
|---|
| 75 | center is affected by any transforms in the hierarchy above the osg::LOD.*/ |
|---|
| 76 | inline void setCenter(const vec_type& center) { if (_centerMode!=UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED) { _centerMode=USER_DEFINED_CENTER; } _userDefinedCenter = center; } |
|---|
| 77 | |
|---|
| 78 | /** return the LOD center point. */ |
|---|
| 79 | 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(); } |
|---|
| 80 | |
|---|
| 81 | |
|---|
| 82 | /** Set the object-space reference radius of the volume enclosed by the LOD. |
|---|
| 83 | * Used to determine the bounding sphere of the LOD in the absence of any children.*/ |
|---|
| 84 | inline void setRadius(value_type radius) { _radius = radius; } |
|---|
| 85 | |
|---|
| 86 | /** Get the object-space radius of the volume enclosed by the LOD.*/ |
|---|
| 87 | inline value_type getRadius() const { return _radius; } |
|---|
| 88 | |
|---|
| 89 | /** Modes that control how the range values should be interpreted when computing which child is active.*/ |
|---|
| 90 | enum RangeMode |
|---|
| 91 | { |
|---|
| 92 | DISTANCE_FROM_EYE_POINT, |
|---|
| 93 | PIXEL_SIZE_ON_SCREEN |
|---|
| 94 | }; |
|---|
| 95 | |
|---|
| 96 | /** Set how the range values should be interpreted when computing which child is active.*/ |
|---|
| 97 | void setRangeMode(RangeMode mode) { _rangeMode = mode; } |
|---|
| 98 | |
|---|
| 99 | /** Get how the range values should be interpreted when computing which child is active.*/ |
|---|
| 100 | RangeMode getRangeMode() const { return _rangeMode; } |
|---|
| 101 | |
|---|
| 102 | |
|---|
| 103 | /** Sets the min and max visible ranges of range of specific child. |
|---|
| 104 | Values are floating point distance specified in local objects coordinates.*/ |
|---|
| 105 | void setRange(unsigned int childNo, float min,float max); |
|---|
| 106 | |
|---|
| 107 | /** returns the min visible range for specified child.*/ |
|---|
| 108 | inline float getMinRange(unsigned int childNo) const { return _rangeList[childNo].first; } |
|---|
| 109 | |
|---|
| 110 | /** returns the max visible range for specified child.*/ |
|---|
| 111 | inline float getMaxRange(unsigned int childNo) const { return _rangeList[childNo].second; } |
|---|
| 112 | |
|---|
| 113 | /** returns the number of ranges currently set. |
|---|
| 114 | * An LOD which has been fully set up will have getNumChildren()==getNumRanges(). */ |
|---|
| 115 | inline unsigned int getNumRanges() const { return _rangeList.size(); } |
|---|
| 116 | |
|---|
| 117 | /** set the list of MinMax ranges for each child.*/ |
|---|
| 118 | inline void setRangeList(const RangeList& rangeList) { _rangeList=rangeList; } |
|---|
| 119 | |
|---|
| 120 | /** return the list of MinMax ranges for each child.*/ |
|---|
| 121 | inline const RangeList& getRangeList() const { return _rangeList; } |
|---|
| 122 | |
|---|
| 123 | virtual BoundingSphere computeBound() const; |
|---|
| 124 | |
|---|
| 125 | protected : |
|---|
| 126 | virtual ~LOD() {} |
|---|
| 127 | |
|---|
| 128 | CenterMode _centerMode; |
|---|
| 129 | vec_type _userDefinedCenter; |
|---|
| 130 | value_type _radius; |
|---|
| 131 | |
|---|
| 132 | RangeMode _rangeMode; |
|---|
| 133 | RangeList _rangeList; |
|---|
| 134 | |
|---|
| 135 | }; |
|---|
| 136 | |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | #endif |
|---|