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

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

Added a viewer.sync to the end of all the demos.

Removed the Win32 remapping of keycodes from the osgProducer::EventAdapter?.

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