Ticket #168: crappy_little_bug.cpp

File crappy_little_bug.cpp, 5.1 kB (added by allenb, 1 year ago)

modification of a tutorial application to show the bug.

Line 
1 // Headers
2 #include <OpenSG/OSGGLUT.h>
3 #include <OpenSG/OSGConfig.h>
4 #include <OpenSG/OSGSimpleGeometry.h>
5 #include <OpenSG/OSGGLUTWindow.h>
6 #include <OpenSG/OSGSimpleSceneManager.h>
7 #include <OpenSG/OSGAction.h>
8 #include <vector>
9
10 // the general scene file loading handler
11 #include <OpenSG/OSGSceneFileHandler.h>
12 #include <boost/bind.hpp>
13
14 // Activate the OpenSG namespace
15 OSG_USING_NAMESPACE
16
17 // The SimpleSceneManager to manage simple applications
18 SimpleSceneManager *mgr;
19 GroupNodePtr       gScene;
20
21 std::map<unsigned, GroupNodePtr>  gTransformRoots;
22
23
24 // forward declaration so we can have the interesting stuff upfront
25 int setupGLUT( int *argc, char *argv[] );
26 void updateScene(void);
27
28
29 // Initialize GLUT & OpenSG and set up the scene
30 int main(int argc, char **argv)
31 {
32     // OSG init
33     osgInit(argc,argv);
34
35     // GLUT init
36     int winid = setupGLUT(&argc, argv);
37
38     // the connection between GLUT and OpenSG
39     GLUTWindowPtr gwin= GLUTWindow::create();
40     gwin->setId(winid);
41     gwin->init();
42
43     // load the scene
44     gScene = GroupNodePtr::create();
45
46     commitChanges();
47
48     for (unsigned i=0;i<20000;i++)
49     {
50        updateScene();
51        commitChanges();
52     }
53
54     // create the SimpleSceneManager helper
55     mgr = new SimpleSceneManager;
56
57     // tell the manager what to manage
58     mgr->setWindow(gwin );
59     mgr->setRoot  (gScene.node());
60
61     // show the whole scene
62     mgr->showAll();
63
64     // GLUT main loop
65     glutMainLoop();
66
67     return 0;
68 }
69
70 //
71 // GLUT callback functions
72 //
73
74 GroupNodePtr buildGeomChain()
75 {
76    GroupNodePtr         root = GroupNodePtr::create();
77    TransformNodePtr    xform = TransformNodePtr::create();
78    GeometryPtr          geom = makeBoxGeo(1000000, 1000000, 1000000, 10, 10, 10);
79    NodeRefPtr      geom_node = NodeRefPtr(Node::create());
80    geom_node->setCore(geom);
81
82    SimpleMaterialPtr     mat = SimpleMaterial::create();
83    mat->setDiffuse(Color3f(1,1,1));
84    geom->setMaterial(mat);
85
86    root.node()->addChild(xform);
87    xform.node()->addChild(geom_node);
88    return root;
89 }
90
91 void updateScene(void)
92 {
93    static int i=0;
94    i++;
95
96    std::cerr << "Iter: " << i << std::endl;
97
98    // Simple case of remove a child and add a child
99 #if 1
100    if(gScene.node()->getNChildren() > 0)
101    {
102       gScene.node()->subChild(0);
103    }
104
105    GroupNodePtr new_chain = buildGeomChain();
106    gScene.node()->addChild(new_chain.node());
107
108    // More complex case of dynamic adding and removing over time
109 #else
110    unsigned add_per_frame = 5;
111    unsigned max_num = 100;
112
113    std::cerr << "Adding geom: " << std::endl;
114    for (unsigned x=0;x<add_per_frame;x++)
115    {
116       GroupNodePtr new_chain = buildGeomChain();
117       gScene.node()->addChild(new_chain.node());
118       gTransformRoots[(i*add_per_frame)+x] = new_chain;
119       std::cerr << "   added:" << (i*add_per_frame)+x << std::endl;
120    }
121
122    int num_extra = gScene.node()->getNChildren()-max_num;
123    if (num_extra > 0)
124    {
125       // Pick the first num_extra items in the map and remove them
126       std::cerr << "num extra: " << num_extra << std::endl;
127       std::vector<unsigned> to_remove;
128       for (std::map<unsigned, GroupNodePtr>::iterator j=gTransformRoots.begin();
129             j!=gTransformRoots.end() && (to_remove.size() < num_extra); j++)
130       { to_remove.push_back((*j).first); }
131
132       std::cerr << "Removing: [" << to_remove.size() << "]" << std::endl;
133       for(unsigned k=0; k<to_remove.size(); k++)
134       {
135          unsigned remove_idx       = to_remove[k];
136          std::cerr << "    remove: " << remove_idx << std::endl;
137          GroupNodePtr remove_group = gTransformRoots[remove_idx];
138          gTransformRoots.erase(remove_idx);
139          gScene.node()->subChild(remove_group.node());
140       }
141    }
142
143    std::cerr << "    num nodes: " << gTransformRoots.size() << std::endl;
144 #endif
145
146 }
147
148 // redraw the window
149 void display(void)
150 {
151    //updateScene();
152    //commitChanges();
153
154     mgr->idle();
155     mgr->redraw();
156 }
157
158 // react to size changes
159 void reshape(int w, int h)
160 {
161     mgr->resize(w, h);
162     glutPostRedisplay();
163 }
164
165 // react to mouse button presses
166 void mouse(int button, int state, int x, int y)
167 {
168
169     if (state)
170         mgr->mouseButtonRelease(button, x, y);
171     else
172         mgr->mouseButtonPress(button, x, y);
173
174     glutPostRedisplay();
175 }
176
177 // react to mouse motions with pressed buttons
178 void motion(int x, int y)
179 {
180
181     mgr->mouseMove(x, y);
182     glutPostRedisplay();
183 }
184
185 // react to keys
186 void keyboard(unsigned char k, int , int )
187 {
188     switch(k)
189     {
190         case 27:
191         {
192             OSG::osgExit();
193             exit(0);
194         }
195         break;
196
197         case 'f':
198         {
199             mgr->setNavigationMode(Navigator::FLY);
200         }
201         break;
202
203         case 't':
204         {
205             mgr->setNavigationMode(Navigator::TRACKBALL);
206         }
207         break;
208     }
209 }
210
211 // setup the GLUT library which handles the windows for us
212 int setupGLUT(int *argc, char *argv[])
213 {
214     glutInit(argc, argv);
215     glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
216
217     int winid = glutCreateWindow("OpenSG");
218
219     glutReshapeFunc(reshape);
220     glutDisplayFunc(display);
221     glutIdleFunc(display);
222     glutMouseFunc(mouse);
223     glutMotionFunc(motion);
224     glutKeyboardFunc(keyboard);
225
226     return winid;
227 }