root/OpenSceneGraph/trunk/src/osgSim/InsertImpostorsVisitor.cpp @ 13041

Revision 13041, 5.1 kB (checked in by robert, 2 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#if defined(_MSC_VER)
14    #pragma warning( disable : 4786 )
15#endif
16
17#include <osgSim/InsertImpostorsVisitor>
18#include <osgSim/Impostor>
19
20#include <algorithm>
21
22using namespace osg;
23using namespace osgSim;
24
25InsertImpostorsVisitor::InsertImpostorsVisitor()
26{
27    setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
28    _impostorThresholdRatio = 30.0f;
29    _maximumNumNestedImpostors = 3;
30    _numNestedImpostors = 0;
31}
32
33void InsertImpostorsVisitor::reset()
34{
35    _groupList.clear();
36    _lodList.clear();
37    _numNestedImpostors = 0;
38}
39
40void InsertImpostorsVisitor::apply(Node& node)
41{
42    traverse(node);
43}
44
45void InsertImpostorsVisitor::apply(Group& node)
46{
47    _groupList.push_back(&node);
48
49    ++_numNestedImpostors;
50    if (_numNestedImpostors<_maximumNumNestedImpostors)
51    {
52        traverse(node);
53    }
54    --_numNestedImpostors;
55}
56
57void InsertImpostorsVisitor::apply(LOD& node)
58{
59    if (dynamic_cast<osgSim::Impostor*>(&node)==0)
60    {
61        _lodList.push_back(&node);
62    }
63
64    ++_numNestedImpostors;
65    if (_numNestedImpostors<_maximumNumNestedImpostors)
66    {
67        traverse(node);
68    }
69    --_numNestedImpostors;
70}
71
72/* insert the required impostors into the scene graph.*/
73void InsertImpostorsVisitor::insertImpostors()
74{
75
76    bool _insertImpostorsAboveGroups = true;
77    bool _replaceLODsByImpostors = true;
78
79    // handle group's
80    if (_insertImpostorsAboveGroups)
81    {
82        std::sort(_groupList.begin(),_groupList.end());
83
84        Group* previousGroup = NULL;
85        for(GroupList::iterator itr=_groupList.begin();
86            itr!=_groupList.end();
87            ++itr)
88        {
89            Group* group = (*itr);
90            if (group!=previousGroup)
91            {
92                const BoundingSphere& bs = group->getBound();
93                if (bs.valid())
94                {
95
96                    // take a copy of the original parent list
97                    // before we change it around by adding the group
98                    // to an impostor.
99                    Node::ParentList parentList = group->getParents();
100
101                    Impostor* impostor = new Impostor;
102
103                    // standard LOD settings
104                    impostor->addChild(group);
105                    impostor->setRange(0,0.0f,1e7f);
106
107                    // impostor specfic settings.
108                    impostor->setImpostorThresholdToBound(_impostorThresholdRatio);
109
110                    // now replace the group by the new impostor in all of the
111                    // group's original parent list.
112                    for(Node::ParentList::iterator pitr=parentList.begin();
113                        pitr!=parentList.end();
114                        ++pitr)
115                    {
116                        (*pitr)->replaceChild(group,impostor);
117                    }
118
119                }
120            }
121        }
122
123    }
124
125
126    // handle LOD's
127    if (_replaceLODsByImpostors)
128    {
129        std::sort(_lodList.begin(),_lodList.end());
130
131        LOD* previousLOD = NULL;
132        for(LODList::iterator itr=_lodList.begin();
133            itr!=_lodList.end();
134            ++itr)
135        {
136            osg::LOD* lod = (*itr);
137            if (lod!=previousLOD)
138            {
139                const osg::BoundingSphere& bs = lod->getBound();
140                if (bs.valid())
141                {
142
143                    // take a copy of the original parent list
144                    // before we change it around by adding the lod
145                    // to an impostor.
146                    osg::Node::ParentList parentList = lod->getParents();
147
148                    Impostor* impostor = new Impostor;
149
150                    // standard LOD settings
151                    for(unsigned int ci=0;ci<lod->getNumChildren();++ci)
152                    {
153                        impostor->addChild(lod->getChild(ci));
154                        impostor->setRange(ci,lod->getMinRange(ci),lod->getMaxRange(ci));
155                    }
156
157                    impostor->setCenter(lod->getCenter());
158                    impostor->setCenterMode(lod->getCenterMode());
159
160                    // impostor specfic settings.
161                    impostor->setImpostorThresholdToBound(_impostorThresholdRatio);
162
163                    // now replace the lod by the new impostor in all of the
164                    // lod's original parent list.
165                    for(Node::ParentList::iterator pitr=parentList.begin();
166                        pitr!=parentList.end();
167                        ++pitr)
168                    {
169                        (*pitr)->replaceChild(lod,impostor);
170                    }
171
172                }
173            }
174        }
175
176    }
177}
Note: See TracBrowser for help on using the browser.