OpenWalnut  1.4.0
WGEGeodeUtils.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 <map>
26 #include <string>
27 #include <vector>
28 
29 #include <osg/Array>
30 #include <osg/Geode>
31 #include <osg/Geometry>
32 #include <osg/LightModel>
33 #include <osg/LineWidth>
34 #include <osg/Material>
35 #include <osg/MatrixTransform>
36 #include <osg/ShapeDrawable>
37 #include <osg/Vec3>
38 
39 #include "../common/math/WMath.h"
40 #include "../common/WPathHelper.h"
41 #include "../common/WStringUtils.h"
42 
43 #include "shaders/WGEShader.h"
44 #include "WGEGeodeUtils.h"
45 #include "WGEGeometryUtils.h"
46 #include "WGEGroupNode.h"
47 #include "WGESubdividedPlane.h"
48 #include "WGEUtils.h"
49 #include "widgets/labeling/WGELabel.h"
50 
51 osg::ref_ptr< osg::Geode > wge::generateBoundingBoxGeode( const WBoundingBox& bb, const WColor& color )
52 {
53  const WBoundingBox::vec_type& pos1 = bb.getMin();
54  const WBoundingBox::vec_type& pos2 = bb.getMax();
55 
56  WAssert( pos1[0] <= pos2[0] && pos1[1] <= pos2[1] && pos1[2] <= pos2[2], "pos1 does not seem to be the frontLowerLeft corner of the BB!" );
57  using osg::ref_ptr;
58  ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
59  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
60  ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
61 
62  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) );
63  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) );
64  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) );
65  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) );
66  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) );
67  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) );
68  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) );
69  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) );
70  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) );
71  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) );
72 
73  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) );
74 
75  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) );
76  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) );
77  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) );
78  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) );
79  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) );
80  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) );
81 
82  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) );
83 
84  geometry->setVertexArray( vertices );
85  colors->push_back( color );
86  geometry->setColorArray( colors );
87  geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
88  osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
89  geode->addDrawable( geometry );
90 
91  // disable light for this geode as lines can't be lit properly
92  osg::StateSet* state = geode->getOrCreateStateSet();
93  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
94 
95  return geode;
96 }
97 
98 void wge::createCube( osg::ref_ptr< osg::Geometry > geometry, const WPosition& position, const WPosition& size, const WColor& color )
99 {
100  // the geometry might be empty: ensure we have arrays properly set. If they cannot be casted, they get overwritten later. Users own fault if
101  // he does not read the doc
102  osg::ref_ptr< osg::Vec3Array > vertices = dynamic_cast< osg::Vec3Array* >( geometry->getVertexArray() );
103  osg::ref_ptr< osg::Vec3Array > tex = dynamic_cast< osg::Vec3Array* >( geometry->getTexCoordArray( 0 ) );
104  osg::ref_ptr< osg::Vec3Array > normals = dynamic_cast< osg::Vec3Array* >( geometry->getNormalArray() );
105  osg::ref_ptr< osg::Vec4Array > colors = dynamic_cast< osg::Vec4Array* >( geometry->getColorArray() );
106 
107  // get some mem if not already done
108  if( !vertices )
109  {
110  vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
111  }
112  if( !tex )
113  {
114  tex = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
115  }
116  if( !normals )
117  {
118  normals = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
119  }
120  if( !colors )
121  {
122  colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
123  }
124 
125  size_t first = vertices->getNumElements();
126 
127  // NOTE: as the OSG 3.2 does not allow binding normals/colors and other arrays on a per-primitive basis, we bind the normals per vertex
128  // This means we add four normals per face
129 
130  // front face
131  vertices->push_back( position + WPosition( 0.0, 0.0, 0.0 ) );
132  vertices->push_back( position + WPosition( size.x(), 0.0, 0.0 ) );
133  vertices->push_back( position + WPosition( size.x(), size.y(), 0.0 ) );
134  vertices->push_back( position + WPosition( 0.0, size.y(), 0.0 ) );
135  tex->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
136  tex->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
137  tex->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
138  tex->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
139  normals->push_back( osg::Vec3( 0.0, 0.0, -1.0 ) );
140  normals->push_back( osg::Vec3( 0.0, 0.0, -1.0 ) );
141  normals->push_back( osg::Vec3( 0.0, 0.0, -1.0 ) );
142  normals->push_back( osg::Vec3( 0.0, 0.0, -1.0 ) );
143 
144  // back face
145  vertices->push_back( position + WPosition( 0.0, 0.0, size.z() ) );
146  vertices->push_back( position + WPosition( size.x(), 0.0, size.z() ) );
147  vertices->push_back( position + WPosition( size.x(), size.y(), size.z() ) );
148  vertices->push_back( position + WPosition( 0.0, size.y(), size.z() ) );
149  tex->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
150  tex->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
151  tex->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
152  tex->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
153  normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
154  normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
155  normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
156  normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
157 
158  // left
159  vertices->push_back( position + WPosition( 0.0, 0.0, 0.0 ) );
160  vertices->push_back( position + WPosition( 0.0, size.y(), 0.0 ) );
161  vertices->push_back( position + WPosition( 0.0, size.y(), size.z() ) );
162  vertices->push_back( position + WPosition( 0.0, 0.0, size.z() ) );
163  tex->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
164  tex->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
165  tex->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
166  tex->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
167  normals->push_back( osg::Vec3( -1.0, 0.0, 0.0 ) );
168  normals->push_back( osg::Vec3( -1.0, 0.0, 0.0 ) );
169  normals->push_back( osg::Vec3( -1.0, 0.0, 0.0 ) );
170  normals->push_back( osg::Vec3( -1.0, 0.0, 0.0 ) );
171 
172  // right
173  vertices->push_back( position + WPosition( size.x(), 0.0, 0.0 ) );
174  vertices->push_back( position + WPosition( size.x(), size.y(), 0.0 ) );
175  vertices->push_back( position + WPosition( size.x(), size.y(), size.z() ) );
176  vertices->push_back( position + WPosition( size.x(), 0.0, size.z() ) );
177  tex->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
178  tex->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
179  tex->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
180  tex->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
181  normals->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
182  normals->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
183  normals->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
184  normals->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
185 
186  // bottom
187  vertices->push_back( position + WPosition( 0.0, 0.0, 0.0 ) );
188  vertices->push_back( position + WPosition( size.x(), 0.0, 0.0 ) );
189  vertices->push_back( position + WPosition( size.x(), 0.0, size.z() ) );
190  vertices->push_back( position + WPosition( 0.0, 0.0, size.z() ) );
191  tex->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
192  tex->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
193  tex->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
194  tex->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
195  normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) );
196  normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) );
197  normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) );
198  normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) );
199 
200  // top
201  vertices->push_back( position + WPosition( 0.0, size.y(), 0.0 ) );
202  vertices->push_back( position + WPosition( size.x(), size.y(), 0.0 ) );
203  vertices->push_back( position + WPosition( size.x(), size.y(), size.z() ) );
204  vertices->push_back( position + WPosition( 0.0, size.y(), size.z() ) );
205  tex->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
206  tex->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
207  tex->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
208  tex->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
209  normals->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
210  normals->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
211  normals->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
212  normals->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
213 
214  // set it up and set arrays
215  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, first, 6 * 4 ) ); // 6 faces, 4 vertices per face
216  geometry->setVertexArray( vertices );
217 
218  // set 3D texture coordinates here.
219  geometry->setTexCoordArray( 0, tex );
220 
221  // set normals
222  geometry->setNormalArray( normals );
223  geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
224 
225  // finally, the colors
226  colors->push_back( color );
227  geometry->setColorArray( colors );
228  geometry->setColorBinding( osg::Geometry::BIND_PER_PRIMITIVE_SET );
229 }
230 
231 osg::ref_ptr< osg::Geometry > wge::createCube( const WPosition& position, const WPosition& size, const WColor& color )
232 {
233  // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
234  osg::ref_ptr< osg::Geometry > cube = new osg::Geometry();
235  createCube( cube, position, size, color );
236  return cube;
237 }
238 
239 osg::ref_ptr< osg::Geometry > wge::createUnitCube( const WColor& color )
240 {
241  // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
242  return createCube( WPosition( 0.0, 0.0, 0.0 ), WPosition( 1.0, 1.0, 1.0 ), color );
243 }
244 
245 osg::ref_ptr< osg::Geometry > wge::createUnitCubeAsLines( const WColor& color )
246 {
247  // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
248  osg::ref_ptr< osg::Geometry > cube = new osg::Geometry();
249  osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
250  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
251 
252  vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
253  vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
254  vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
255  vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
256  vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
257  vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
258  vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
259  vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
260  vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
261  vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
262 
263  cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) );
264 
265  vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
266  vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
267  vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
268  vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
269  vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
270  vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
271 
272  cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) );
273 
274  // set it up and set arrays
275  cube->setVertexArray( vertices );
276 
277  // set 3D texture coordinates here.
278  cube->setTexCoordArray( 0, vertices );
279 
280  // finally, the colors
281  colors->push_back( color );
282  cube->setColorArray( colors );
283  cube->setColorBinding( osg::Geometry::BIND_OVERALL );
284 
285  return cube;
286 }
287 
288 osg::ref_ptr< osg::Node > wge::generateSolidBoundingBoxNode( const WBoundingBox& bb, const WColor& color, bool threeDTexCoords )
289 {
290  WAssert( bb.valid(), "Invalid bounding box!" );
291 
292  // create a uni cube
293  osg::ref_ptr< osg::Geode > cube = new osg::Geode();
294  cube->setName( "Solid Bounding Box" );
295  if( threeDTexCoords )
296  {
297  cube->addDrawable( createUnitCube( color ) );
298  }
299  else
300  {
301  osg::ref_ptr< osg::ShapeDrawable > cubeDrawable = new osg::ShapeDrawable( new osg::Box( osg::Vec3( 0.5, 0.5, 0.5 ), 1.0 ) );
302  cubeDrawable->setColor( color );
303  cube->addDrawable( cubeDrawable );
304  }
305 
306  // transform the cube to match the bbox
307  osg::Matrixd transformM;
308  osg::Matrixd scaleM;
309  transformM.makeTranslate( bb.getMin() );
310  scaleM.makeScale( bb.getMax() - bb.getMin() );
311 
312  // apply transformation to bbox
313  osg::ref_ptr< osg::MatrixTransform > transform = new osg::MatrixTransform();
314  transform->setMatrix( scaleM * transformM );
315  transform->addChild( cube );
316 
317  // we do not need light
318  osg::StateSet* state = cube->getOrCreateStateSet();
319  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
320 
321  return transform;
322 }
323 
324 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh,
325  const WColor& defaultColor,
326  bool includeNormals,
327  bool lighting,
328  bool useMeshColor )
329 {
330  osg::ref_ptr< osg::Geometry> geometry( new osg::Geometry );
331  geometry->setVertexArray( mesh->getVertexArray() );
332 
333  osg::DrawElementsUInt* surfaceElement;
334 
335  surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
336 
337  std::vector< size_t > tris = mesh->getTriangles();
338  surfaceElement->reserve( tris.size() );
339 
340  for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
341  {
342  surfaceElement->push_back( tris[vertId] );
343  }
344  geometry->addPrimitiveSet( surfaceElement );
345 
346  // add the mesh colors
347  if( mesh->getVertexColorArray() && useMeshColor )
348  {
349  geometry->setColorArray( mesh->getVertexColorArray() );
350  geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
351  }
352  else
353  {
354  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
355  colors->push_back( defaultColor );
356  geometry->setColorArray( colors );
357  geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
358  }
359 
360  // ------------------------------------------------
361  // normals
362  if( includeNormals )
363  {
364  geometry->setNormalArray( mesh->getVertexNormalArray() );
365  geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
366 
367  if( lighting )
368  {
369  // if normals are specified, we also setup a default lighting.
370  osg::StateSet* state = geometry->getOrCreateStateSet();
371  osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
372  lightModel->setTwoSided( true );
373  state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
374  state->setMode( GL_BLEND, osg::StateAttribute::ON );
375  {
376  osg::ref_ptr< osg::Material > material = new osg::Material();
377  material->setDiffuse( osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
378  material->setSpecular( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
379  material->setAmbient( osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) );
380  material->setEmission( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
381  material->setShininess( osg::Material::FRONT, 25.0 );
382  state->setAttribute( material );
383  }
384  }
385  }
386 
387  // enable VBO
388  geometry->setUseDisplayList( false );
389  geometry->setUseVertexBufferObjects( true );
390 
391  return geometry;
392 }
393 
394 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometryFlatShaded( WTriangleMesh::SPtr mesh,
395  const WColor& defaultColor,
396  bool includeNormals,
397  bool lighting,
398  bool useMeshColor )
399 {
400  osg::DrawElementsUInt* surfaceElement;
401  surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
402  std::vector< size_t > tris = mesh->getTriangles();
403 
404  osg::ref_ptr< osg::Geometry> geometry( new osg::Geometry );
405  osg::ref_ptr< osg::Vec3Array > oldVertexArray( mesh->getVertexArray() );
406  osg::ref_ptr< osg::Vec3Array > newVertexArray( new osg::Vec3Array );
407 
408  // Make separate vertices for all triangle corners
409  for( size_t index = 0; index < tris.size(); ++index )
410  {
411  newVertexArray->push_back( (*oldVertexArray)[tris[index]] );
412  surfaceElement->push_back( index );
413  }
414  geometry->setVertexArray( newVertexArray );
415  geometry->addPrimitiveSet( surfaceElement );
416 
417  // add the mesh colors
418  if( mesh->getVertexColorArray() && useMeshColor )
419  {
420  geometry->setColorArray( mesh->getVertexColorArray() );
421  geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
422  }
423  else
424  {
425  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
426  colors->push_back( defaultColor );
427  geometry->setColorArray( colors );
428  geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
429  }
430 
431  // ------------------------------------------------
432  // normals
433  if( includeNormals )
434  {
435  // Set all vertex normals to the normals of the corresponding
436  // triangles causing uniform shading in a triangle
437  osg::ref_ptr< osg::Vec3Array > oldTriNormals = mesh->getTriangleNormalArray( true );
438  osg::ref_ptr< osg::Vec3Array > newVertNormals( new osg::Vec3Array );
439  for( size_t index = 0; index < tris.size(); ++index )
440  {
441  newVertNormals->push_back( (*oldTriNormals)[index/3] );
442  }
443  geometry->setNormalArray( newVertNormals );
444  geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
445 
446  if( lighting )
447  {
448  // if normals are specified, we also setup a default lighting.
449  osg::StateSet* state = geometry->getOrCreateStateSet();
450  osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
451  lightModel->setTwoSided( true );
452  state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
453  state->setMode( GL_BLEND, osg::StateAttribute::ON );
454  {
455  osg::ref_ptr< osg::Material > material = new osg::Material();
456  material->setDiffuse( osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
457  material->setSpecular( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
458  material->setAmbient( osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) );
459  material->setEmission( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
460  material->setShininess( osg::Material::FRONT, 25.0 );
461  state->setAttribute( material );
462  }
463  }
464  }
465 
466  // enable VBO
467  geometry->setUseDisplayList( false );
468  geometry->setUseVertexBufferObjects( true );
469 
470  return geometry;
471 }
472 
473 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh,
474  const WColoredVertices& colorMap,
475  const WColor& defaultColor,
476  bool includeNormals, bool lighting )
477 {
478  osg::ref_ptr< osg::Geometry > geometry = convertToOsgGeometry( mesh, defaultColor, includeNormals, lighting, false );
479 
480  // ------------------------------------------------
481  // colors
482  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
483  for( size_t i = 0; i < mesh->vertSize(); ++i )
484  {
485  colors->push_back( defaultColor );
486  }
487  for( std::map< size_t, WColor >::const_iterator vc = colorMap.getData().begin(); vc != colorMap.getData().end(); ++vc )
488  {
489  // ATTENTION: the colormap might not be available and hence an old one, but the new mesh might have triggered the update
490  if( vc->first < colors->size() )
491  {
492  colors->at( vc->first ) = vc->second;
493  }
494  }
495 
496  geometry->setColorArray( colors );
497  geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
498 
499  return geometry;
500 }
501 
502 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometryLines( WTriangleMesh::SPtr mesh,
503  const WColor& defaultColor,
504  bool useMeshColor )
505 {
506  osg::ref_ptr< osg::Geometry > geometry( new osg::Geometry );
507  geometry->setVertexArray( mesh->getVertexArray() );
508 
509  osg::DrawElementsUInt* meshElement;
510 
511  meshElement = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
512 
513  std::vector< size_t > tris = mesh->getTriangles();
514  meshElement->reserve( tris.size() * 3 );
515 
516  for( unsigned int triId = 0; triId < tris.size() / 3.; ++triId )
517  {
518  for( size_t edgeId = 0; edgeId < 3; ++edgeId )
519  {
520  meshElement->push_back( tris[triId*3 + edgeId] );
521  meshElement->push_back( tris[triId*3 + ( edgeId + 1 ) % 3] );
522  }
523  }
524  geometry->addPrimitiveSet( meshElement );
525 
526  // add the mesh colors
527  if( mesh->getVertexColorArray() && useMeshColor )
528  {
529  geometry->setColorArray( mesh->getVertexColorArray() );
530  geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
531  }
532  else
533  {
534  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
535  colors->push_back( defaultColor );
536  geometry->setColorArray( colors );
537  geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
538  }
539 
540  osg::StateSet* stateset = geometry->getOrCreateStateSet();
541  stateset->setAttributeAndModes( new osg::LineWidth( 1 ), osg::StateAttribute::ON );
542  stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
543  stateset->setMode( GL_BLEND, osg::StateAttribute::ON );
544 
545  return geometry;
546 }
547 
548 osg::ref_ptr< osg::PositionAttitudeTransform > wge::addLabel( osg::Vec3 position, std::string text )
549 {
550  osg::ref_ptr< osgText::Text > label = osg::ref_ptr< osgText::Text >( new osgText::Text() );
551  osg::ref_ptr< osg::Geode > labelGeode = osg::ref_ptr< osg::Geode >( new osg::Geode() );
552 
553  labelGeode->addDrawable( label );
554 
555  // setup font
556  label->setFont( WPathHelper::getAllFonts().Default.string() );
557  label->setBackdropType( osgText::Text::OUTLINE );
558  label->setCharacterSize( 6 );
559 
560  label->setText( text );
561  label->setAxisAlignment( osgText::Text::SCREEN );
562  label->setDrawMode( osgText::Text::TEXT );
563  label->setAlignment( osgText::Text::CENTER_TOP );
564  label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) );
565  label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
566 
567  osg::ref_ptr< osg::PositionAttitudeTransform > labelXform =
568  osg::ref_ptr< osg::PositionAttitudeTransform >( new osg::PositionAttitudeTransform() );
569  labelXform->setPosition( position );
570 
571  labelXform->addChild( labelGeode );
572 
573  return labelXform;
574 }
575 
576 osg::ref_ptr< osg::PositionAttitudeTransform > wge::vector2label( osg::Vec3 position )
577 {
578  std::string label = "(" + string_utils::toString( position[0] ) + "," +
579  string_utils::toString( position[1] ) + "," + string_utils::toString( position[2] ) + ")";
580  return ( addLabel( position, label ) );
581 }
582 
583 osg::ref_ptr< osg::Geode > wge::genFinitePlane( double xSize, double ySize, const WPlane& p, const WColor& color, bool border )
584 {
585  using osg::ref_ptr;
586  ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
587  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
588  ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
589 
590  colors->push_back( color );
591 
592  vertices->push_back( p.getPointInPlane( xSize, ySize ) );
593  vertices->push_back( p.getPointInPlane( -xSize, ySize ) );
594  vertices->push_back( p.getPointInPlane( -xSize, -ySize ) );
595  vertices->push_back( p.getPointInPlane( xSize, -ySize ) );
596 
597  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
598  geometry->setVertexArray( vertices );
599  geometry->setColorArray( colors );
600  geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
601 
602  osg::StateSet* stateset = new osg::StateSet;
603  stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
604  geometry->setStateSet( stateset );
605 
606  osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
607  geode->addDrawable( geometry );
608 
609  if( border )
610  {
611  vertices->push_back( vertices->front() );
612  ref_ptr< osg::Geometry > borderGeom = ref_ptr< osg::Geometry >( new osg::Geometry );
613  borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, 4 ) );
614  borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 3, 2 ) );
615  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
616  colors->push_back( inverseColor( color ) );
617  borderGeom->setColorArray( colors );
618  borderGeom->setColorBinding( osg::Geometry::BIND_OVERALL );
619  borderGeom->setVertexArray( vertices );
620  geode->addDrawable( borderGeom );
621  }
622  return geode;
623 }
624 
625 osg::ref_ptr< osg::Geode > wge::genFinitePlane( osg::Vec3 const& base, osg::Vec3 const& a, osg::Vec3 const& b, const WColor& color )
626 {
627  // the stuff needed by the OSG to create a geometry instance
628  osg::ref_ptr< osg::Vec3Array > vertices = new osg::Vec3Array;
629  osg::ref_ptr< osg::Vec3Array > texcoords0 = new osg::Vec3Array;
630  osg::ref_ptr< osg::Vec3Array > normals = new osg::Vec3Array;
631  osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array;
632 
633  osg::Vec3 aPlusB = a + b;
634 
635  vertices->push_back( base );
636  vertices->push_back( base + a );
637  vertices->push_back( base + aPlusB );
638  vertices->push_back( base + b );
639 
640  osg::Vec3 aCrossB = a ^ b;
641  aCrossB.normalize();
642  osg::Vec3 aNorm = a;
643  aNorm.normalize();
644  osg::Vec3 bNorm = b;
645  bNorm.normalize();
646 
647  normals->push_back( aCrossB );
648  colors->push_back( color );
649  texcoords0->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
650  texcoords0->push_back( aNorm );
651  texcoords0->push_back( aNorm + bNorm );
652  texcoords0->push_back( bNorm );
653 
654  // put it all together
655  osg::ref_ptr< osg::Geometry > geometry = new osg::Geometry();
656  geometry->setVertexArray( vertices );
657  geometry->setTexCoordArray( 0, texcoords0 );
658  geometry->setNormalArray( normals );
659  geometry->setNormalBinding( osg::Geometry::BIND_OVERALL );
660  geometry->setColorArray( colors );
661  geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
662  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
663 
664  osg::ref_ptr< osg::Geode > geode = new osg::Geode();
665  geode->addDrawable( geometry );
666  return geode;
667 }
668 
669 osg::ref_ptr< osg::Group > wge::creatCoordinateSystem(
670  osg::Vec3 middle,
671  double sizeX,
672  double sizeY,
673  double sizeZ
674 )
675 {
676  osg::ref_ptr< WGEGroupNode >groupNode = new WGEGroupNode();
677  osg::ref_ptr< WGEShader > shaderCoordinateSystem( new WGEShader( "WGECoordinateSystem" ) );
678 
679  osg::ref_ptr< osg::Geode > graphX( new osg::Geode );
680  osg::ref_ptr< osg::Geode > graphY( new osg::Geode );
681  osg::ref_ptr< osg::Geode > graphZ( new osg::Geode );
682 
683  osg::ref_ptr< osg::Geode > graphXCylinder( new osg::Geode );
684  osg::ref_ptr< osg::Geode > graphYCylinder( new osg::Geode );
685  osg::ref_ptr< osg::Geode > graphZCylinder( new osg::Geode );
686 
687  // X
688  osg::ref_ptr< osg::ShapeDrawable > cylinderX = new osg::ShapeDrawable( new osg::Cylinder(
689  middle, 1, sizeX + ( sizeX * 0.5 )
690  ) );
691  osg::ref_ptr< osg::ShapeDrawable > cylinderXEnd = new osg::ShapeDrawable( new osg::Cylinder(
692  osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 1.0, 1.0
693  ) );
694  osg::ref_ptr< osg::ShapeDrawable > coneX = new osg::ShapeDrawable( new osg::Cone(
695  osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 2.0, 5.0
696  ) );
697  cylinderXEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
698  graphXCylinder->addDrawable( cylinderX );
699  graphX->addDrawable( coneX );
700  graphX->addDrawable( cylinderXEnd );
701 
702  osg::ref_ptr< osg::Material > matX = new osg::Material();
703  matX->setDiffuse( osg::Material::FRONT, WColor( 1.0, 0.0, 0.0, 1.0 ) );
704  cylinderX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON );
705  coneX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON );
706 
707  // Y
708  osg::ref_ptr< osg::ShapeDrawable > cylinderY = new osg::ShapeDrawable( new osg::Cylinder(
709  middle, 1, sizeY + ( sizeY * 0.5 )
710  ) );
711  osg::ref_ptr< osg::ShapeDrawable > cylinderYEnd = new osg::ShapeDrawable( new osg::Cylinder(
712  osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 1.0, 1.0
713  ) );
714  osg::ref_ptr< osg::ShapeDrawable > coneY = new osg::ShapeDrawable( new osg::Cone(
715  osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 2.0, 5.0
716  ) );
717  cylinderYEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
718 
719  graphYCylinder->addDrawable( cylinderY );
720  graphY->addDrawable( coneY );
721  graphY->addDrawable( cylinderYEnd );
722 
723  osg::ref_ptr< osg::Material > matY = new osg::Material();
724  matY->setDiffuse( osg::Material::FRONT, WColor( 0.0, 1.0, 0.0, 1.0 ) );
725  cylinderY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON );
726  coneY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON );
727 
728 
729  // Z
730  osg::ref_ptr< osg::ShapeDrawable > cylinderZ = new osg::ShapeDrawable( new osg::Cylinder(
731  middle, 1, sizeZ + ( sizeZ * 0.5 )
732  ) );
733  osg::ref_ptr< osg::ShapeDrawable > cylinderZEnd = new osg::ShapeDrawable( new osg::Cylinder(
734  osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 1.0, 1.0
735  ) );
736  osg::ref_ptr< osg::ShapeDrawable > coneZ = new osg::ShapeDrawable( new osg::Cone(
737  osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 2.0, 5.0
738  ) );
739  cylinderZEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
740 
741  graphZCylinder->addDrawable( cylinderZ );
742  graphZ->addDrawable( coneZ );
743  graphZ->addDrawable( cylinderZEnd );
744 
745  osg::ref_ptr< osg::Material > matZ = new osg::Material();
746  matZ->setDiffuse( osg::Material::FRONT, WColor( 0.0, 0.0, 1.0, 1.0 ) );
747  cylinderZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON );
748  coneZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON );
749 
750  shaderCoordinateSystem->apply( graphXCylinder );
751  shaderCoordinateSystem->apply( graphYCylinder );
752  shaderCoordinateSystem->apply( graphZCylinder );
753 
754  osg::ref_ptr< WGELabel > graphXLabel = new WGELabel();
755  graphXLabel->setText( "X" );
756  graphXLabel->setCharacterSize( 10 );
757  graphXLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 + 5.0 ) );
758  graphXLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
759  graphX->addDrawable( graphXLabel );
760 
761  osg::ref_ptr< WGELabel > graphYLabel = new WGELabel();
762  graphYLabel->setText( "Y" );
763  graphYLabel->setCharacterSize( 10 );
764  graphYLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 + 5.0 ) );
765  graphYLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
766  graphY->addDrawable( graphYLabel );
767 
768  osg::ref_ptr< WGELabel > graphZLabel = new WGELabel();
769  graphZLabel->setText( "Z" );
770  graphZLabel->setCharacterSize( 10 );
771  graphZLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 + 5.0 ) );
772  graphZLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
773  graphZ->addDrawable( graphZLabel );
774 
775 
776  osg::ref_ptr< osg::MatrixTransform > graphXTransform = new osg::MatrixTransform();
777  graphXTransform->addChild( graphX );
778  graphXTransform->addChild( graphXCylinder );
779  osg::ref_ptr< osg::MatrixTransform > graphYTransform = new osg::MatrixTransform();
780  graphYTransform->addChild( graphY );
781  graphYTransform->addChild( graphYCylinder );
782  osg::ref_ptr< osg::MatrixTransform > graphZTransform = new osg::MatrixTransform();
783  graphZTransform->addChild( graphZ );
784  graphZTransform->addChild( graphZCylinder );
785 
786  osg::Matrixd matrixTranslateTo0 = osg::Matrixd::translate( -middle.x(), -middle.y(), -middle.z() );
787  osg::Matrixd matrixTranslateFrom0 = osg::Matrixd::translate( middle.x(), middle.y(), middle.z() );
788 
789  graphXTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate(
790  90.0 * piDouble / 180.0,
791  osg::Vec3f( 0.0, 1.0, 0.0 ) ) * matrixTranslateFrom0
792  );
793  graphYTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate(
794  -90.0 * piDouble / 180.0,
795  osg::Vec3f( 1.0, 0.0, 0.0 ) ) * matrixTranslateFrom0
796  );
797 
798  groupNode->insert( graphXTransform );
799  groupNode->insert( graphYTransform );
800  groupNode->insert( graphZTransform );
801 
802  return groupNode;
803 }
const std::map< size_t, WColor > & getData() const
Reference to the data.
Represents a std::map where for each vertex ID a color is stored.
osg::ref_ptr< osg::Geometry > createUnitCubeAsLines(const WColor &color)
Creates a osg::Geometry containing an unit cube as line-strips, having 3D texture coordinates...
static Fonts getAllFonts()
The paths to all fonts supported.
osg::ref_ptr< osg::Geometry > createUnitCube(const WColor &color)
Creates a osg::Geometry containing an unit cube, having 3D texture coordinates.
osg::ref_ptr< osg::PositionAttitudeTransform > addLabel(osg::Vec3 position, std::string text)
helper function to add a label somewhere
osg::ref_ptr< osg::Geode > genFinitePlane(double xSize, double ySize, const WPlane &p, const WColor &color=WColor(0.0, 0.7, 0.7, 1.0), bool border=false)
Generates a geode out of a Plane with a fixed size in direction of the vectors which span that plane...
This only is a 3d double vector.
osg::ref_ptr< osg::Geometry > convertToOsgGeometryLines(WTriangleMesh::SPtr mesh, const WColor &defaultColor=WColor(1.0, 1.0, 1.0, 1.0), bool useMeshColor=true)
Convert triangle mesh to lines representing it.
Represents a plane with a normal vector and a position in space.
Definition: WPlane.h:41
osg::ref_ptr< osg::Geometry > convertToOsgGeometryFlatShaded(WTriangleMesh::SPtr mesh, const WColor &defaultColor=WColor(1.0, 1.0, 1.0, 1.0), bool includeNormals=false, bool lighting=false, bool useMeshColor=true)
Extract the vertices and triangles from a WTriangleMesh and save them into an osg::Geometry in order ...
osg::BoundingBoxImpl< osg::Vec3 >::vec_type vec_type
Vertex type for min and max positions of this box.
Definition: WBoundingBox.h:53
osg::ref_ptr< osg::Group > creatCoordinateSystem(osg::Vec3 middle, double sizeX, double sizeY, double sizeZ)
Create a coordinate system.
osg::ref_ptr< osg::PositionAttitudeTransform > vector2label(osg::Vec3 position)
helper function to add a label with it's position vector
osg::ref_ptr< osg::Geometry > convertToOsgGeometry(WTriangleMesh::SPtr mesh, const WColor &defaultColor=WColor(1.0, 1.0, 1.0, 1.0), bool includeNormals=false, bool lighting=false, bool useMeshColor=true)
Extract the vertices and triangles from a WTriangleMesh and save them into an osg::Geometry.
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader...
Definition: WGEShader.h:51
WPosition getPointInPlane(double x, double y) const
Computes with relative coordinates a point in this plane.
Definition: WPlane.cpp:153
Class to wrap around the osg Group node and providing a thread safe add/removal mechanism.
Definition: WGEGroupNode.h:48
std::string toString(const T &value)
Convert a given value to a string.
Definition: WStringUtils.h:120
const vec_type & getMin() const
Gives the front lower left aka minimum corner.
Definition: WBoundingBox.h:315
osg::ref_ptr< osg::Node > generateSolidBoundingBoxNode(const WBoundingBox &bb, const WColor &color, bool threeDTexCoords=true)
Generates an OSG node for the specified bounding box.
osg::ref_ptr< osg::Geode > generateBoundingBoxGeode(const WBoundingBox &bb, const WColor &color)
Generates an OSG geode for the bounding box.
Label layout-item.
Definition: WGELabel.h:37
const vec_type & getMax() const
Gives the back upper right aka maximum corner.
Definition: WBoundingBox.h:321
boost::shared_ptr< WTriangleMesh > SPtr
Shared pointer.
Definition: WTriangleMesh.h:51
Some default colors.
Definition: WColor.cpp:35
void createCube(osg::ref_ptr< osg::Geometry > geometry, const WPosition &position, const WPosition &size, const WColor &color)
Create an arbitrary cube and insert it into the given geometry.