root/OpenSceneGraph/trunk/src/osgUtil/SceneGraphBuilder.cpp @ 13041

Revision 13041, 14.7 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13#include <osgUtil/SceneGraphBuilder>
14
15#include <osg/Notify>
16#include <osg/io_utils>
17
18#include <osg/PrimitiveSet>
19#include <osg/Texture>
20#include <osg/AlphaFunc>
21#include <osg/BlendFunc>
22#include <osg/LineStipple>
23#include <osg/Depth>
24#include <osg/CullFace>
25#include <osg/FrontFace>
26#include <osg/LineWidth>
27#include <osg/Point>
28#include <osg/PolygonMode>
29#include <osg/PolygonOffset>
30#include <osg/PolygonStipple>
31#include <osg/ShadeModel>
32#include <osg/ShapeDrawable>
33
34using namespace osgUtil;
35
36SceneGraphBuilder::SceneGraphBuilder():
37    _statesetAssigned(false),
38    _normalSet(false),
39    _normal(0.0f,0.0f,1.0f),
40    _colorSet(false),
41    _color(1.0f,1.0f,1.0f,1.0f),
42    _maxNumTexCoordComponents(0),
43    _texCoord(0.f,0.0f,0.0f,1.0f),
44    _primitiveMode(0)
45{
46}
47
48
49///////////////////////////////////////////////////////////////////////////////////////////
50//
51// OpenGL 1.0 building methods
52//
53void SceneGraphBuilder::PushMatrix()
54{
55    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
56    else _matrixStack.push_back(_matrixStack.back());
57}
58
59void SceneGraphBuilder::PopMatrix()
60{
61    if (!_matrixStack.empty()) _matrixStack.pop_back();
62
63    matrixChanged();
64}
65
66void SceneGraphBuilder::LoadIdentity()
67{
68    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
69    _matrixStack.back().makeIdentity();
70
71    matrixChanged();
72}
73
74void SceneGraphBuilder::LoadMatrixd(const GLdouble* m)
75{
76    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
77    _matrixStack.back().set(m);
78
79    matrixChanged();
80}
81
82void SceneGraphBuilder::MultMatrixd(const GLdouble* m)
83{
84    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
85    _matrixStack.back().preMult(osg::Matrixd(m));
86
87    matrixChanged();
88}
89
90void SceneGraphBuilder::Translated(GLdouble x, GLdouble y, GLdouble z)
91{
92    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
93    _matrixStack.back().preMultTranslate(osg::Vec3d(x,y,z));
94
95    matrixChanged();
96}
97
98void SceneGraphBuilder::Scaled(GLdouble x, GLdouble y, GLdouble z)
99{
100    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
101    _matrixStack.back().preMultScale(osg::Vec3d(x,y,z));
102
103    matrixChanged();
104}
105
106void SceneGraphBuilder::Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
107{
108    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
109    _matrixStack.back().preMultRotate(osg::Quat(osg::inDegrees(angle),osg::Vec3d(x,y,z)));
110
111    matrixChanged();
112}
113
114void SceneGraphBuilder::BlendFunc(GLenum srcFactor, GLenum dstFactor)
115{
116    addAttribute(new osg::BlendFunc(srcFactor, dstFactor));
117}
118
119void SceneGraphBuilder::CullFace(GLenum mode)
120{
121    addAttribute(new osg::CullFace(osg::CullFace::Mode(mode)));
122}
123
124void SceneGraphBuilder::DepthFunc(GLenum mode)
125{
126    addAttribute(new osg::Depth(osg::Depth::Function(mode)));
127}
128
129void SceneGraphBuilder::FrontFace(GLenum mode)
130{
131    addAttribute(new osg::FrontFace(osg::FrontFace::Mode(mode)));
132}
133
134void SceneGraphBuilder::LineStipple(GLint factor, GLushort pattern)
135{
136    addAttribute(new osg::LineStipple(factor, pattern));
137}
138
139void SceneGraphBuilder::LineWidth(GLfloat lineWidth)
140{
141    addAttribute(new osg::LineWidth(lineWidth));
142}
143
144void SceneGraphBuilder::PointSize(GLfloat pointSize)
145{
146    addAttribute(new osg::Point(pointSize));
147}
148
149void SceneGraphBuilder::PolygonMode(GLenum face, GLenum mode)
150{
151    addAttribute(new osg::PolygonMode(osg::PolygonMode::Face(face),osg::PolygonMode::Mode(mode)));
152}
153
154void SceneGraphBuilder::PolygonOffset(GLfloat factor, GLfloat units)
155{
156    addAttribute(new osg::PolygonOffset(factor,units));
157}
158
159void SceneGraphBuilder::PolygonStipple(const GLubyte* mask)
160{
161    addAttribute(new osg::PolygonStipple(mask));
162}
163
164void SceneGraphBuilder::ShadeModel(GLenum mode)
165{
166    addAttribute(new osg::ShadeModel(osg::ShadeModel::Mode(mode)));
167}
168void SceneGraphBuilder::Enable(GLenum mode)
169{
170    addMode(mode, true);
171}
172
173void SceneGraphBuilder::Disable(GLenum mode)
174{
175    addMode(mode, false);
176}
177
178void SceneGraphBuilder::Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
179{
180    _normalSet = true;
181    _color.set(red,green,blue,alpha);
182}
183
184void SceneGraphBuilder::Normal3f(GLfloat x, GLfloat y, GLfloat z)
185{
186    _normalSet = true;
187    _normal.set(x,y,z);
188}
189
190void SceneGraphBuilder::TexCoord1f(GLfloat x)
191{
192    _maxNumTexCoordComponents = 1;
193    _texCoord.set(x,0.0f,0.0f,1.0f);
194}
195
196void SceneGraphBuilder::TexCoord2f(GLfloat x, GLfloat y)
197{
198    _maxNumTexCoordComponents = 2;
199    _texCoord.set(x,y,0.0f,1.0f);
200}
201
202void SceneGraphBuilder::TexCoord3f(GLfloat x, GLfloat y, GLfloat z)
203{
204    _maxNumTexCoordComponents = 3;
205    _texCoord.set(x,y,z,1.0);
206}
207
208void SceneGraphBuilder::TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
209{
210    _maxNumTexCoordComponents = 4;
211    _texCoord.set(x,y,z,w);
212}
213
214void SceneGraphBuilder::Vertex3f(GLfloat x, GLfloat y, GLfloat z)
215{
216    osg::Vec3 vertex(x,y,z);
217
218    vertex = vertex * _matrixStack.back();
219
220    if (_vertices.valid()) _vertices->push_back(vertex);
221    if (_normal.valid()) _normals->push_back(_normal);
222    if (_colors.valid()) _colors->push_back(_color);
223    if (_texCoords.valid()) _texCoords->push_back(_texCoord);
224}
225
226void SceneGraphBuilder::Begin(GLenum mode)
227{
228    // reset geometry
229    _primitiveMode = mode;
230    _vertices = new osg::Vec3Array;
231
232    _normalSet = false;
233    _normals = new osg::Vec3Array;
234
235    _colorSet = false;
236    _colors = new osg::Vec4Array;
237
238    _maxNumTexCoordComponents = 0;
239    _texCoords = new osg::Vec4Array;
240
241}
242
243void SceneGraphBuilder::End()
244{
245    allocateGeometry();
246
247    _geometry->setVertexArray(_vertices.get());
248
249    if (_colorSet)
250    {
251         _geometry->setColorArray(_colors.get());
252         _geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
253    }
254    else
255    {
256         osg::Vec4Array* colors = new osg::Vec4Array;
257         colors->push_back(_color);
258
259         _geometry->setColorArray(colors);
260         _geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
261    }
262
263    if (_normalSet)
264    {
265         _geometry->setNormalArray(_normals.get());
266         _geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
267    }
268    else
269    {
270         _geometry->setNormalBinding(osg::Geometry::BIND_OFF);
271    }
272
273    if (_maxNumTexCoordComponents==1)
274    {
275        // convert Vec4Array into FloatArray
276        osg::FloatArray* texCoords = new osg::FloatArray;
277        for(osg::Vec4Array::iterator itr = _texCoords->begin();
278            itr != _texCoords->end();
279            ++itr)
280        {
281            texCoords->push_back(itr->x());
282        }
283         _geometry->setTexCoordArray(0, texCoords);
284    }
285    if (_maxNumTexCoordComponents==2)
286    {
287        // convert Vec4Array into FloatArray
288        osg::Vec2Array* texCoords = new osg::Vec2Array;
289        for(osg::Vec4Array::iterator itr = _texCoords->begin();
290            itr != _texCoords->end();
291            ++itr)
292        {
293            texCoords->push_back(osg::Vec2(itr->x(),itr->y()));
294        }
295         _geometry->setTexCoordArray(0, texCoords);
296    }
297    if (_maxNumTexCoordComponents==3)
298    {
299        // convert Vec4Array into FloatArray
300        osg::Vec3Array* texCoords = new osg::Vec3Array;
301        for(osg::Vec4Array::iterator itr = _texCoords->begin();
302            itr != _texCoords->end();
303            ++itr)
304        {
305            texCoords->push_back(osg::Vec3(itr->x(),itr->y(), itr->z()));
306        }
307         _geometry->setTexCoordArray(0, texCoords);
308    }
309    else if (_maxNumTexCoordComponents==4)
310    {
311         _geometry->setTexCoordArray(0, _texCoords.get());
312    }
313
314    _geometry->addPrimitiveSet(new osg::DrawArrays(_primitiveMode, 0, _vertices->size()));
315
316    completeGeometry();
317}
318
319///////////////////////////////////////////////////////////////////////////////////////////
320//
321//  GLU style building methods
322//
323void SceneGraphBuilder::QuadricDrawStyle(GLenum aDrawStyle)
324{
325    _quadricState._drawStyle = aDrawStyle;
326}
327
328void SceneGraphBuilder::QuadricNormals(GLenum aNormals)
329{
330    _quadricState._normals = aNormals;
331}
332
333void SceneGraphBuilder::QuadricOrientation(GLenum aOrientation)
334{
335    _quadricState._orientation = aOrientation;
336}
337
338void SceneGraphBuilder::QuadricTexture(GLboolean aTexture)
339{
340    _quadricState._texture = aTexture;
341}
342
343void SceneGraphBuilder::Cylinder(GLfloat        aBase,
344                             GLfloat        aTop,
345                             GLfloat        aHeight,
346                             GLint          aSlices,
347                             GLint          aStacks)
348{
349    OSG_NOTICE<<"SceneGraphBuilder::Cylinder("<<aBase<<", "<<aTop<<", "<<aHeight<<", "<<aSlices<<", "<<aStacks<<") not implemented yet"<<std::endl;
350}
351
352void SceneGraphBuilder::Disk(GLfloat        inner,
353                             GLfloat        outer,
354                             GLint          slices,
355                             GLint          /*loops*/)
356{
357    double angle = 0.0;
358    double delta = 2.0*osg::PI/double(slices-1);
359
360    if (_quadricState._normals!=GLU_NONE) Normal3f(0.0f,0.0f,1.0f);
361
362    switch(_quadricState._drawStyle)
363    {
364        case(GLU_POINT):
365        {
366            Begin(GL_POINTS);
367            if (_quadricState._texture) TexCoord2f(0.5f,0.5f);
368            Vertex3f(0.0f, 0.0f, 0.0f);
369            for(GLint i=0; i<slices; ++i, angle += delta)
370            {
371                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
372                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
373            }
374            End();
375            break;
376        }
377        case(GLU_LINE):
378        {
379            Begin(GL_LINE_LOOP);
380            for(GLint i=0; i<slices; ++i, angle += delta)
381            {
382                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
383                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
384            }
385            End();
386            break;
387        }
388        case(GLU_FILL):
389        {
390            Begin(GL_TRIANGLE_FAN);
391            if (_quadricState._texture) TexCoord2f(0.5f,0.5f);
392            Vertex3f(0.0f, 0.0f, 0.0f);
393            for(GLint i=0; i<slices; ++i, angle += delta)
394            {
395                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
396                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
397            }
398            End();
399            break;
400        }
401        case(GLU_SILHOUETTE):
402        {
403            Begin(GL_LINE_LOOP);
404            for(GLint i=0; i<slices; ++i, angle += delta)
405            {
406                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
407                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
408            }
409            End();
410            break;
411        }
412    }
413}
414
415void SceneGraphBuilder::PartialDisk(GLfloat        inner,
416                                    GLfloat        outer,
417                                    GLint          slices,
418                                    GLint          loops,
419                                    GLfloat        start,
420                                    GLfloat        sweep)
421{
422    OSG_NOTICE<<"SceneGraphBuilder::PartialDisk("<<inner<<", "<<outer<<", "<<slices<<", "<<loops<<", "<<start<<", "<<sweep<<") not implemented yet."<<std::endl;
423    OSG_NOTICE<<"   quadric("<<_quadricState._drawStyle<<", "<<_quadricState._normals<<", "<<_quadricState._orientation<<", "<<_quadricState._texture<<std::endl;
424}
425
426void SceneGraphBuilder::Sphere(GLfloat        radius,
427                               GLint          /*slices*/,
428                               GLint          /*stacks*/)
429{
430    addShape(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f), radius));
431}
432
433
434///////////////////////////////////////////////////////////////////////////////////////////
435//
436//  General scene graph building methods
437//
438
439osg::Node* SceneGraphBuilder::getScene()
440{
441    if (_group.valid() && _group->getNumChildren()>0) return _group.get();
442    else if (_transform.valid() && _transform->getNumChildren()>0) return _transform.get();
443    else if (_geode.valid() && _geode->getNumDrawables()>0) return _geode.get();
444
445    return 0;
446}
447
448osg::Node* SceneGraphBuilder::takeScene()
449{
450    osg::ref_ptr<osg::Node> node;
451
452    if (_group.valid() && _group->getNumChildren()>0) node = _group.get();
453    else if (_transform.valid() && _transform->getNumChildren()>0) node = _transform.get();
454    else if (_geode.valid() && _geode->getNumDrawables()>0) node = _geode.get();
455
456    // reset all the pointers to properly release the scene graph
457    _geometry = 0;
458    _geode = 0;
459    _transform = 0;
460    _group = 0;
461
462    return node.release();
463}
464
465void SceneGraphBuilder::matrixChanged()
466{
467}
468
469void SceneGraphBuilder::addAttribute(osg::StateAttribute* attribute)
470{
471    allocateStateSet();
472    _stateset->setAttribute(attribute);
473}
474
475void SceneGraphBuilder::addMode(GLenum mode, bool enabled)
476{
477    allocateStateSet();
478    _stateset->setMode(mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
479}
480
481
482void SceneGraphBuilder::addTextureAttribute(unsigned int unit, osg::StateAttribute* attribute)
483{
484    allocateStateSet();
485    _stateset->setTextureAttribute(unit, attribute);
486}
487
488void SceneGraphBuilder::addTextureMode(unsigned int unit, GLenum mode, bool enabled)
489{
490    allocateStateSet();
491    _stateset->setTextureMode(unit, mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
492}
493
494void SceneGraphBuilder::addShape(osg::Shape* shape)
495{
496    osg::ShapeDrawable* sd = new osg::ShapeDrawable(shape);
497    sd->setColor(_color);
498
499    addDrawable(sd);
500}
501
502void SceneGraphBuilder::addDrawable(osg::Drawable* drawable)
503{
504    if (!_geode) _geode = new osg::Geode;
505
506    if (_stateset.valid())
507    {
508        drawable->setStateSet(_stateset.get());
509        _statesetAssigned = true;
510    }
511
512    _geode->addDrawable(drawable);
513}
514
515void SceneGraphBuilder::allocateStateSet()
516{
517    if (_statesetAssigned)
518    {
519        _stateset = dynamic_cast<osg::StateSet*>(_stateset->clone(osg::CopyOp::SHALLOW_COPY));
520        _statesetAssigned = false;
521    }
522
523    if (!_stateset) _stateset = new osg::StateSet;
524}
525
526void SceneGraphBuilder::allocateGeometry()
527{
528    if (!_geometry)
529    {
530        _geometry = new osg::Geometry;
531    }
532}
533
534void SceneGraphBuilder::completeGeometry()
535{
536    if (_geometry.valid()) addDrawable(_geometry.get());
537    _geometry = 0;
538}
Note: See TracBrowser for help on using the browser.