root/OpenSceneGraph/trunk/src/osgPlugins/normals/Normals.cpp @ 13502

Revision 13502, 8.6 kB (checked in by robert, 4 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#include "Normals.h"
2
3using namespace osg;
4
5Normals::Normals( Node *node, float scale, Mode mode )
6{
7    setName(mode == VertexNormals ? "VertexNormals" : "SurfaceNormals");
8
9    MakeNormalsVisitor mnv(scale,mode);
10    node->accept( mnv );
11
12    ref_ptr<Vec3Array> coords = mnv.getCoords();
13    ref_ptr<Vec4Array> colors = new Vec4Array;
14    if( mode == SurfaceNormals )
15        colors->push_back( Vec4( 0, 1, 0, 1 ));
16    else if( mode == VertexNormals )
17        colors->push_back( Vec4( 1, 0, 0, 1 ));
18
19    ref_ptr<Geometry> geom = new Geometry;
20    geom->setVertexArray( coords.get() );
21    geom->setColorArray( colors.get() );
22    geom->setColorBinding( Geometry::BIND_OVERALL );
23
24    geom->addPrimitiveSet( new DrawArrays( PrimitiveSet::LINES, 0, coords->size()));
25
26    StateSet *sset = new StateSet;
27    sset->setMode( GL_LIGHTING,   StateAttribute::OFF);
28    geom->setStateSet( sset );
29    addDrawable( geom.get() );
30}
31
32
33
34Normals::MakeNormalsVisitor::MakeNormalsVisitor( float normalScale, Mode mode):
35            NodeVisitor(NodeVisitor::TRAVERSE_ALL_CHILDREN),
36            _normal_scale(normalScale),
37            _mode(mode)
38{
39    _local_coords = new Vec3Array;
40    _mat = osg::Matrix::identity();
41}
42
43
44void Normals::MakeNormalsVisitor::apply(osg::MatrixTransform& tx)
45{
46    _matStack.push( _mat );
47    _mat = _mat * tx.getMatrix();
48
49    traverse( tx );
50
51    _mat = _matStack.top();
52    _matStack.pop();
53}
54
55void Normals::MakeNormalsVisitor::apply( Geode &geode )
56{
57    for( unsigned int i = 0; i < geode.getNumDrawables(); i++ )
58    {
59        Geometry *geom = dynamic_cast<Geometry *>(geode.getDrawable(i));
60        if( geom )
61        {
62            if (geom->containsDeprecatedData()) geom->fixDeprecatedData();
63           
64            Vec3Array *coords   = dynamic_cast<Vec3Array*>(geom->getVertexArray());
65            if( coords == 0L )
66                continue;
67
68            Vec3Array *normals  = dynamic_cast<Vec3Array*>(geom->getNormalArray());
69            if( normals == 0L )
70                continue;
71
72            Geometry::AttributeBinding binding = geom->getNormalBinding();
73            if( binding == Geometry::BIND_OFF )
74                continue;
75
76            if( binding == Geometry::BIND_OVERALL )
77            {
78                Vec3 v(0,0,0);
79                Vec3 n = normals->front();
80
81                Vec3Array::iterator coord_index = coords->begin();
82                while( coord_index != coords->end() )
83                  v += *(coord_index++) * _mat;
84                v /= (float)(coords->size());
85
86                n *= _normal_scale;
87                _local_coords->push_back( v );
88                _local_coords->push_back( (v + n));
89            }
90            else // BIND_PER_PRIMITIVE_SET, BIND_PER_VERTEX
91            {
92                Geometry::PrimitiveSetList& primitiveSets = geom->getPrimitiveSetList();
93                Geometry::PrimitiveSetList::iterator itr;
94
95                Vec3Array::iterator coord_index   = coords->begin();
96                Vec3Array::iterator normals_index = normals->begin();
97
98                for(itr=primitiveSets.begin(); itr!=primitiveSets.end(); ++itr)
99                {
100#ifdef DEBUG
101                    _printPrimitiveType( (*itr).get() );
102#endif
103                    if( binding == Geometry::BIND_PER_PRIMITIVE_SET )
104                    {
105                        Vec3 v(0,0,0);
106                        Vec3 n = *(normals_index++);
107                        int ni = (*itr)->getNumIndices();
108                        for( int i = 0; i < ni; i++ )
109                            v += *(coord_index++) * _mat;
110                        v /= (float)(ni);
111
112                        n *= _normal_scale;
113                        _local_coords->push_back( v );
114                        _local_coords->push_back( (v + n));
115                    }
116                    else
117                    {
118                        switch((*itr)->getMode())
119                        {
120                            case(PrimitiveSet::TRIANGLES):
121                            {
122                                for( unsigned int j = 0; j < (*itr)->getNumPrimitives(); j++ )
123                                {
124                                    _processPrimitive( 3, coord_index, normals_index, binding );
125                                    coord_index += 3;
126                                    normals_index+=3;
127                                }
128                                break;
129                            }
130                            case(PrimitiveSet::TRIANGLE_STRIP):
131                            {
132                                for( unsigned int j = 0; j < (*itr)->getNumIndices()-2; j++ )
133                                {
134                                    _processPrimitive( 3, coord_index, normals_index, binding );
135                                    coord_index++;
136                                    normals_index++;
137                                }
138                                coord_index += 2;
139                                if( binding == Geometry::BIND_PER_VERTEX )
140                                    normals_index += 2;
141                                break;
142                            }
143                            case(PrimitiveSet::TRIANGLE_FAN):
144                                break;
145
146                            case(PrimitiveSet::QUADS):
147                            {
148                                for( unsigned int j = 0; j < (*itr)->getNumPrimitives(); j++ )
149                                {
150                                    _processPrimitive( 4, coord_index, normals_index, binding );
151                                    coord_index += 4;
152                                    normals_index +=4;
153                                }
154                                break;
155                            }
156                            case(PrimitiveSet::QUAD_STRIP):
157                                break;
158
159                            case(PrimitiveSet::POLYGON):
160                            {
161                                DrawArrayLengths* dal = dynamic_cast<DrawArrayLengths*>((*itr).get());
162                                if (dal) {
163                                    for (unsigned int j = 0; j < dal->size(); ++j) {
164                                        unsigned int num_prim = (*dal)[j];
165                                        //OSG_WARN << "j=" << j << " num_prim=" << num_prim << std::endl;
166                                        _processPrimitive(num_prim, coord_index, normals_index, binding);
167                                        coord_index += num_prim;
168                                        normals_index += num_prim;
169                                    }
170                                }
171                                break;
172                            }
173
174                            default:
175                                break;
176                        }
177                    }
178                }
179            }
180        }
181    }
182    traverse( geode );
183}
184
185
186void Normals::MakeNormalsVisitor::_processPrimitiveunsigned int nv,
187                        Vec3Array::iterator coords,
188                        Vec3Array::iterator normals,
189                        Geometry::AttributeBinding binding )
190{
191    Vec3 v(0,0,0);
192    Vec3 n(0,0,0);
193    if( _mode == SurfaceNormals )
194    {
195        if( binding == Geometry::BIND_PER_VERTEX )
196        {
197            for( unsigned int i = 0; i < nv; i++ )
198                n += *(normals++);
199            n /= (float)(nv);
200        }
201
202        for( unsigned int i = 0; i < nv; i++ )
203            v += *(coords++) * _mat;
204        v /= (float)(nv);
205
206        n *= _normal_scale;
207        _local_coords->push_back( v );
208        _local_coords->push_back( (v + n));
209    }
210    else if( _mode == VertexNormals )
211    {
212        for( unsigned int i = 0; i < nv; i++ )
213        {
214            v = *(coords++) * _mat;
215            n = *(normals++);
216            n *= _normal_scale;
217            _local_coords->push_back( v );
218            _local_coords->push_back( (v + n));
219        }
220    }
221}
222
223#ifdef DEBUG
224void Normals::_printPrimitiveType( osg::PrimitiveSet *pset )
225{
226    std::cout << (
227            pset->getMode() == PrimitiveSet::POINTS ? "POINTS" :
228            pset->getMode() == PrimitiveSet::LINES ? "LINES" :
229            pset->getMode() == PrimitiveSet::LINE_STRIP ? "LINE_STRIP" :
230            pset->getMode() == PrimitiveSet::LINE_LOOP ? "LINE_LOOP" :
231            pset->getMode() == PrimitiveSet::TRIANGLES ? "TRIANGLES" :
232            pset->getMode() == PrimitiveSet::TRIANGLE_STRIP ? "TRIANGLE_STRIP" :
233            pset->getMode() == PrimitiveSet::TRIANGLE_FAN ? "TRIANGLE_FAN" :
234            pset->getMode() == PrimitiveSet::QUADS ? "QUADS" :
235            pset->getMode() == PrimitiveSet::QUAD_STRIP ? "QUAD_STRIP" :
236            pset->getMode() == PrimitiveSet::POLYGON ? "POLYGON" : "Dunno" )  << std::endl;
237}
238#endif
Note: See TracBrowser for help on using the browser.