root/OpenSceneGraph/trunk/examples/osgpagedlod/osgpagedlod.cpp @ 4380

Revision 4380, 6.0 kB (checked in by robert, 9 years ago)

Changed osgpagedlod example to convert LOD nodes into PagedLOD ones.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/Group>
2#include <osg/Notify>
3#include <osg/Geometry>
4#include <osg/ArgumentParser>
5#include <osg/ApplicationUsage>
6#include <osg/Texture2D>
7#include <osg/Geode>
8#include <osg/PagedLOD>
9
10#include <osgDB/Registry>
11#include <osgDB/ReadFile>
12#include <osgDB/WriteFile>
13
14#include <osgUtil/Optimizer>
15
16#include <iostream>
17#include <sstream>
18
19class WriteOutPagedLODSubgraphsVistor : public osg::NodeVisitor
20{
21public:
22    WriteOutPagedLODSubgraphsVistor():
23        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
24    {
25    }
26   
27    virtual void apply(osg::PagedLOD& plod)
28    {
29
30        // go through all the named children and write them out to disk.
31        for(unsigned int i=0;i<plod.getNumChildren();++i)
32        {
33            osg::Node* child = plod.getChild(i);
34            std::string filename = plod.getFileName(i);
35            if (!filename.empty())
36            {
37                osg::notify(osg::NOTICE)<<"Writing out "<<filename<<std::endl;
38                osgDB::writeNodeFile(*child,filename);
39            }
40        }
41   
42        traverse(plod);
43    }   
44};
45
46class ConvertToPageLODVistor : public osg::NodeVisitor
47{
48public:
49    ConvertToPageLODVistor(const std::string& basename, const std::string& extension):
50        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
51        _basename(basename),
52        _extension(extension)
53    {
54    }
55   
56    virtual ~ConvertToPageLODVistor()
57    {
58    }
59
60    virtual void apply(osg::LOD& lod)
61    {
62        _lodSet.insert(&lod);
63   
64        traverse(lod);
65    }   
66
67    virtual void apply(osg::PagedLOD& plod)
68    {
69        // do thing, but want to avoid call LOD.
70        traverse(plod);
71    }
72
73    void convert()
74    {
75        unsigned int lodNum = 0;
76        for(LODSet::iterator itr = _lodSet.begin();
77            itr != _lodSet.end();
78            ++itr, ++lodNum)
79        {
80            osg::ref_ptr<osg::LOD> lod = const_cast<osg::LOD*>(itr->get());
81           
82            if (lod->getNumParents()==0)
83            {
84                osg::notify(osg::NOTICE)<<"Warning can't operator on root node."<<std::endl;
85                break;
86            }
87
88            osg::notify(osg::NOTICE)<<"Converting LOD to PagedLOD"<<std::endl;
89           
90            osg::PagedLOD* plod = new osg::PagedLOD;
91           
92            const osg::LOD::RangeList& originalRangeList = lod->getRangeList();
93            typedef std::map< osg::LOD::MinMaxPair , unsigned int > MinMaxPairMap;
94            MinMaxPairMap rangeMap;
95            unsigned int pos = 0;
96            for(osg::LOD::RangeList::const_iterator ritr = originalRangeList.begin();
97                ritr != originalRangeList.end();
98                ++ritr, ++pos)
99            {
100                rangeMap[*ritr] = pos;
101            }
102           
103            pos = 0;
104            for(MinMaxPairMap::reverse_iterator mitr = rangeMap.rbegin();
105                mitr != rangeMap.rend();
106                ++mitr, ++pos)
107            {
108                if (pos==0)
109                {
110                    plod->addChild(lod->getChild(mitr->second), mitr->first.first, mitr->first.second);
111                   osg::notify(osg::NOTICE)<<"  adding staight child"<<std::endl;
112                }
113                else
114                {
115                    std::string filename = _basename;
116                    std::ostringstream os;
117                    os << _basename << "_"<<lodNum<<"_"<<pos<<_extension;
118                   
119                    plod->addChild(lod->getChild(mitr->second), mitr->first.first, mitr->first.second, os.str());
120                   osg::notify(osg::NOTICE)<<"  adding tiled subgraph"<<os.str()<<std::endl;
121                }
122            }
123           
124            osg::Node::ParentList parents = lod->getParents();
125            for(osg::Node::ParentList::iterator pitr=parents.begin();
126                pitr!=parents.end();
127                ++pitr)
128            {
129                (*pitr)->replaceChild(lod.get(),plod);
130            }
131
132            plod->setCenter(plod->getBound().center());
133            plod->setCenter(plod->getBound().center());
134
135        }
136    }
137
138   
139    typedef std::set< osg::ref_ptr<osg::LOD> >  LODSet;
140    LODSet _lodSet;
141    std::string _basename;
142    std::string _extension;
143
144};
145
146
147int main( int argc, char **argv )
148{
149
150    // use an ArgumentParser object to manage the program arguments.
151    osg::ArgumentParser arguments(&argc,argv);
152   
153    // set up the usage document, in case we need to print out how to use this program.
154    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
155    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" creates a hierachy of files for paging which can be later loaded by viewers.");
156    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
157    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
158
159    // if user request help write it out to cout.
160    if (arguments.read("-h") || arguments.read("--help"))
161    {
162        arguments.getApplicationUsage()->write(std::cout);
163        return 1;
164    }
165
166    // any option left unread are converted into errors to write out later.
167    arguments.reportRemainingOptionsAsUnrecognized();
168
169    // report any errors if they have occured when parsing the program aguments.
170    if (arguments.errors())
171    {
172        arguments.writeErrorMessages(std::cout);
173        return 1;
174    }
175   
176//     if (arguments.argc()<=1)
177//     {
178//         arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
179//         return 1;
180//     }
181
182
183    osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments);
184   
185    if (!model)
186    {
187        osg::notify(osg::NOTICE)<<"No model loaded."<<std::endl;
188        return 1;
189    }
190   
191    ConvertToPageLODVistor converter("tile",".ive");
192    model->accept(converter);
193    converter.convert();
194   
195    if (model.valid())
196    {
197        osgDB::writeNodeFile(*model,"tile.ive");
198       
199        WriteOutPagedLODSubgraphsVistor woplsv;
200        model->accept(woplsv);
201    }
202
203    return 0;
204}
Note: See TracBrowser for help on using the browser.