OpenWalnut  1.5.0dev
WGEUtils.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <vector>
27 
28 #include <osg/Array>
29 #include <osg/MatrixTransform>
30 
31 #include "../common/math/linearAlgebra/WPosition.h"
32 #include "core/common/WLogger.h"
33 
34 #include "WGETexture.h"
35 #include "shaders/WGEShader.h"
36 #include "WGEGeodeUtils.h"
37 
38 #include "WGEUtils.h"
39 
40 osg::ref_ptr< osg::Vec3Array > wge::osgVec3Array( const std::vector< WPosition >& posArray )
41 {
42  osg::ref_ptr< osg::Vec3Array > result = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
43  result->reserve( posArray.size() );
44  std::vector< WPosition >::const_iterator cit;
45  for( cit = posArray.begin(); cit != posArray.end(); ++cit )
46  {
47  result->push_back( *cit );
48  }
49  return result;
50 }
51 
52 osg::Vec3 wge::unprojectFromScreen( const osg::Vec3 screen, osg::ref_ptr< WGECamera > camera )
53 {
54  return screen * osg::Matrix::inverse( camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix() );
55 }
56 
57 osg::Vec4 wge::unprojectFromScreen( const osg::Vec4 screen, osg::ref_ptr< WGECamera > camera )
58 {
59  return screen * osg::Matrix::inverse( camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix() );
60 }
61 
62 WColor wge::createColorFromIndex( int index )
63 {
64  float r = 0.0;
65  float g = 0.0;
66  float b = 0.0;
67  float mult = 1.0;
68 
69  if( index == 0 )
70  {
71  return WColor( 0.0, 0.0, 0.0, 1.0 );
72  }
73 
74  if( ( index & 1 ) == 1 )
75  {
76  b = 1.0;
77  }
78  if( ( index & 2 ) == 2 )
79  {
80  g = 1.0;
81  }
82  if( ( index & 4 ) == 4 )
83  {
84  r = 1.0;
85  }
86  if( ( index & 8 ) == 8 )
87  {
88  mult -= 0.15;
89  if( r < 1.0 && g < 1.0 && b < 1.0 )
90  {
91  r = 1.0;
92  g = 1.0;
93  }
94  }
95  if( ( index & 16 ) == 16 )
96  {
97  mult -= 0.15;
98  if( r < 1.0 && g < 1.0 && b < 1.0 )
99  {
100  b = 1.0;
101  g = 1.0;
102  }
103  }
104  if( ( index & 32 ) == 32 )
105  {
106  mult -= 0.15;
107  if( r < 1.0 && g < 1.0 && b < 1.0 )
108  {
109  r = 1.0;
110  b = 1.0;
111  }
112  }
113  if( ( index & 64 ) == 64 )
114  {
115  mult -= 0.15;
116  if( r < 1.0 && g < 1.0 && b < 1.0 )
117  {
118  g = 1.0;
119  }
120  }
121  if( ( index & 128 ) == 128 )
122  {
123  mult -= 0.15;
124  if( r < 1.0 && g < 1.0 && b < 1.0 )
125  {
126  r = 1.0;
127  }
128  }
129  r *= mult;
130  g *= mult;
131  b *= mult;
132 
133  return WColor( r, g, b, 1.0 );
134 }
135 
136 WColor wge::createColorFromHSV( int h, float s, float v )
137 {
138  h = h % 360;
139 
140  int hi = h / 60;
141  float f = ( static_cast<float>( h ) / 60.0 ) - hi;
142 
143  float p = v * ( 1.0 - s );
144  float q = v * ( 1.0 - s * f );
145  float t = v * ( 1.0 - s * ( 1.0 - f ) );
146 
147  switch( hi )
148  {
149  case 0:
150  return WColor( v, t, p, 1.0 );
151  case 1:
152  return WColor( q, v, p, 1.0 );
153  case 2:
154  return WColor( p, v, t, 1.0 );
155  case 3:
156  return WColor( p, q, v, 1.0 );
157  case 4:
158  return WColor( t, p, v, 1.0 );
159  case 5:
160  return WColor( v, p, q, 1.0 );
161  case 6:
162  return WColor( v, t, p, 1.0 );
163  default:
164  return WColor( v, t, p, 1.0 );
165  }
166 }
167 
168 WColor wge::getNthHSVColor( int n )
169 {
170  int h = 0;
171  float s = 1.0;
172  float v = 1.0;
173 
174  if( ( n & 1 ) == 1 )
175  {
176  h += 180;
177  }
178  if( ( n & 2 ) == 2 )
179  {
180  h += 90;
181  }
182  if( ( n & 4 ) == 4 )
183  {
184  h += 45;
185  }
186  if( ( n & 8 ) == 8 )
187  {
188  h += 202;
189  h = h % 360;
190  }
191  if( ( n & 16 ) == 16 )
192  {
193  v -= .25;
194  }
195  if( ( n & 32 ) == 32 )
196  {
197  s -= .25;
198  }
199  if( ( n & 64 ) == 64 )
200  {
201  v -= .25;
202  }
203  if( ( n & 128 ) == 128 )
204  {
205  s -= 0.25;
206  }
207  if( ( n & 256 ) == 256 )
208  {
209  v -= 0.25;
210  }
211 
212  return createColorFromHSV( h, s, v );
213 }
214 
215 void wge::enableTransparency( osg::ref_ptr< osg::Node > node )
216 {
217  osg::StateSet* state = node->getOrCreateStateSet();
218 
219  // NOTE: this does not en/disable blending. This is always on.
220  state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
221 
222  // Enable depth test so that an opaque polygon will occlude a transparent one behind it.
223  state->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON );
224 
225  // Conversely, disable writing to depth buffer so that a transparent polygon will allow polygons behind it to shine through.
226  // OSG renders transparent polygons after opaque ones.
227  // NOTE: USEFUL?
228  // osg::Depth* depth = new osg::Depth;
229  // depth->setWriteMask( false );
230  // state->setAttributeAndModes( depth, osg::StateAttribute::ON );
231 
232  // blending. Without this, setting alpha does not cause anything
233  state->setMode( GL_BLEND, osg::StateAttribute::ON );
234 }
235 
236 osg::ref_ptr< osg::Node > wge::generateCullProxy( const WBoundingBox& bbox )
237 {
238  // Create some cube. Color is uninteresting.
239  osg::ref_ptr< osg::Node > cullProxy = wge::generateSolidBoundingBoxNode( bbox, defaultColor::WHITE );
240 
241  // Avoid picking the proxy
242  cullProxy->asTransform()->getChild( 0 )->setName( "_Cull Proxy Cube" ); // Be aware that this name is used in the pick handler.
243  // because of the underscore in front it won't be picked
244 
245  // Add a shader which visually removes the proxy cube.
246  osg::ref_ptr< WGEShader > cullProxyShader = new WGEShader( "WGECullProxyShader" );
247  cullProxyShader->apply( cullProxy );
248 
249  return cullProxy;
250 }
251 
252 /**
253  * Update matrix transform according to bounds of some node
254  */
255 class BoundsCallback: public osg::NodeCallback
256 {
257 public:
258  /**
259  * Create and init.
260  *
261  * \param node the node
262  */
263  explicit BoundsCallback( osg::ref_ptr< osg::Node > node ):
264  m_node( node )
265  {
266  }
267 
268  /**
269  * Callback method called by the NodeVisitor when visiting a node
270  *
271  * \param node the node handled
272  * \param nv the visitor
273  */
274  virtual void operator()( osg::Node* node, osg::NodeVisitor* nv )
275  {
276  osg::MatrixTransform* m = static_cast< osg::MatrixTransform* >( node );
277 
278  osg::BoundingSphere s = m_node->getBound();
279 
280  // this will not be the bounding box which is embedded into the sphere as we do not know how the sphere was calculated. Create a BBox
281  // around the sphere.
282  osg::Matrix matrix = osg::Matrix::scale( osg::Vec3d( s.radius(), s.radius(), s.radius() ) ) * osg::Matrix::translate( s.center() );
283 
284  m->setMatrix( matrix );
285 
286  traverse( node, nv );
287  }
288 private:
289  /**
290  * The node to use as template for the resulting bbox
291  */
292  osg::ref_ptr< osg::Node > m_node;
293 };
294 
295 osg::ref_ptr< osg::Node > wge::generateDynamicCullProxy( osg::ref_ptr< osg::Node > node )
296 {
297  // create a unit size proxy cube
298  osg::ref_ptr< osg::Node > proxyUnitCube = generateCullProxy(
299  WBoundingBox( WBoundingBox::vec_type( -1.0, -1.0, -1.0 ), WBoundingBox::vec_type( 1.0, 1.0, 1.0 ) )
300  );
301 
302  // setComputeBoundingSphereCallback does not work -> we need a transform node which scales the cube using an update callback
303  osg::ref_ptr< osg::MatrixTransform > mt( new osg::MatrixTransform() );
304 
305  mt->setUpdateCallback( new BoundsCallback( node ) );
306  mt->addChild( proxyUnitCube );
307 
308  return mt;
309 }
310 
Update matrix transform according to bounds of some node.
Definition: WGEUtils.cpp:256
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)
Callback method called by the NodeVisitor when visiting a node.
Definition: WGEUtils.cpp:274
BoundsCallback(osg::ref_ptr< osg::Node > node)
Create and init.
Definition: WGEUtils.cpp:263
osg::ref_ptr< osg::Node > m_node
The node to use as template for the resulting bbox.
Definition: WGEUtils.cpp:292
osg::BoundingBoxImpl< osg::Vec3 >::vec_type vec_type
Vertex type for min and max positions of this box.
Definition: WBoundingBox.h:53
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
Definition: WGEShader.h:48
WColor getNthHSVColor(int n)
creates the nth color of a partition of the hsv color circle
Definition: WGEUtils.cpp:168
void enableTransparency(osg::ref_ptr< osg::Node > node)
Enable transparency for the given node.
Definition: WGEUtils.cpp:215
WColor createColorFromHSV(int h, float s=1.0, float v=1.0)
creates a rgb WColor from a HSV value
Definition: WGEUtils.cpp:136
osg::ref_ptr< osg::Node > generateCullProxy(const WBoundingBox &bbox)
Generate a proxy cube, which ensures OSG does proper near-far plane calculation and culling.
Definition: WGEUtils.cpp:236
osg::Vec3 unprojectFromScreen(const osg::Vec3 screen, osg::ref_ptr< WGECamera > camera)
Converts screen coordinates into Camera coordinates.
Definition: WGEUtils.cpp:52
osg::ref_ptr< osg::Node > generateSolidBoundingBoxNode(const WBoundingBox &bb, const WColor &color, bool threeDTexCoords=true)
Generates an OSG node for the specified bounding box.
WColor createColorFromIndex(int index)
creates the same color as the atlas colormap shader from the index
Definition: WGEUtils.cpp:62
osg::ref_ptr< osg::Node > generateDynamicCullProxy(osg::ref_ptr< osg::Node > node)
Generate a proxy cube, which ensures OSG does proper near-far plane calculation and culling.
Definition: WGEUtils.cpp:295
osg::ref_ptr< osg::Vec3Array > osgVec3Array(const std::vector< WPosition > &posArray)
Converts a whole vector of WPositions into an osg::Vec3Array.
Definition: WGEUtils.cpp:40