root/OpenSceneGraph/trunk/examples/osgcopy/osgcopy.cpp @ 1844

Revision 1844, 9.0 kB (checked in by robert, 11 years ago)

Added desciptions to all the demos.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/MatrixTransform>
2#include <osg/Billboard>
3#include <osg/Geode>
4#include <osg/Group>
5#include <osg/Notify>
6#include <osg/Texture>
7
8#include <osgDB/Registry>
9#include <osgDB/ReadFile>
10#include <osgDB/WriteFile>
11
12#include <osgProducer/Viewer>
13
14#include <osgUtil/Optimizer>
15
16using namespace osg;
17
18// Customize the CopyOp so that we add our own verbose
19// output of what's being copied.
20class MyCopyOp : public osg::CopyOp
21{
22    public:
23   
24        inline MyCopyOp(CopyFlags flags=SHALLOW_COPY):
25            osg::CopyOp(flags),
26            _indent(0),
27            _step(4) {}
28
29        inline void moveIn() const { _indent += _step; }
30        inline void moveOut() const { _indent -= _step; }
31        inline void writeIndent() const 
32        {
33            for(int i=0;i<_indent;++i) std::cout << " ";
34        }
35   
36        virtual osg::Referenced*     operator() (const osg::Referenced* ref) const
37        {
38            writeIndent(); std::cout << "copying Referenced "<<ref<<std::endl;
39            moveIn();
40            osg::Referenced* ret_ref = CopyOp::operator()(ref);
41            moveOut();
42            return ret_ref;
43        }
44       
45        virtual osg::Object*         operator() (const osg::Object* obj) const
46        {
47            writeIndent(); std::cout << "copying Object "<<obj;
48            if (obj) std::cout<<" "<<obj->className();
49            std::cout<<std::endl;
50            moveIn();
51            osg::Object* ret_obj = CopyOp::operator()(obj);
52            moveOut();
53            return ret_obj;
54        }
55       
56        virtual osg::Node*           operator() (const osg::Node* node) const
57        {
58            writeIndent(); std::cout << "copying Node "<<node;
59            if (node) std::cout<<" "<<node->className()<<" '"<<node->getName()<<"'";
60            std::cout<<std::endl;
61            moveIn();
62            osg::Node* ret_node = CopyOp::operator()(node);
63            moveOut();
64            return ret_node;
65        }
66
67        virtual osg::Drawable*       operator() (const osg::Drawable* drawable) const
68        {
69            writeIndent(); std::cout << "copying Drawable "<<drawable;
70            if (drawable) std::cout<<" "<<drawable->className();
71            std::cout<<std::endl;
72            moveIn();
73            osg::Drawable* ret_drawable = CopyOp::operator()(drawable);
74            moveOut();
75            return ret_drawable;
76        }
77
78        virtual osg::StateSet*       operator() (const osg::StateSet* stateset) const
79        {
80            writeIndent(); std::cout << "copying StateSet "<<stateset;
81            if (stateset) std::cout<<" "<<stateset->className();
82            std::cout<<std::endl;
83            moveIn();
84            osg::StateSet* ret_stateset = CopyOp::operator()(stateset);
85            moveOut();
86            return ret_stateset;
87        }
88
89        virtual osg::StateAttribute* operator() (const osg::StateAttribute* attr) const
90        {
91            writeIndent(); std::cout << "copying StateAttribute "<<attr;
92            if (attr) std::cout<<" "<<attr->className();
93            std::cout<<std::endl;
94            moveIn();
95            osg::StateAttribute* ret_attr = CopyOp::operator()(attr);
96            moveOut();
97            return ret_attr;
98        }
99
100        virtual osg::Texture*        operator() (const osg::Texture* text) const
101        {
102            writeIndent(); std::cout << "copying Texture "<<text;
103            if (text) std::cout<<" "<<text->className();
104            std::cout<<std::endl;
105            moveIn();
106            osg::Texture* ret_text = CopyOp::operator()(text);
107            moveOut();
108            return ret_text;
109        }
110
111        virtual osg::Image*          operator() (const osg::Image* image) const
112        {
113            writeIndent(); std::cout << "copying Image "<<image;
114            if (image) std::cout<<" "<<image->className();
115            std::cout<<std::endl;
116            moveIn();
117            osg::Image* ret_image = CopyOp::operator()(image);
118            moveOut();
119            return ret_image;
120        }
121       
122    protected:
123   
124        // must be mutable since CopyOp is passed around as const to
125        // the various clone/copy constructors.
126        mutable int _indent;
127        mutable int _step;
128};
129
130int main( int argc, char **argv )
131{
132    // use an ArgumentParser object to manage the program arguments.
133    osg::ArgumentParser arguments(&argc,argv);
134
135    // set up the usage document, in case we need to print out how to use this program.
136    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of deep vs shallow vs custom copying of scene graphs.");
137    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
138    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
139   
140    // initialize the viewer.
141    osgProducer::Viewer viewer(arguments);
142
143    // if user request help write it out to cout.
144    if (arguments.read("-h") || arguments.read("--help"))
145    {
146        arguments.getApplicationUsage()->write(std::cout);
147        return 1;
148    }
149
150    // any option left unread are converted into errors to write out later.
151    arguments.reportRemainingOptionsAsUnrecognized();
152
153    // report any errors if they have occured when parsing the program aguments.
154    if (arguments.errors())
155    {
156        arguments.writeErrorMessages(std::cout);
157        return 1;
158    }
159   
160    if (arguments.argc()<=1)
161    {
162        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
163        return 1;
164    }
165
166    // load the nodes from the commandline arguments.
167    osg::Node* rootnode = osgDB::readNodeFiles(arguments);
168    if (!rootnode)
169    {
170        return 1;
171    }
172   
173    // run optimization over the scene graph
174    osgUtil::Optimizer optimzer;
175    optimzer.optimize(rootnode);
176   
177// -------------    Start of copy specific code -------------------------------------------------------
178   
179    // do a deep copy, using MyCopyOp to reveal whats going on under the good,
180    // in your own code you'd typically just use the basic osg::CopyOp something like
181    // osg::Node* mycopy = dynamic_cast<osg::Node*>(rootnode->clone(osg::CopyOp::DEEP_COPY_ALL));
182    std::cout << "Doing a deep copy of scene graph"<<std::endl;
183    // note, we need the dyanmic_cast because MS Visual Studio can't handle covarient
184    // return types, so that clone has return just Object*.  bahh hum bug
185    osg::Node* deep_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::DEEP_COPY_ALL)));
186   
187    std::cout << "----------------------------------------------------------------"<<std::endl;
188
189    // do a shallow copy.
190    std::cout << "Doing a shallow copy of scene graph"<<std::endl;
191    osg::Node* shallow_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::SHALLOW_COPY)));
192
193
194    // write out the various scene graphs so that they can be browsed, either
195    // in an editor or using a graphics diff tool gdiff/xdiff/xxdiff.
196    std::cout << std::endl << "Writing out the original scene graph as 'original.osg'"<<std::endl;
197    osgDB::writeNodeFile(*rootnode,"original.osg");
198
199    std::cout << "Writing out the deep copied scene graph as 'deep_copy.osg'"<<std::endl;
200    osgDB::writeNodeFile(*deep_copy,"deep_copy.osg");
201
202    std::cout << "Writing out the shallow copied scene graph as 'shallow_copy.osg'"<<std::endl;
203    osgDB::writeNodeFile(*shallow_copy,"shallow_copy.osg");
204
205
206    // You can use a bit mask to control which parts of the scene graph are shallow copied
207    // vs deep copied.  The options are (from include/osg/CopyOp) :
208    // enum Options {
209    //        SHALLOW_COPY = 0,
210    //        DEEP_COPY_OBJECTS = 1,
211    //        DEEP_COPY_NODES = 2,
212    //        DEEP_COPY_DRAWABLES = 4,
213    //        DEEP_COPY_STATESETS = 8,
214    //        DEEP_COPY_STATEATTRIBUTES = 16,
215    //        DEEP_COPY_TEXTURES = 32,
216    //        DEEP_COPY_IMAGES = 64,
217    //        DEEP_COPY_ALL = 0xffffffff
218    // };
219    //
220    // These options you can use together such as :
221    //    osg::Node* mycopy = dynamic_cast<osg::Node*>(rootnode->clone(osg::CopyOp::DEEP_COPY_NODES | DEEP_COPY_DRAWABLES));
222    // Which shares state but creates copies of all nodes and drawables (which contain the geometry).
223    //
224    // You may also want to subclass from CopyOp to provide finer grained control of what gets shared (shallow copy) vs
225    // cloned (deep copy).
226   
227
228
229// -------------    End of copy specific code -------------------------------------------------------
230     
231    // set the scene to render
232    viewer.setSceneData(rootnode);
233
234    // create the windows and run the threads.
235    viewer.realize();
236
237    while( !viewer.done() )
238    {
239        // wait for all cull and draw threads to complete.
240        viewer.sync();
241
242        // update the scene by traversing it with the the update visitor which will
243        // call all node update callbacks and animations.
244        viewer.update();
245         
246        // fire off the cull and draw traversals of the scene.
247        viewer.frame();
248       
249    }
250   
251    // wait for all cull and draw threads to complete before exit.
252    viewer.sync();
253
254    return 0;
255}
Note: See TracBrowser for help on using the browser.