Moby
Color.h
1 /****************************************************************************
2  * Copyright 2014 Evan Drumwright
3  * This library is distributed under the terms of the Apache V2.0
4  * License (obtainable from http://www.apache.org/licenses/LICENSE-2.0).
5  ****************************************************************************/
6 
7 
8 #include <osg/Array>
9 #include <osg/Geode>
10 #include <osg/Geometry>
11 #include <osg/NodeVisitor>
12 #include <osg/Vec4>
13 #include <osg/ShapeDrawable>
14 #include <osg/Texture2D>
15 
16 namespace Moby {
18 
24 class CcolorVisitor : public osg::NodeVisitor {
25 
26 public :
27 
28 
29 
30  CcolorVisitor() : NodeVisitor( NodeVisitor::TRAVERSE_ALL_CHILDREN ) {
31  // ---------------------------------------------------------------
32  //
33  // Default Ctors overide the default node visitor mode so all
34  // children are visited
35  //
36  // ---------------------------------------------------------------
37 
38  //
39  // Default to a white color
40  //
41  m_color.set( 1.0, 1.0, 1.0, 1.0 );
42 
43  m_colorArrays = new osg::Vec4Array;
44 
45  m_colorArrays->push_back( m_color );
46 
47  };
48 
49 
50  CcolorVisitor( const osg::Vec4 &color ) : NodeVisitor( NodeVisitor::TRAVERSE_ALL_CHILDREN ) {
51  // -------------------------------------------------------------------
52  //
53  // Overloaded Ctor initialised with the Color
54  // Also override the visitor to traverse all the nodes children
55  //
56  // -------------------------------------------------------------------
57 
58  m_color = m_color;
59 
60  m_colorArrays = new osg::Vec4Array;
61 
62  m_colorArrays->push_back( m_color );
63 
64 
65  };
66 
67 
68 
69  virtual ~CcolorVisitor(){};
70 
71 
72  virtual
73  void apply ( osg::Node &node ){
74  // --------------------------------------------
75  //
76  // Handle traversal of osg::Node node types
77  //
78  // --------------------------------------------
79 
80  traverse( node );
81 
82  } // apply( osg::Node &node )
83 
84 
85  virtual
86  void apply( osg::Geode &geode ){
87  // ------------------------------------------------
88  //
89  // Handle traversal of osg::Geode node types
90  //
91  // ------------------------------------------------
92  osg::StateSet *state = NULL;
93  unsigned int vertNum = 0;
94 
95  //
96  // We need to iterate through all the drawables check if
97  // the contain any geometry that we will need to process
98  //
99  unsigned int numGeoms = geode.getNumDrawables();
100 
101 
102  for( unsigned int geodeIdx = 0; geodeIdx < numGeoms; geodeIdx++ ) {
103 
104  //
105  // Use 'asGeometry' as its supposed to be faster than a dynamic_cast
106  // every little saving counts
107  //
108  osg::Geometry *curGeom = geode.getDrawable( geodeIdx )->asGeometry();
109 
110 
111  //
112  // Only process if the drawable is geometry
113  //
114  if ( curGeom ) {
115  osg::Vec4Array *colorArrays = dynamic_cast< osg::Vec4Array *>(curGeom->getColorArray());
116 
117  if ( colorArrays ) {
118  for ( unsigned int i = 0; i < colorArrays->size(); i++ ) {
119 
120  osg::Vec4 *color = &colorArrays->operator [](i);
121 
122  //
123  // could also use *color = m_color
124  //
125  color->normalize();
126  color->set( color->_v[0]*m_color._v[0], color->_v[0]*m_color._v[1], color->_v[0]*m_color._v[2], color->_v[3]*m_color._v[3]);
127 
128  }
129  } else{
130  curGeom->setColorArray( m_colorArrays.get());
131  curGeom->setColorBinding( osg::Geometry::BIND_OVERALL );
132  }
133  } else {
134  // If Shape is not a geometry, it might be a shape, change shape color
135  osg::ShapeDrawable * sd = dynamic_cast<osg::ShapeDrawable*>(geode.getDrawable( geodeIdx ));
136  if(sd){
137  if(m_color._v[3] == 0.0){
138  int s = 64;
139  unsigned char* pData = new unsigned char[s*s*3];
140  for ( int y=0; y<s; y++ )
141  for ( int x=0; x<s; x++ )
142  {
143  unsigned char c = (( ((y&0x8)==0) ^ (((x&0x8))==0) ))*255;
144  if(c > 127.5){
145  pData[x*3+y*s*3+0] = 255;
146  pData[x*3+y*s*3+1] = 255;
147  pData[x*3+y*s*3+2] = 255;
148  }else{
149  pData[x*3+y*s*3+0] = 255*m_color._v[0];
150  pData[x*3+y*s*3+1] = 255*m_color._v[1];
151  pData[x*3+y*s*3+2] = 255*m_color._v[2];
152  }
153  }
154 
155  osg::Image* pImage = new osg::Image;
156  pImage->setImage(
157  s, s, 1, // 1=r? depth perhaps?
158  GL_RGB, // internal format
159  GL_RGB,GL_UNSIGNED_BYTE, // pixelformat, type
160  pData, // data
161  osg::Image::USE_NEW_DELETE, // mode
162  1 ); // packing
163 
164  osg::Texture2D* pTex = new osg::Texture2D;
165  pTex->setImage( pImage );
166 
167  osg::StateSet* pStateSet = geode.getOrCreateStateSet();
168  pStateSet->setTextureAttributeAndModes( 0, pTex, osg::StateAttribute::ON );
169  } else {
170  osg::StateSet* ss = sd->getStateSet();
171  if( ss == NULL ) {
172  ss = new osg::StateSet();
173  sd->setStateSet( ss );
174  ss->setMode( GL_BLEND, osg::StateAttribute::ON );
175  }
176  sd->setColor(osg::Vec4(m_color._v[0], m_color._v[1], m_color._v[2], m_color._v[3]));
177  }
178  }
179  }
180  }
181  } // apply( osg::Geode
182 
183 
184  void
185  setColor( const float r, const float g, const float b, const float a = 1.0f ){
186  // -------------------------------------------------------------------
187  //
188  // Set the color to change apply to the nodes geometry
189  //
190  // -------------------------------------------------------------------
191 
192  osg::Vec4 *c = &m_colorArrays->operator []( 0 );
193 
194  m_color.set( r,g,b,a );
195 
196  *c = m_color;
197 
198 
199  } // setColor( r,g,b,a )
200 
201 
202  void
203  setColor( const osg::Vec4 &color ){
204  // -------------------------------------------------------------------
205  //
206  // Set the color to change apply to the nodes geometry
207  //
208  // -------------------------------------------------------------------
209 
210  osg::Vec4 *c = &m_colorArrays->operator []( 0 );
211 
212  m_color = color;
213 
214  *c = m_color;
215 
216 
217  } // setColor( vec4 )
218 
219 
220 
221 
222 
223 private :
224 
225 
226  osg::Vec4 m_color;
227  osg::ref_ptr< osg::Vec4Array > m_colorArrays;
228 
229 
230  }; // class CcolorVisitor
231 }
This OSG NodeVisitor colors all Geometry & ShapeDrawable of a single node.
Definition: Color.h:24