root/OpenSceneGraph/trunk/examples/osggeometry/osggeometry.cpp @ 13470

Revision 13470, 26.0 kB (checked in by robert, 12 days ago)

Moved widgets from VolumeEditorWidget? to TransferFunctionWidget?, and widget utilities into WidgetUtils?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osggeometry.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osg/Geode>
20#include <osg/GeometryNew>
21#include <osg/Material>
22#include <osg/Vec3>
23#include <osg/MatrixTransform>
24#include <osg/Texture2D>
25#include <osg/PolygonStipple>
26#include <osg/TriangleFunctor>
27#include <osg/io_utils>
28
29#include <osgDB/ReadFile>
30#include <osgDB/WriteFile>
31
32#include <osgGA/TrackballManipulator>
33
34#include <osgViewer/Viewer>
35
36#include <osg/Math>
37
38#include <iostream>
39
40
41// This demo illustrates how to create the various different types of geometry that
42// the osg::Geometry class can represent.  This demo uses the OpenGL red book diagram of different
43// OpenGL Primitives as a template for all the equivalent OpenSceneGraph Primitives.  The OpenSceneGraph
44// wraps OpenGL very thinly and therefore uses all the same enum and naming conventions. The coordinate data is also
45// wrapped around OpenGL's vertex arrays and draw arrays/elements calls.  Familiarity with
46// OpenGL will help you understand the osg::Geometry class which encapsulate all this, or if you
47// havn't learned OpenGL yet, learning osg::Geometry will help you understand how OpenGL
48// works!
49
50// The osg::Geometry class "is a" subclass of osg::Drawable base class, so is an object that provides
51// a draw method for drawing objects in the scene.  osg::Geometry contains all the vertex, normal
52// color and texture coordinate arrays required to specify the coordinates of your objects, and the
53// primitives join these coordinates together as the points, lines or surfaces that you will see
54// rendered on your screen.
55//
56// This demo is split into two functions, the createScene() function which creates the scene graph
57// with the various primitives in it, and the main() which sets up a basic viewer window and
58// adds to the it the scene generated by createScene().
59
60
61struct NormalPrint
62{
63    void operator() (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool) const 
64    {
65        osg::Vec3 normal = (v2-v1)^(v3-v2);
66        normal.normalize();
67        std::cout << "\t("<<v1<<") ("<<v2<<") ("<<v3<<") "<<") normal ("<<normal<<")"<<std::endl;
68    }
69};
70
71// decompose Drawable primitives into triangles, print out these triangles and computed normals.
72void printTriangles(const std::string& name, osg::Drawable& drawable)
73{
74    std::cout<<name<<std::endl;
75   
76    osg::TriangleFunctor<NormalPrint> tf;
77    drawable.accept(tf);
78 
79    std::cout<<std::endl;
80}
81
82
83osg::Node* createScene()
84{
85    // create the Geode (Geometry Node) to contain all our osg::Geometry objects.
86    osg::Geode* geode = new osg::Geode();
87
88    // following are separate blocks for creating POINTS, LINES, LINE_STRIP, LINE_LOOP, POLYGON, QUADS,
89    // QUAD_STRIP, TRIANGLES, TRIANGLE_STRIP and TRIANGLE_FAN primitives. An image of these primitives
90    // is provided in the distribution: OpenSceneGraph-Data/Images/primitives.gif.
91
92
93    // create POINTS
94    {
95        // create Geometry object to store all the vertices and points primitive.
96        osg::GeometryNew* pointsGeom = new osg::GeometryNew();
97       
98        // create a Vec3Array and add to it all my coordinates.
99        // Like all the *Array variants (see include/osg/Array) , Vec3Array is derived from both osg::Array
100        // and std::vector<>.  osg::Array's are reference counted and hence sharable,
101        // which std::vector<> provides all the convenience, flexibility and robustness
102        // of the most popular of all STL containers.
103        osg::Vec3Array* vertices = new osg::Vec3Array;
104        vertices->push_back(osg::Vec3(-1.02168, -2.15188e-09, 0.885735));
105        vertices->push_back(osg::Vec3(-0.976368, -2.15188e-09, 0.832179));
106        vertices->push_back(osg::Vec3(-0.873376, 9.18133e-09, 0.832179));
107        vertices->push_back(osg::Vec3(-0.836299, -2.15188e-09, 0.885735));
108        vertices->push_back(osg::Vec3(-0.790982, 9.18133e-09, 0.959889));
109       
110        // pass the created vertex array to the points geometry object.
111        pointsGeom->setVertexArray(vertices);
112       
113       
114       
115        // create the color of the geometry, one single for the whole geometry.
116        // for consistency of design even one single color must added as an element
117        // in a color array.
118        osg::Vec4Array* colors = new osg::Vec4Array;
119        // add a white color, colors take the form r,g,b,a with 0.0 off, 1.0 full on.
120        colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
121       
122        // pass the color array to points geometry, note the binding to tell the geometry
123        // that only use one color for the whole object.
124        pointsGeom->setColorArray(colors);
125        pointsGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
126       
127       
128        // set the normal in the same way color.
129        osg::Vec3Array* normals = new osg::Vec3Array;
130        normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
131        pointsGeom->setNormalArray(normals);
132        pointsGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
133
134
135        // create and add a DrawArray Primitive (see include/osg/Primitive).  The first
136        // parameter passed to the DrawArrays constructor is the Primitive::Mode which
137        // in this case is POINTS (which has the same value GL_POINTS), the second
138        // parameter is the index position into the vertex array of the first point
139        // to draw, and the third parameter is the number of points to draw.
140        pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,vertices->size()));
141       
142       
143        // add the points geometry to the geode.
144        geode->addDrawable(pointsGeom);
145    }
146
147    // create LINES
148    {
149        // create Geometry object to store all the vertices and lines primitive.
150        osg::GeometryNew* linesGeom = new osg::GeometryNew();
151       
152        // this time we'll preallocate the vertex array to the size we
153        // need and then simple set them as array elements, 8 points
154        // makes 4 line segments.
155        osg::Vec3Array* vertices = new osg::Vec3Array(8);
156        (*vertices)[0].set(-1.13704, -2.15188e-09, 0.40373);
157        (*vertices)[1].set(-0.856897, -2.15188e-09, 0.531441);
158        (*vertices)[2].set(-0.889855, -2.15188e-09, 0.444927);
159        (*vertices)[3].set(-0.568518, -2.15188e-09, 0.40373);
160        (*vertices)[4].set(-1.00933, -2.15188e-09, 0.370773);
161        (*vertices)[5].set(-0.716827, -2.15188e-09, 0.292498);
162        (*vertices)[6].set(-1.07936, 9.18133e-09, 0.317217);
163        (*vertices)[7].set(-0.700348, 9.18133e-09, 0.362533);
164
165       
166        // pass the created vertex array to the points geometry object.
167        linesGeom->setVertexArray(vertices);
168       
169        // set the colors as before, plus using the above
170        osg::Vec4Array* colors = new osg::Vec4Array;
171        colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
172        linesGeom->setColorArray(colors);
173        linesGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
174       
175
176        // set the normal in the same way color.
177        osg::Vec3Array* normals = new osg::Vec3Array;
178        normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
179        linesGeom->setNormalArray(normals);
180        linesGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
181
182
183        // This time we simply use primitive, and hardwire the number of coords to use
184        // since we know up front,
185        linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,8));
186       
187       
188        // add the points geometry to the geode.
189        geode->addDrawable(linesGeom);
190    }
191   
192    // create LINE_STRIP
193    {
194        // create Geometry object to store all the vertices and lines primitive.
195        osg::GeometryNew* linesGeom = new osg::GeometryNew();
196       
197        // this time we'll preallocate the vertex array to the size
198        // and then use an iterator to fill in the values, a bit perverse
199        // but does demonstrate that we have just a standard std::vector underneath.
200        osg::Vec3Array* vertices = new osg::Vec3Array(5);
201        osg::Vec3Array::iterator vitr = vertices->begin();
202        (vitr++)->set(-0.0741545, -2.15188e-09, 0.416089);
203        (vitr++)->set(0.234823, -2.15188e-09, 0.259541);
204        (vitr++)->set(0.164788, -2.15188e-09, 0.366653);
205        (vitr++)->set(-0.0288379, -2.15188e-09, 0.333695);
206        (vitr++)->set(-0.0453167, -2.15188e-09, 0.280139);
207       
208        // pass the created vertex array to the points geometry object.
209        linesGeom->setVertexArray(vertices);
210       
211        // set the colors as before, plus using the above
212        osg::Vec4Array* colors = new osg::Vec4Array;
213        colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
214        linesGeom->setColorArray(colors);
215        linesGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
216
217
218        // set the normal in the same way color.
219        osg::Vec3Array* normals = new osg::Vec3Array;
220        normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
221        linesGeom->setNormalArray(normals);
222        linesGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
223
224
225        // This time we simply use primitive, and hardwire the number of coords to use
226        // since we know up front,
227        linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,0,5));
228       
229       
230        // add the points geometry to the geode.
231        geode->addDrawable(linesGeom);
232    }
233
234    // create LINE_LOOP
235    {
236        // create Geometry object to store all the vertices and lines primitive.
237        osg::GeometryNew* linesGeom = new osg::GeometryNew();
238       
239        // this time we'll a C arrays to initialize the vertices.
240       
241        osg::Vec3 myCoords[] =
242        {
243            osg::Vec3(0.741546, -2.15188e-09, 0.453167),
244            osg::Vec3(0.840418, -2.15188e-09, 0.304858),
245            osg::Vec3(1.12468, -2.15188e-09, 0.300738),
246            osg::Vec3(1.03816, 9.18133e-09, 0.453167),
247            osg::Vec3(0.968129, -2.15188e-09, 0.337815),
248            osg::Vec3(0.869256, -2.15188e-09, 0.531441)
249        };
250       
251        int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
252       
253        osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);
254       
255        // pass the created vertex array to the points geometry object.
256        linesGeom->setVertexArray(vertices);
257       
258        // set the colors as before, plus using the above
259        osg::Vec4Array* colors = new osg::Vec4Array;
260        colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
261        linesGeom->setColorArray(colors);
262        linesGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
263       
264
265        // set the normal in the same way color.
266        osg::Vec3Array* normals = new osg::Vec3Array;
267        normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
268        linesGeom->setNormalArray(normals);
269        linesGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
270       
271
272        // This time we simply use primitive, and hardwire the number of coords to use
273        // since we know up front,
274        linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,numCoords));
275       
276       
277        // add the points geometry to the geode.
278        geode->addDrawable(linesGeom);
279    }
280
281
282
283
284    // now we'll stop creating separate normal and color arrays
285    // since we are using the same values all the time, we'll just
286    // share the same ColorArray and NormalArrays..
287
288    // set the colors as before, use a ref_ptr rather than just
289    // standard C pointer, as that in the case of it not being
290    // assigned it will still be cleaned up automatically.
291    osg::ref_ptr<osg::Vec4Array> shared_colors = new osg::Vec4Array;
292    shared_colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
293
294    // same trick for shared normal.
295    osg::ref_ptr<osg::Vec3Array> shared_normals = new osg::Vec3Array;
296    shared_normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
297
298
299
300    // Note on vertex ordering.
301    // According to the OpenGL diagram vertices should be specified in a clockwise direction.
302    // In reality you need to specify coords for polygons in a anticlockwise direction
303    // for their front face to be pointing towards you; get this wrong and you could
304    // find back face culling removing the wrong faces of your models.  The OpenGL diagram
305    // is just plain wrong, but it's a nice diagram so we'll keep it for now!
306
307    // create POLYGON
308    {
309        // create Geometry object to store all the vertices and lines primitive.
310        osg::GeometryNew* polyGeom = new osg::GeometryNew();
311       
312        // this time we'll use C arrays to initialize the vertices.
313        // note, anticlockwise ordering.
314        // note II, OpenGL polygons must be convex, planar polygons, otherwise
315        // undefined results will occur.  If you have concave polygons or ones
316        // that cross over themselves then use the osgUtil::Tessellator to fix
317        // the polygons into a set of valid polygons.
318        osg::Vec3 myCoords[] =
319        {
320            osg::Vec3(-1.0464, 0.0f, -0.193626),
321            osg::Vec3(-1.0258, 0.0f, -0.26778),
322            osg::Vec3(-0.807461, 0.0f, -0.181267),
323            osg::Vec3(-0.766264, 0.0f, -0.0576758),
324            osg::Vec3(-0.980488, 0.0f, -0.094753)
325        };
326       
327        int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
328       
329        osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);
330       
331        // pass the created vertex array to the points geometry object.
332        polyGeom->setVertexArray(vertices);
333       
334        // use the shared color array.
335        polyGeom->setColorArray(shared_colors.get());
336        polyGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
337       
338
339        // use the shared normal array.
340        polyGeom->setNormalArray(shared_normals.get());
341        polyGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
342       
343
344        // This time we simply use primitive, and hardwire the number of coords to use
345        // since we know up front,
346        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,numCoords));
347
348        printTriangles("Polygon",*polyGeom);
349       
350        // add the points geometry to the geode.
351        geode->addDrawable(polyGeom);
352    }
353
354
355    // create QUADS
356    {
357        // create Geometry object to store all the vertices and lines primitive.
358        osg::GeometryNew* polyGeom = new osg::GeometryNew();
359       
360        // note, anticlockwise ordering.
361        osg::Vec3 myCoords[] =
362        {
363            osg::Vec3(0.0247182, 0.0f, -0.156548),
364            osg::Vec3(0.0247182, 0.0f, -0.00823939),
365            osg::Vec3(-0.160668, 0.0f, -0.0453167),
366            osg::Vec3(-0.222464, 0.0f, -0.13183),
367
368            osg::Vec3(0.238942, 0.0f, -0.251302),
369            osg::Vec3(0.333696, 0.0f, 0.0329576),
370            osg::Vec3(0.164788, 0.0f, -0.0453167),
371            osg::Vec3(0.13595,  0.0f, -0.255421)
372        };
373       
374        int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
375       
376        osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);
377       
378        // pass the created vertex array to the points geometry object.
379        polyGeom->setVertexArray(vertices);
380       
381        // use the shared color array.
382        polyGeom->setColorArray(shared_colors.get());
383        polyGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
384       
385
386        // use the shared normal array.
387        polyGeom->setNormalArray(shared_normals.get());
388        polyGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
389       
390
391        // This time we simply use primitive, and hardwire the number of coords to use
392        // since we know up front,
393        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,numCoords));
394       
395       
396        printTriangles("Quads",*polyGeom);
397
398        // add the points geometry to the geode.
399        geode->addDrawable(polyGeom);
400    }
401
402    // create QUAD_STRIP
403    {
404        // create Geometry object to store all the vertices and lines primitive.
405        osg::GeometryNew* polyGeom = new osg::GeometryNew();
406       
407        // note, first coord at top, second at bottom, reverse to that buggy OpenGL image..
408        osg::Vec3 myCoords[] =
409        {
410            osg::Vec3(0.733306, -2.15188e-09, -0.0741545),
411            osg::Vec3(0.758024, -2.15188e-09, -0.205985),
412
413            osg::Vec3(0.885735, -2.15188e-09, -0.0576757),
414            osg::Vec3(0.885735, -2.15188e-09, -0.214224),
415
416            osg::Vec3(0.964009, 9.18133e-09, -0.0370773),
417            osg::Vec3(1.0464, 9.18133e-09, -0.173027),
418
419            osg::Vec3(1.11232, -2.15188e-09, 0.0123591),
420            osg::Vec3(1.12468, 9.18133e-09, -0.164788),
421        };
422       
423        int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
424       
425        osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);
426       
427        // pass the created vertex array to the points geometry object.
428        polyGeom->setVertexArray(vertices);
429       
430        // use the shared color array.
431        polyGeom->setColorArray(shared_colors.get());
432        polyGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
433       
434
435        // use the shared normal array.
436        polyGeom->setNormalArray(shared_normals.get());
437        polyGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
438       
439
440        // This time we simply use primitive, and hardwire the number of coords to use
441        // since we know up front,
442        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,numCoords));
443       
444       
445        printTriangles("Quads strip",*polyGeom);
446
447        // add the points geometry to the geode.
448        geode->addDrawable(polyGeom);
449    }
450
451    // create TRIANGLES, TRIANGLE_STRIP and TRIANGLE_FAN all in one Geometry/
452    {
453        // create Geometry object to store all the vertices and lines primitive.
454        osg::GeometryNew* polyGeom = new osg::GeometryNew();
455       
456        // note, first coord at top, second at bottom, reverse to that buggy OpenGL image..
457        osg::Vec3 myCoords[] =
458        {
459            // TRIANGLES 6 vertices, v0..v5
460            // note in anticlockwise order.
461            osg::Vec3(-1.12056, -2.15188e-09, -0.840418),
462            osg::Vec3(-0.95165, -2.15188e-09, -0.840418),
463            osg::Vec3(-1.11644, 9.18133e-09, -0.716827),
464
465            // note in anticlockwise order.
466            osg::Vec3(-0.840418, 9.18133e-09, -0.778623),
467            osg::Vec3(-0.622074, 9.18133e-09, -0.613835),
468            osg::Vec3(-1.067, 9.18133e-09, -0.609715),
469
470            // TRIANGLE STRIP 6 vertices, v6..v11
471            // note defined top point first,
472            // then anticlockwise for the next two points,
473            // then alternating to bottom there after.
474            osg::Vec3(-0.160668, -2.15188e-09, -0.531441),
475            osg::Vec3(-0.160668, -2.15188e-09, -0.749785),
476            osg::Vec3(0.0617955, 9.18133e-09, -0.531441),
477            osg::Vec3(0.168908, -2.15188e-09, -0.753905),
478            osg::Vec3(0.238942, -2.15188e-09, -0.531441),
479            osg::Vec3(0.280139, -2.15188e-09, -0.823939),
480
481            // TRIANGLE FAN 5 vertices, v12..v16
482            // note defined in anticlockwise order.
483            osg::Vec3(0.844538, 9.18133e-09, -0.712708),
484            osg::Vec3(1.0258, 9.18133e-09, -0.799221),
485            osg::Vec3(1.03816, -2.15188e-09, -0.692109),
486            osg::Vec3(0.988727, 9.18133e-09, -0.568518),
487            osg::Vec3(0.840418, -2.15188e-09, -0.506723),
488
489        };
490       
491        int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
492       
493        osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);
494       
495        // pass the created vertex array to the points geometry object.
496        polyGeom->setVertexArray(vertices);
497       
498        // use the shared color array.
499        polyGeom->setColorArray(shared_colors.get());
500        polyGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
501       
502
503        // use the shared normal array.
504        polyGeom->setNormalArray(shared_normals.get());
505        polyGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
506       
507
508        // This time we simply use primitive, and hardwire the number of coords to use
509        // since we know up front,
510        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,6));
511        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP,6,6));
512        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,12,5));
513       
514        // polygon stipple
515        osg::StateSet* stateSet = new osg::StateSet();
516        polyGeom->setStateSet(stateSet);
517       
518        #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
519        osg::PolygonStipple* polygonStipple = new osg::PolygonStipple;
520        stateSet->setAttributeAndModes(polygonStipple,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
521        #endif
522       
523        printTriangles("Triangles/Strip/Fan",*polyGeom);
524
525        // add the points geometry to the geode.
526        geode->addDrawable(polyGeom);
527    }
528   
529    return geode;   
530}
531
532
533// define a node callback to animate a transform as a cycle along the y axis, between 0 and 2.0.
534class MyTransformCallback : public osg::NodeCallback
535{
536
537    public:
538
539        MyTransformCallback(float angularVelocity)
540        {
541            _angular_velocity = angularVelocity;
542        }
543
544        virtual void operator() (osg::Node* node, osg::NodeVisitor* nv)
545        {
546            osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(node);               
547            if (nv && transform && nv->getFrameStamp())
548            {
549                double time = nv->getFrameStamp()->getSimulationTime();
550                transform->setMatrix(osg::Matrix::translate(0.0f,1.0f+cosf(time*_angular_velocity),0.0f));
551            }
552           
553            // must continue subgraph traversal.
554            traverse(node,nv);           
555           
556        }
557       
558    protected:
559   
560        float               _angular_velocity;
561
562};
563
564
565osg::Node* createBackground()
566{   
567
568    // we'll create a texture mapped quad to sit behind the Geometry
569    osg::Image* image = osgDB::readImageFile("Images/primitives.gif");
570    if (!image) return NULL;
571   
572 
573    // create Geometry object to store all the vertices and lines primitive.
574    osg::GeometryNew* polyGeom = new osg::GeometryNew();
575
576    // note, anticlockwise ordering.
577    osg::Vec3 myCoords[] =
578    {
579        osg::Vec3(-1.22908f,0.0f,1.0f),
580        osg::Vec3(-1.22908f,0.0f,-1.0f),
581        osg::Vec3(1.22908f,0.0f,-1.0f),
582        osg::Vec3(1.22908f,0.0f,1.0f)
583    };
584
585    int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
586
587    // pass the created vertex array to the points geometry object.
588    polyGeom->setVertexArray(new osg::Vec3Array(numCoords,myCoords));
589
590    osg::Vec4Array* colors = new osg::Vec4Array;
591    colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
592    polyGeom->setColorArray(colors);
593    polyGeom->setColorBinding(osg::GeometryNew::BIND_OVERALL);
594
595
596    // set the normal in the same way color.
597    osg::Vec3Array* normals = new osg::Vec3Array;
598    normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
599    polyGeom->setNormalArray(normals);
600    polyGeom->setNormalBinding(osg::GeometryNew::BIND_OVERALL);
601
602    osg::Vec2 myTexCoords[] =
603    {
604        osg::Vec2(0,1),
605        osg::Vec2(0,0),
606        osg::Vec2(1,0),
607        osg::Vec2(1,1)
608    };
609
610    int numTexCoords = sizeof(myTexCoords)/sizeof(osg::Vec2);
611
612    // pass the created tex coord array to the points geometry object,
613    // and use it to set texture unit 0.
614    polyGeom->setTexCoordArray(0,new osg::Vec2Array(numTexCoords,myTexCoords));
615
616    // well use indices and DrawElements to define the primitive this time.
617    unsigned short myIndices[] =
618    {
619        0,
620        1,
621        3,
622        2
623    };
624
625    int numIndices = sizeof(myIndices)/sizeof(unsigned short);
626
627    // There are three variants of the DrawElements osg::Primitive, UByteDrawElements which
628    // contains unsigned char indices, UShortDrawElements which contains unsigned short indices,
629    // and UIntDrawElements which contains ... unsigned int indices. 
630    // The first parameter to DrawElements is
631    polyGeom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP,numIndices,myIndices));
632
633    // new we need to add the texture to the Drawable, we do so by creating a
634    // StateSet to contain the Texture2D StateAttribute.
635    osg::StateSet* stateset = new osg::StateSet;
636
637    // set up the texture.
638    osg::Texture2D* texture = new osg::Texture2D;
639    texture->setImage(image);
640
641    stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
642
643    polyGeom->setStateSet(stateset);
644
645 
646    // create the Geode (Geometry Node) to contain all our osg::Geometry objects.
647    osg::Geode* geode = new osg::Geode();
648
649    // add the points geometry to the geode.
650    geode->addDrawable(polyGeom);
651
652    //return geode;
653
654    // create a transform to move the background back and forward with.
655 
656    osg::MatrixTransform* transform = new osg::MatrixTransform();
657    transform->setUpdateCallback(new MyTransformCallback(1.0f));
658    transform->addChild(geode);
659
660    return transform;
661}
662
663int main(int, char **)
664{
665    // create the model
666    osg::Group* root = new osg::Group;
667    root->addChild( createScene() );
668    root->addChild( createBackground() );
669
670    //osgDB::writeNodeFile(*root,"geoemtry.osgt");
671
672    osgViewer::Viewer viewer;
673
674    // add model to viewer.
675    viewer.setSceneData( root );
676
677    return viewer.run();
678}
Note: See TracBrowser for help on using the browser.