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

Revision 1832, 8.9 kB (checked in by robert, 12 years ago)

Changed the Viewer::realize() calls across to not using the threading paramter
leaving it up to the Viewer to specify the mode (which by default is MultiThreaded?).
Added a check for the presence of osgParticle systems so that threading is
disabled in this case.

  • 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()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
137    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
138   
139    // initialize the viewer.
140    osgProducer::Viewer viewer(arguments);
141
142    // if user request help write it out to cout.
143    if (arguments.read("-h") || arguments.read("--help"))
144    {
145        arguments.getApplicationUsage()->write(std::cout);
146        return 1;
147    }
148
149    // any option left unread are converted into errors to write out later.
150    arguments.reportRemainingOptionsAsUnrecognized();
151
152    // report any errors if they have occured when parsing the program aguments.
153    if (arguments.errors())
154    {
155        arguments.writeErrorMessages(std::cout);
156        return 1;
157    }
158   
159    if (arguments.argc()<=1)
160    {
161        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
162        return 1;
163    }
164
165    // load the nodes from the commandline arguments.
166    osg::Node* rootnode = osgDB::readNodeFiles(arguments);
167    if (!rootnode)
168    {
169        return 1;
170    }
171   
172    // run optimization over the scene graph
173    osgUtil::Optimizer optimzer;
174    optimzer.optimize(rootnode);
175   
176// -------------    Start of copy specific code -------------------------------------------------------
177   
178    // do a deep copy, using MyCopyOp to reveal whats going on under the good,
179    // in your own code you'd typically just use the basic osg::CopyOp something like
180    // osg::Node* mycopy = dynamic_cast<osg::Node*>(rootnode->clone(osg::CopyOp::DEEP_COPY_ALL));
181    std::cout << "Doing a deep copy of scene graph"<<std::endl;
182    // note, we need the dyanmic_cast because MS Visual Studio can't handle covarient
183    // return types, so that clone has return just Object*.  bahh hum bug
184    osg::Node* deep_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::DEEP_COPY_ALL)));
185   
186    std::cout << "----------------------------------------------------------------"<<std::endl;
187
188    // do a shallow copy.
189    std::cout << "Doing a shallow copy of scene graph"<<std::endl;
190    osg::Node* shallow_copy = dynamic_cast<osg::Node*>(rootnode->clone(MyCopyOp(osg::CopyOp::SHALLOW_COPY)));
191
192
193    // write out the various scene graphs so that they can be browsed, either
194    // in an editor or using a graphics diff tool gdiff/xdiff/xxdiff.
195    std::cout << std::endl << "Writing out the original scene graph as 'original.osg'"<<std::endl;
196    osgDB::writeNodeFile(*rootnode,"original.osg");
197
198    std::cout << "Writing out the deep copied scene graph as 'deep_copy.osg'"<<std::endl;
199    osgDB::writeNodeFile(*deep_copy,"deep_copy.osg");
200
201    std::cout << "Writing out the shallow copied scene graph as 'shallow_copy.osg'"<<std::endl;
202    osgDB::writeNodeFile(*shallow_copy,"shallow_copy.osg");
203
204
205    // You can use a bit mask to control which parts of the scene graph are shallow copied
206    // vs deep copied.  The options are (from include/osg/CopyOp) :
207    // enum Options {
208    //        SHALLOW_COPY = 0,
209    //        DEEP_COPY_OBJECTS = 1,
210    //        DEEP_COPY_NODES = 2,
211    //        DEEP_COPY_DRAWABLES = 4,
212    //        DEEP_COPY_STATESETS = 8,
213    //        DEEP_COPY_STATEATTRIBUTES = 16,
214    //        DEEP_COPY_TEXTURES = 32,
215    //        DEEP_COPY_IMAGES = 64,
216    //        DEEP_COPY_ALL = 0xffffffff
217    // };
218    //
219    // These options you can use together such as :
220    //    osg::Node* mycopy = dynamic_cast<osg::Node*>(rootnode->clone(osg::CopyOp::DEEP_COPY_NODES | DEEP_COPY_DRAWABLES));
221    // Which shares state but creates copies of all nodes and drawables (which contain the geometry).
222    //
223    // You may also want to subclass from CopyOp to provide finer grained control of what gets shared (shallow copy) vs
224    // cloned (deep copy).
225   
226
227
228// -------------    End of copy specific code -------------------------------------------------------
229     
230    // set the scene to render
231    viewer.setSceneData(rootnode);
232
233    // create the windows and run the threads.
234    viewer.realize();
235
236    while( !viewer.done() )
237    {
238        // wait for all cull and draw threads to complete.
239        viewer.sync();
240
241        // update the scene by traversing it with the the update visitor which will
242        // call all node update callbacks and animations.
243        viewer.update();
244         
245        // fire off the cull and draw traversals of the scene.
246        viewer.frame();
247       
248    }
249   
250    // wait for all cull and draw threads to complete before exit.
251    viewer.sync();
252
253    return 0;
254}
Note: See TracBrowser for help on using the browser.