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

Revision 1730, 8.7 kB (checked in by robert, 12 years ago)

Add osg:: infront of CopyOp? instances.

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