root/OpenSceneGraph/trunk/src/osgPlugins/vrml/Primitives.cpp @ 13557

Revision 13557, 20.9 kB (checked in by robert, 13 hours ago)

Improved handling of setting of the depth of the UI.

  • Property svn:eol-style set to native
Line 
1// -*-c++-*-
2
3#include "ReaderWriterVRML2.h"
4
5#include <complex>
6
7#if defined(_MSC_VER)
8#   pragma warning(disable: 4250)
9#   pragma warning(disable: 4290)
10#   pragma warning(disable: 4800)
11#endif
12
13#include <openvrml/node.h>
14
15#include <osg/CullFace>
16
17osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedLineSet(openvrml::node *vrml_ifs) const
18{
19    osg::ref_ptr<deprecated_osg::Geometry> osg_geom = new deprecated_osg::Geometry();
20
21    osg_geom->addPrimitiveSet(new osg::DrawArrayLengths(osg::PrimitiveSet::LINE_STRIP));
22
23    // get array of vertex coordinate_nodes
24    if(vrml_ifs->type().id() == "IndexedLineSet")
25    {
26        std::auto_ptr<openvrml::field_value> fv = vrml_ifs->field("coord");
27        const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
28
29        openvrml::coordinate_node *vrml_coord_node = dynamic_cast<openvrml::coordinate_node *>((sfn->value()).get());
30        const std::vector<openvrml::vec3f> &vrml_coord = vrml_coord_node->point();
31
32        osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
33
34        unsigned i;
35        for (i = 0; i < vrml_coord.size(); i++)
36        {
37            openvrml::vec3f vec = vrml_coord[i];
38            osg_vertices->push_back(osg::Vec3(vec[0], vec[1], vec[2]));
39        }
40
41        osg_geom->setVertexArray(osg_vertices.get());
42
43        // get array of vertex indices
44        std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("coordIndex");
45        const openvrml::mfint32 *vrml_coord_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
46
47        osg::ref_ptr<osg::IntArray> osg_vert_index = new osg::IntArray();
48
49        int num_vert = 0;
50        for (i = 0; i < vrml_coord_index->value().size(); i++)
51        {
52            int index = vrml_coord_index->value()[i];
53            if (index == -1)
54            {
55                static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0))->push_back(num_vert);
56                num_vert = 0;
57            }
58            else
59            {
60                osg_vert_index->push_back(index);
61                ++num_vert;
62            }
63        }
64
65        if (num_vert)
66        {
67            //GvdB: Last coordIndex wasn't -1
68            static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0))->push_back(num_vert);
69        }
70
71        osg_geom->setVertexIndices(osg_vert_index.get());
72    }
73
74    // get array of colours per vertex (if specified)
75    {
76        std::auto_ptr<openvrml::field_value> fv = vrml_ifs->field("color");
77        const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
78        openvrml::color_node *vrml_color_node = dynamic_cast<openvrml::color_node *>(sfn->value().get());
79
80        if (vrml_color_node != 0) // if no colors, node is NULL pointer
81        {
82            const std::vector<openvrml::color> &vrml_colors = vrml_color_node->color();
83
84            osg::ref_ptr<osg::Vec3Array> osg_colors = new osg::Vec3Array();
85
86            unsigned i;
87            for (i = 0; i < vrml_colors.size(); i++)
88            {
89                const openvrml::color color = vrml_colors[i];
90                osg_colors->push_back(osg::Vec3(color.r(), color.g(), color.b()));
91            }
92            osg_geom->setColorArray(osg_colors.get());
93
94            // get array of color indices
95            std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("colorIndex");
96            const openvrml::mfint32 *vrml_color_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
97
98            osg::ref_ptr<osg::IntArray> osg_color_index = new osg::IntArray();
99
100            if(vrml_color_index->value().size() > 0)
101            {
102                for (i = 0; i < vrml_color_index->value().size(); i++)
103                {
104                    int index = vrml_color_index->value()[i];
105                    if (index != -1) {
106                        osg_color_index->push_back(index);
107                    }
108                }
109                osg_geom->setColorIndices(osg_color_index.get());
110            } else
111                // unspecified, use coordIndices field
112                osg_geom->setColorIndices(const_cast<osg::IndexArray*>(osg_geom->getVertexIndices()));
113
114            // get color binding
115            std::auto_ptr<openvrml::field_value> fv3 = vrml_ifs->field("colorPerVertex");
116            const openvrml::sfbool *vrml_color_per_vertex = dynamic_cast<const openvrml::sfbool *>(fv3.get());
117
118            if (vrml_color_per_vertex->value())
119            {
120                osg_geom->setColorBinding(deprecated_osg::Geometry::BIND_PER_VERTEX);
121            } else
122            {
123                osg_geom->setColorBinding(deprecated_osg::Geometry::BIND_PER_PRIMITIVE);
124            }
125        }
126    }
127
128    osg_geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
129
130    return osg_geom;
131}
132
133osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Box(openvrml::node* vrml_box) const
134{
135    std::auto_ptr<openvrml::field_value> fv = vrml_box->field("size");
136    const openvrml::vec3f &size = static_cast<const openvrml::sfvec3f *> (fv.get())->value();
137
138    osg::Vec3 halfSize(size[0] * 0.5f, size[1] * 0.5f, size[2] * 0.5f);
139
140    BoxLibrary::const_iterator it = m_boxLibrary.find(halfSize);
141    if (it != m_boxLibrary.end())
142    {
143        return (*it).second.get();
144    }
145
146    osg::ref_ptr<deprecated_osg::Geometry> osg_geom = new deprecated_osg::Geometry();
147    osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
148    osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
149    osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array();
150
151    osg::ref_ptr<osg::DrawArrays> box = new osg::DrawArrays(osg::PrimitiveSet::QUADS);
152
153    osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2]));
154    osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2]));
155    osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2]));
156    osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2]));
157
158    osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2]));
159    osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2]));
160    osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2]));
161    osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2]));
162
163    osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2]));
164    osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2]));
165    osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2]));
166    osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2]));
167
168    osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2]));
169    osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2]));
170    osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2]));
171    osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2]));
172
173    osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2]));
174    osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2]));
175    osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2]));
176    osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2]));
177
178    osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2]));
179    osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2]));
180    osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2]));
181    osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2]));
182
183    for (int i = 0; i != 6; ++i)
184    {
185        osg_texcoords->push_back(osg::Vec2(0.0f, 1.0f));
186        osg_texcoords->push_back(osg::Vec2(0.0f, 0.0f));
187        osg_texcoords->push_back(osg::Vec2(1.0f, 0.0f));
188        osg_texcoords->push_back(osg::Vec2(1.0f, 1.0f));
189    }
190
191    osg_normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
192    osg_normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
193    osg_normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
194    osg_normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));
195    osg_normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
196    osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
197
198    box->setCount(osg_vertices->size());
199
200    osg_geom->addPrimitiveSet(box.get());
201
202    osg_geom->setVertexArray(osg_vertices.get());
203    osg_geom->setTexCoordArray(0, osg_texcoords.get());
204    osg_geom->setNormalArray(osg_normals.get());
205    osg_geom->setNormalBinding(deprecated_osg::Geometry::BIND_PER_PRIMITIVE);
206
207    osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
208
209    m_boxLibrary[halfSize] = osg_geom;
210
211    return osg_geom.get();
212}
213
214osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Sphere(openvrml::node* vrml_sphere) const
215{
216    std::auto_ptr<openvrml::field_value> fv = vrml_sphere->field("radius");
217    const float radius = static_cast<const openvrml::sffloat *> (fv.get())->value();
218
219    SphereLibrary::const_iterator it = m_sphereLibrary.find(radius);
220    if (it != m_sphereLibrary.end())
221    {
222        return (*it).second.get();
223    }
224
225    osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry();
226    osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
227    osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
228    osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array();
229
230    unsigned int numSegments = 40;
231    unsigned int numRows = 20;
232
233    const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments);
234    const float texCoordSDelta = 1.0f / float(numSegments);
235    const float phiDelta = float(osg::PI) / float(numRows);
236    const float texCoordTDelta = 1.0f / float(numRows);
237
238    float phi = -0.5f * float(osg::PI);
239    float texCoordT = 0.0f;
240
241    osg::ref_ptr<osg::DrawArrayLengths> sphere = new osg::DrawArrayLengths(osg::PrimitiveSet::QUAD_STRIP);
242
243    for (unsigned int i = 0; i < numRows; ++i, phi += phiDelta, texCoordT += texCoordTDelta)
244    {
245        std::complex<float> latBottom = std::polar(1.0f, phi);
246        std::complex<float> latTop = std::polar(1.0f, phi + phiDelta);
247        std::complex<float> eBottom = latBottom * radius;
248        std::complex<float> eTop = latTop * radius;
249
250        float theta = 0.0f;
251        float texCoordS = 0.0f;
252
253        for (unsigned int j = 0; j < numSegments; ++j, theta += thetaDelta, texCoordS += texCoordSDelta)
254        {
255            std::complex<float> n = -std::polar(1.0f, theta);
256
257            osg_normals->push_back(osg::Vec3(latTop.real() * n.imag(), latTop.imag(), latTop.real() * n.real()));
258            osg_normals->push_back(osg::Vec3(latBottom.real() * n.imag(), latBottom.imag(), latBottom.real() * n.real()));
259
260            osg_texcoords->push_back(osg::Vec2(texCoordS, texCoordT + texCoordTDelta));
261            osg_texcoords->push_back(osg::Vec2(texCoordS, texCoordT));
262
263            osg_vertices->push_back(osg::Vec3(eTop.real() * n.imag(), eTop.imag(), eTop.real() * n.real()));
264            osg_vertices->push_back(osg::Vec3(eBottom.real() * n.imag(), eBottom.imag(), eBottom.real() * n.real()));
265        }
266
267        osg_normals->push_back(osg::Vec3(0.0f, latTop.imag(), -latTop.real()));
268        osg_normals->push_back(osg::Vec3(0.0f, latBottom.imag(), -latBottom.real()));
269
270        osg_texcoords->push_back(osg::Vec2(1.0f, texCoordT + texCoordTDelta));
271        osg_texcoords->push_back(osg::Vec2(1.0f, texCoordT));
272
273        osg_vertices->push_back(osg::Vec3(0.0f, eTop.imag(), -eTop.real()));
274        osg_vertices->push_back(osg::Vec3(0.0f, eBottom.imag(), -eBottom.real()));
275
276        sphere->push_back(numSegments * 2 + 2);
277    }
278
279    osg_geom->addPrimitiveSet(sphere.get());
280
281    osg_geom->setVertexArray(osg_vertices.get());
282    osg_geom->setTexCoordArray(0, osg_texcoords.get());
283    osg_geom->setNormalArray(osg_normals.get());
284    osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
285
286    osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
287
288    m_sphereLibrary[radius] = osg_geom;
289
290    return osg_geom.get();
291}
292
293osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cone(openvrml::node* vrml_cone) const
294{
295    float height = static_cast<const openvrml::sffloat*>(vrml_cone->field("height").get())->value();
296    float radius = static_cast<const openvrml::sffloat*>(vrml_cone->field("bottomRadius").get())->value();
297    bool bottom = static_cast<const openvrml::sfbool*>(vrml_cone->field("bottom").get())->value();
298    bool side = static_cast<const openvrml::sfbool*>(vrml_cone->field("side").get())->value();
299
300    QuadricKey key(height, radius, bottom, side, false);
301
302    ConeLibrary::const_iterator it = m_coneLibrary.find(key);
303    if (it != m_coneLibrary.end())
304    {
305        return (*it).second.get();
306    }
307
308    osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry();
309    osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
310    osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
311    osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array();
312
313    unsigned int numSegments = 40;
314
315    const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments);
316
317    float topY = height * 0.5f;
318    float bottomY = height * -0.5f;
319
320    if (side)
321    {
322        osg::ref_ptr<osg::DrawArrays> side = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP);
323
324        const float texCoordDelta = 1.0f / float(numSegments);
325        float theta = 0.0f;
326        float texCoord = 0.0f;
327
328        for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta, texCoord += texCoordDelta)
329        {
330            std::complex<float> n = -std::polar(1.0f, theta);
331            std::complex<float> e = n * radius;
332
333            osg::Vec3 normal(n.imag() * height, radius, n.real() * height);
334            normal.normalize();
335
336            osg_normals->push_back(normal);
337            osg_normals->push_back(normal);
338
339            osg_texcoords->push_back(osg::Vec2(texCoord, 1.0f));
340            osg_texcoords->push_back(osg::Vec2(texCoord, 0.0f));
341
342            osg_vertices->push_back(osg::Vec3(0.0f, topY, 0.0f));
343            osg_vertices->push_back(osg::Vec3(e.imag(), bottomY, e.real()));
344        }
345
346        // do last point by hand to ensure no round off errors.
347
348        osg::Vec3 normal(0.0f, radius, -height);
349        normal.normalize();
350
351        osg_normals->push_back(normal);
352        osg_normals->push_back(normal);
353
354        osg_texcoords->push_back(osg::Vec2(1.0f, 1.0f));
355        osg_texcoords->push_back(osg::Vec2(1.0f, 0.0f));
356
357        osg_vertices->push_back(osg::Vec3(0.0f, topY, 0.0f));
358        osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius));
359
360        side->setCount(osg_vertices->size());
361        osg_geom->addPrimitiveSet(side.get());
362    }
363
364    if (bottom)
365    {
366        osg::ref_ptr<osg::DrawArrays> bottom = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN);
367
368        size_t first = osg_vertices->size();
369        bottom->setFirst(first);
370
371        float theta = 0.0f;
372
373        for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta)
374        {
375            std::complex<float> n = -std::polar(1.0f, theta);
376            std::complex<float> e = n * radius;
377
378            osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
379            osg_texcoords->push_back(osg::Vec2(0.5f - 0.5f * n.imag(), 0.5f + 0.5f * n.real()));
380            osg_vertices->push_back(osg::Vec3(-e.imag(), bottomY, e.real()));
381        }
382
383        // do last point by hand to ensure no round off errors.
384
385        osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
386        osg_texcoords->push_back(osg::Vec2(0.5f, 0.0f));
387        osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius));
388
389        bottom->setCount(osg_vertices->size() - first);
390        osg_geom->addPrimitiveSet(bottom.get());
391    }
392
393    osg_geom->setVertexArray(osg_vertices.get());
394    osg_geom->setTexCoordArray(0, osg_texcoords.get());
395    osg_geom->setNormalArray(osg_normals.get());
396    osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
397
398    osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
399
400    m_coneLibrary[key] = osg_geom;
401
402    return osg_geom.get();
403}
404
405osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cylinder(openvrml::node* vrml_cylinder) const
406{
407    float height = static_cast<const openvrml::sffloat*>(vrml_cylinder->field("height").get())->value();
408    float radius = static_cast<const openvrml::sffloat*>(vrml_cylinder->field("radius").get())->value();
409    bool bottom = static_cast<const openvrml::sfbool*>(vrml_cylinder->field("bottom").get())->value();
410    bool side = static_cast<const openvrml::sfbool*>(vrml_cylinder->field("side").get())->value();
411    bool top = static_cast<const openvrml::sfbool*>(vrml_cylinder->field("top").get())->value();
412
413    QuadricKey key(height, radius, bottom, side, top);
414
415    CylinderLibrary::const_iterator it = m_cylinderLibrary.find(key);
416    if (it != m_cylinderLibrary.end())
417    {
418        return (*it).second.get();
419    }
420
421    osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry();
422    osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
423    osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
424    osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array();
425
426    unsigned int numSegments = 40;
427
428    const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments);
429
430    float topY = height * 0.5f;
431    float bottomY = height * -0.5f;
432
433    if (side)
434    {
435        osg::ref_ptr<osg::DrawArrays> side = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP);
436
437        const float texCoordDelta = 1.0f / float(numSegments);
438        float theta = 0.0f;
439        float texCoord = 0.0f;
440
441        for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta, texCoord += texCoordDelta)
442        {
443            std::complex<float> n = -std::polar(1.0f, theta);
444            std::complex<float> e = n * radius;
445
446            osg::Vec3 normal(n.imag(), 0.0f, n.real());
447
448            osg_normals->push_back(normal);
449            osg_normals->push_back(normal);
450
451            osg_texcoords->push_back(osg::Vec2(texCoord, 1.0f));
452            osg_texcoords->push_back(osg::Vec2(texCoord, 0.0f));
453
454            osg_vertices->push_back(osg::Vec3(e.imag(), topY, e.real()));
455            osg_vertices->push_back(osg::Vec3(e.imag(), bottomY, e.real()));
456        }
457
458        // do last point by hand to ensure no round off errors.
459
460        osg::Vec3 normal(0.0f, 0.0f, -1.0f);
461        osg_normals->push_back(normal);
462        osg_normals->push_back(normal);
463
464        osg_texcoords->push_back(osg::Vec2(1.0f, 1.0f));
465        osg_texcoords->push_back(osg::Vec2(1.0f, 0.0f));
466
467        osg_vertices->push_back(osg::Vec3(0.0f, topY, -radius));
468        osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius));
469
470        side->setCount(osg_vertices->size());
471        osg_geom->addPrimitiveSet(side.get());
472    }
473
474    if (bottom)
475    {
476        osg::ref_ptr<osg::DrawArrays> bottom = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN);
477
478        size_t first = osg_vertices->size();
479        bottom->setFirst(first);
480
481        float theta = 0.0f;
482
483        for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta)
484        {
485            std::complex<float> n = -std::polar(1.0f, theta);
486            std::complex<float> e = n * radius;
487
488            osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
489            osg_texcoords->push_back(osg::Vec2(0.5f - 0.5f * n.imag(), 0.5f + 0.5f * n.real()));
490            osg_vertices->push_back(osg::Vec3(-e.imag(), bottomY, e.real()));
491        }
492
493        // do last point by hand to ensure no round off errors.
494
495        osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
496        osg_texcoords->push_back(osg::Vec2(0.5f, 0.0f));
497        osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius));
498
499        bottom->setCount(osg_vertices->size() - first);
500        osg_geom->addPrimitiveSet(bottom.get());
501    }
502
503    if (top)
504    {
505        osg::ref_ptr<osg::DrawArrays> top = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN);
506
507        size_t first = osg_vertices->size();
508        top->setFirst(first);
509
510        float theta = 0.0f;
511
512        for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta)
513        {
514            std::complex<float> n = -std::polar(1.0f, theta);
515            std::complex<float> e = n * radius;
516
517            osg_normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
518            osg_texcoords->push_back(osg::Vec2(0.5f + 0.5f * n.imag(), 0.5f - 0.5f * n.real()));
519            osg_vertices->push_back(osg::Vec3(e.imag(), topY, e.real()));
520        }
521
522        // do last point by hand to ensure no round off errors.
523
524        osg_normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
525        osg_texcoords->push_back(osg::Vec2(0.5f, 1.0f));
526        osg_vertices->push_back(osg::Vec3(0.0f, topY, -radius));
527
528        top->setCount(osg_vertices->size() - first);
529        osg_geom->addPrimitiveSet(top.get());
530    }
531
532    osg_geom->setVertexArray(osg_vertices.get());
533    osg_geom->setTexCoordArray(0, osg_texcoords.get());
534    osg_geom->setNormalArray(osg_normals.get());
535    osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
536
537    osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
538
539    m_cylinderLibrary[key] = osg_geom;
540
541    return osg_geom.get();
542}
Note: See TracBrowser for help on using the browser.