root/OpenSceneGraph/trunk/src/osg/LOD.cpp @ 13041

Revision 13041, 4.5 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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#include <osg/LOD>
14#include <osg/CullStack>
15
16#include <algorithm>
17
18using namespace osg;
19
20LOD::LOD():
21    _centerMode(USE_BOUNDING_SPHERE_CENTER),
22    _radius(-1.0f),
23    _rangeMode(DISTANCE_FROM_EYE_POINT)
24{
25}
26
27LOD::LOD(const LOD& lod,const CopyOp& copyop):
28        Group(lod,copyop),
29        _centerMode(lod._centerMode),
30        _userDefinedCenter(lod._userDefinedCenter),
31        _radius(lod._radius),
32        _rangeMode(lod._rangeMode),
33        _rangeList(lod._rangeList)
34{
35}
36
37
38void LOD::traverse(NodeVisitor& nv)
39{
40    switch(nv.getTraversalMode())
41    {
42        case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
43            std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
44            break;
45        case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
46        {
47            float required_range = 0;
48            if (_rangeMode==DISTANCE_FROM_EYE_POINT)
49            {
50                required_range = nv.getDistanceToViewPoint(getCenter(),true);
51            }
52            else
53            {
54                osg::CullStack* cullStack = dynamic_cast<osg::CullStack*>(&nv);
55                if (cullStack && cullStack->getLODScale())
56                {
57                    required_range = cullStack->clampedPixelSize(getBound()) / cullStack->getLODScale();
58                }
59                else
60                {
61                    // fallback to selecting the highest res tile by
62                    // finding out the max range
63                    for(unsigned int i=0;i<_rangeList.size();++i)
64                    {
65                        required_range = osg::maximum(required_range,_rangeList[i].first);
66                    }
67                }
68            }
69
70            unsigned int numChildren = _children.size();
71            if (_rangeList.size()<numChildren) numChildren=_rangeList.size();
72
73            for(unsigned int i=0;i<numChildren;++i)
74            {
75                if (_rangeList[i].first<=required_range && required_range<_rangeList[i].second)
76                {
77                    _children[i]->accept(nv);
78                }
79            }
80           break;
81        }
82        default:
83            break;
84    }
85}
86
87BoundingSphere LOD::computeBound() const
88{
89    if (_centerMode==USER_DEFINED_CENTER && _radius>=0.0f)
90    {
91        return BoundingSphere(_userDefinedCenter,_radius);
92    }
93    else if (_centerMode==UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED && _radius>=0.0f)
94    {
95        BoundingSphere bs = BoundingSphere(_userDefinedCenter,_radius);
96        bs.expandBy(Group::computeBound());
97        //alternative (used in TxpPagedLOD)
98        // bs.expandRadiusBy(Group::computeBound());
99        return bs;
100    }
101    else
102    {
103        return Group::computeBound();
104    }
105}
106
107bool LOD::addChild( Node *child )
108{
109    if (Group::addChild(child))
110    {
111
112        if (_children.size()>_rangeList.size())
113        {
114            float maxRange = !_rangeList.empty() ? _rangeList.back().second : 0.0f;
115
116            _rangeList.resize(_children.size(),MinMaxPair(maxRange,maxRange));
117        }
118
119        return true;
120    }
121    return false;
122}
123
124
125bool LOD::addChild(Node *child, float min, float max)
126{
127    if (Group::addChild(child))
128    {
129        if (_children.size()>_rangeList.size()) _rangeList.resize(_children.size(),MinMaxPair(min,min));
130        _rangeList[_children.size()-1].first = min;
131        _rangeList[_children.size()-1].second = max;
132        return true;
133    }
134    return false;
135}
136
137bool LOD::removeChildren( unsigned int pos,unsigned int numChildrenToRemove)
138{
139    if (pos<_rangeList.size()) _rangeList.erase(_rangeList.begin()+pos, osg::minimum(_rangeList.begin()+(pos+numChildrenToRemove), _rangeList.end()) );
140
141    return Group::removeChildren(pos,numChildrenToRemove);
142}
143
144void LOD::setRange(unsigned int childNo, float min,float max)
145{
146    if (childNo>=_rangeList.size()) _rangeList.resize(childNo+1,MinMaxPair(min,min));
147    _rangeList[childNo].first=min;
148    _rangeList[childNo].second=max;
149}
Note: See TracBrowser for help on using the browser.