OpenWalnut  1.3.1
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/linearAlgebra/WLinearAlgebra.h"
40 #include "../common/math/WMath.h"
41 #include "../common/WPathHelper.h"
42 #include "../common/WStringUtils.h"
43 
44 #include "shaders/WGEShader.h"
45 #include "WGEGeodeUtils.h"
46 #include "WGEGeometryUtils.h"
47 #include "WGEGroupNode.h"
48 #include "WGESubdividedPlane.h"
49 #include "WGEUtils.h"
50 #include "widgets/labeling/WGELabel.h"
51 
52 osg::ref_ptr< osg::Geode > wge::generateBoundingBoxGeode( const WBoundingBox& bb, const WColor& color )
53 {
54  const WBoundingBox::vec_type& pos1 = bb.getMin();
55  const WBoundingBox::vec_type& pos2 = bb.getMax();
56 
57  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!" );
58  using osg::ref_ptr;
59  ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
60  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
61  ref_ptr< deprecated_osg::Geometry > geometry = ref_ptr< deprecated_osg::Geometry >( new deprecated_osg::Geometry );
62 
63  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) );
64  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) );
65  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) );
66  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) );
67  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) );
68  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) );
69  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) );
70  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) );
71  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) );
72  vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) );
73 
74  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) );
75 
76  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) );
77  vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) );
78  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) );
79  vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) );
80  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) );
81  vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) );
82 
83  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) );
84 
85  geometry->setVertexArray( vertices );
86  colors->push_back( color );
87  geometry->setColorArray( colors );
88  geometry->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
89  osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
90  geode->addDrawable( geometry );
91 
92  // disable light for this geode as lines can't be lit properly
93  osg::StateSet* state = geode->getOrCreateStateSet();
94  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
95 
96  return geode;
97 }
98 
99 osg::ref_ptr< deprecated_osg::Geometry > wge::createUnitCube( const WColor& color )
100 {
101  // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
102  osg::ref_ptr< deprecated_osg::Geometry > cube = new deprecated_osg::Geometry();
103  osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
104  osg::ref_ptr< osg::Vec3Array > normals = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
105  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
106 
107  // front face
108  vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
109  vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
110  vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
111  vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
112  normals->push_back( osg::Vec3( 0.0, 0.0, -1.0 ) );
113 
114  // back face
115  vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
116  vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
117  vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
118  vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
119  normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
120 
121  // left
122  vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
123  vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
124  vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
125  vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
126  normals->push_back( osg::Vec3( -1.0, 0.0, 0.0 ) );
127 
128  // right
129  vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
130  vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
131  vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
132  vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
133  normals->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
134 
135  // bottom
136  vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
137  vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
138  vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
139  vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
140  normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) );
141 
142  // top
143  vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
144  vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
145  vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
146  vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
147  normals->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
148 
149  // set it up and set arrays
150  cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, vertices->size() ) );
151  cube->setVertexArray( vertices );
152 
153  // set 3D texture coordinates here.
154  cube->setTexCoordArray( 0, vertices );
155 
156  // set normals
157  cube->setNormalArray( normals );
158  cube->setNormalBinding( deprecated_osg::Geometry::BIND_PER_PRIMITIVE );
159 
160  // finally, the colors
161  colors->push_back( color );
162  cube->setColorArray( colors );
163  cube->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
164 
165  return cube;
166 }
167 
168 osg::ref_ptr< deprecated_osg::Geometry > wge::createUnitCubeAsLines( const WColor& color )
169 {
170  // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
171  osg::ref_ptr< deprecated_osg::Geometry > cube = new deprecated_osg::Geometry();
172  osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
173  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
174 
175  vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
176  vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
177  vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
178  vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
179  vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
180  vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
181  vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
182  vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
183  vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
184  vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
185 
186  cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) );
187 
188  vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
189  vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
190  vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
191  vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
192  vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
193  vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
194 
195  cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) );
196 
197  // set it up and set arrays
198  cube->setVertexArray( vertices );
199 
200  // set 3D texture coordinates here.
201  cube->setTexCoordArray( 0, vertices );
202 
203  // finally, the colors
204  colors->push_back( color );
205  cube->setColorArray( colors );
206  cube->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
207 
208  return cube;
209 }
210 
211 osg::ref_ptr< osg::Node > wge::generateSolidBoundingBoxNode( const WBoundingBox& bb, const WColor& color, bool threeDTexCoords )
212 {
213  WAssert( bb.valid(), "Invalid bounding box!" );
214 
215  // create a uni cube
216  osg::ref_ptr< osg::Geode > cube = new osg::Geode();
217  cube->setName( "Solid Bounding Box" );
218  if( threeDTexCoords )
219  {
220  cube->addDrawable( createUnitCube( color ) );
221  }
222  else
223  {
224  osg::ref_ptr< osg::ShapeDrawable > cubeDrawable = new osg::ShapeDrawable( new osg::Box( osg::Vec3( 0.5, 0.5, 0.5 ), 1.0 ) );
225  cubeDrawable->setColor( color );
226  cube->addDrawable( cubeDrawable );
227  }
228 
229  // transform the cube to match the bbox
230  osg::Matrixd transformM;
231  osg::Matrixd scaleM;
232  transformM.makeTranslate( bb.getMin() );
233  scaleM.makeScale( bb.getMax() - bb.getMin() );
234 
235  // apply transformation to bbox
236  osg::ref_ptr< osg::MatrixTransform > transform = new osg::MatrixTransform();
237  transform->setMatrix( scaleM * transformM );
238  transform->addChild( cube );
239 
240  // we do not need light
241  osg::StateSet* state = cube->getOrCreateStateSet();
242  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
243 
244  return transform;
245 }
246 
247 osg::ref_ptr< deprecated_osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh,
248  const WColor& defaultColor,
249  bool includeNormals,
250  bool lighting,
251  bool useMeshColor )
252 {
253  osg::ref_ptr< deprecated_osg::Geometry> geometry( new deprecated_osg::Geometry );
254  geometry->setVertexArray( mesh->getVertexArray() );
255 
256  osg::DrawElementsUInt* surfaceElement;
257 
258  surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
259 
260  std::vector< size_t > tris = mesh->getTriangles();
261  surfaceElement->reserve( tris.size() );
262 
263  for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
264  {
265  surfaceElement->push_back( tris[vertId] );
266  }
267  geometry->addPrimitiveSet( surfaceElement );
268 
269  // add the mesh colors
270  if( mesh->getVertexColorArray() && useMeshColor )
271  {
272  geometry->setColorArray( mesh->getVertexColorArray() );
273  geometry->setColorBinding( deprecated_osg::Geometry::BIND_PER_VERTEX );
274  }
275  else
276  {
277  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
278  colors->push_back( defaultColor );
279  geometry->setColorArray( colors );
280  geometry->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
281  }
282 
283  // ------------------------------------------------
284  // normals
285  if( includeNormals )
286  {
287  geometry->setNormalArray( mesh->getVertexNormalArray() );
288  geometry->setNormalBinding( deprecated_osg::Geometry::BIND_PER_VERTEX );
289 
290  if( lighting )
291  {
292  // if normals are specified, we also setup a default lighting.
293  osg::StateSet* state = geometry->getOrCreateStateSet();
294  osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
295  lightModel->setTwoSided( true );
296  state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
297  state->setMode( GL_BLEND, osg::StateAttribute::ON );
298  {
299  osg::ref_ptr< osg::Material > material = new osg::Material();
300  material->setDiffuse( osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
301  material->setSpecular( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
302  material->setAmbient( osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) );
303  material->setEmission( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
304  material->setShininess( osg::Material::FRONT, 25.0 );
305  state->setAttribute( material );
306  }
307  }
308  }
309 
310  // enable VBO
311  geometry->setUseDisplayList( false );
312  geometry->setUseVertexBufferObjects( true );
313 
314  return geometry;
315 }
316 
317 osg::ref_ptr< deprecated_osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh, const WColoredVertices& colorMap, const WColor& defaultColor,
318  bool includeNormals, bool lighting )
319 {
320  deprecated_osg::Geometry* geometry = convertToOsgGeometry( mesh, defaultColor, includeNormals, lighting, false );
321 
322  // ------------------------------------------------
323  // colors
324  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
325  for( size_t i = 0; i < mesh->vertSize(); ++i )
326  {
327  colors->push_back( defaultColor );
328  }
329  for( std::map< size_t, WColor >::const_iterator vc = colorMap.getData().begin(); vc != colorMap.getData().end(); ++vc )
330  {
331  // ATTENTION: the colormap might not be available and hence an old one, but the new mesh might have triggered the update
332  if( vc->first < colors->size() )
333  {
334  colors->at( vc->first ) = vc->second;
335  }
336  }
337 
338  geometry->setColorArray( colors );
339  geometry->setColorBinding( deprecated_osg::Geometry::BIND_PER_VERTEX );
340 
341  return geometry;
342 }
343 
344 osg::ref_ptr< deprecated_osg::Geometry > wge::convertToOsgGeometryLines( WTriangleMesh::SPtr mesh,
345  const WColor& defaultColor,
346  bool useMeshColor )
347 {
348  osg::ref_ptr< deprecated_osg::Geometry > geometry( new deprecated_osg::Geometry );
349  geometry->setVertexArray( mesh->getVertexArray() );
350 
351  osg::DrawElementsUInt* meshElement;
352 
353  meshElement = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
354 
355  std::vector< size_t > tris = mesh->getTriangles();
356  meshElement->reserve( tris.size() * 3 );
357 
358  for( unsigned int triId = 0; triId < tris.size() / 3.; ++triId )
359  {
360  for( size_t edgeId = 0; edgeId < 3; ++edgeId )
361  {
362  meshElement->push_back( tris[triId*3 + edgeId] );
363  meshElement->push_back( tris[triId*3 + ( edgeId + 1 ) % 3] );
364  }
365  }
366  geometry->addPrimitiveSet( meshElement );
367 
368  // add the mesh colors
369  if( mesh->getVertexColorArray() && useMeshColor )
370  {
371  geometry->setColorArray( mesh->getVertexColorArray() );
372  geometry->setColorBinding( deprecated_osg::Geometry::BIND_PER_VERTEX );
373  }
374  else
375  {
376  osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
377  colors->push_back( defaultColor );
378  geometry->setColorArray( colors );
379  geometry->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
380  }
381 
382  osg::StateSet* stateset = geometry->getOrCreateStateSet();
383  stateset->setAttributeAndModes( new osg::LineWidth( 1 ), osg::StateAttribute::ON );
384  stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
385 
386  return geometry;
387 }
388 
389 osg::ref_ptr< osg::Geode > wge::generateLineStripGeode( const WLine& line, const float thickness, const WColor& color )
390 {
391  using osg::ref_ptr;
392  ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
393  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
394  ref_ptr< deprecated_osg::Geometry > geometry = ref_ptr< deprecated_osg::Geometry >( new deprecated_osg::Geometry );
395 
396  for( size_t i = 1; i < line.size(); ++i )
397  {
398  vertices->push_back( osg::Vec3( line[i-1][0], line[i-1][1], line[i-1][2] ) );
399  colors->push_back( wge::getRGBAColorFromDirection( line[i-1], line[i] ) );
400  }
401  vertices->push_back( osg::Vec3( line.back()[0], line.back()[1], line.back()[2] ) );
402  colors->push_back( colors->back() );
403 
404  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, line.size() ) );
405  geometry->setVertexArray( vertices );
406 
407  if( color != WColor( 0, 0, 0, 0 ) )
408  {
409  colors->clear();
410  colors->push_back( color );
411  geometry->setColorArray( colors );
412  geometry->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
413  }
414  else
415  {
416  geometry->setColorArray( colors );
417  geometry->setColorBinding( deprecated_osg::Geometry::BIND_PER_VERTEX );
418  }
419 
420  // line width
421  osg::StateSet* stateset = geometry->getOrCreateStateSet();
422  stateset->setAttributeAndModes( new osg::LineWidth( thickness ), osg::StateAttribute::ON );
423  stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
424 
425  osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
426  geode->addDrawable( geometry );
427  return geode;
428 }
429 
430 osg::ref_ptr< osg::PositionAttitudeTransform > wge::addLabel( osg::Vec3 position, std::string text )
431 {
432  osg::ref_ptr< osgText::Text > label = osg::ref_ptr< osgText::Text >( new osgText::Text() );
433  osg::ref_ptr< osg::Geode > labelGeode = osg::ref_ptr< osg::Geode >( new osg::Geode() );
434 
435  labelGeode->addDrawable( label );
436 
437  // setup font
438  label->setFont( WPathHelper::getAllFonts().Default.string() );
439  label->setBackdropType( osgText::Text::OUTLINE );
440  label->setCharacterSize( 6 );
441 
442  label->setText( text );
443  label->setAxisAlignment( osgText::Text::SCREEN );
444  label->setDrawMode( osgText::Text::TEXT );
445  label->setAlignment( osgText::Text::CENTER_TOP );
446  label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) );
447  label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
448 
449  osg::ref_ptr< osg::PositionAttitudeTransform > labelXform =
450  osg::ref_ptr< osg::PositionAttitudeTransform >( new osg::PositionAttitudeTransform() );
451  labelXform->setPosition( position );
452 
453  labelXform->addChild( labelGeode );
454 
455  return labelXform;
456 }
457 
458 osg::ref_ptr< osg::PositionAttitudeTransform > wge::vector2label( osg::Vec3 position )
459 {
460  std::string label = "(" + string_utils::toString( position[0] ) + "," +
461  string_utils::toString( position[1] ) + "," + string_utils::toString( position[2] ) + ")";
462  return ( addLabel( position, label ) );
463 }
464 
465 osg::ref_ptr< osg::Geode > wge::genFinitePlane( double xSize, double ySize, const WPlane& p, const WColor& color, bool border )
466 {
467  using osg::ref_ptr;
468  ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
469  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
470  ref_ptr< deprecated_osg::Geometry > geometry = ref_ptr< deprecated_osg::Geometry >( new deprecated_osg::Geometry );
471 
472  colors->push_back( color );
473 
474  vertices->push_back( p.getPointInPlane( xSize, ySize ) );
475  vertices->push_back( p.getPointInPlane( -xSize, ySize ) );
476  vertices->push_back( p.getPointInPlane( -xSize, -ySize ) );
477  vertices->push_back( p.getPointInPlane( xSize, -ySize ) );
478 
479  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
480  geometry->setVertexArray( vertices );
481  geometry->setColorArray( colors );
482  geometry->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
483 
484  osg::StateSet* stateset = new osg::StateSet;
485  stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
486  geometry->setStateSet( stateset );
487 
488  osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
489  geode->addDrawable( geometry );
490 
491  if( border )
492  {
493  vertices->push_back( vertices->front() );
494  ref_ptr< deprecated_osg::Geometry > borderGeom = ref_ptr< deprecated_osg::Geometry >( new deprecated_osg::Geometry );
495  borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, 4 ) );
496  borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 3, 2 ) );
497  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
498  colors->push_back( inverseColor( color ) );
499  borderGeom->setColorArray( colors );
500  borderGeom->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
501  borderGeom->setVertexArray( vertices );
502  geode->addDrawable( borderGeom );
503  }
504  return geode;
505 }
506 
507 osg::ref_ptr< osg::Geode > wge::genFinitePlane( osg::Vec3 const& base, osg::Vec3 const& a, osg::Vec3 const& b )
508 {
509  // the stuff needed by the OSG to create a geometry instance
510  osg::ref_ptr< osg::Vec3Array > vertices = new osg::Vec3Array;
511  osg::ref_ptr< osg::Vec3Array > texcoords0 = new osg::Vec3Array;
512  osg::ref_ptr< osg::Vec3Array > normals = new osg::Vec3Array;
513  osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array;
514 
515  osg::Vec3 aPlusB = a + b;
516 
517  vertices->push_back( base );
518  vertices->push_back( base + a );
519  vertices->push_back( base + aPlusB );
520  vertices->push_back( base + b );
521 
522  osg::Vec3 aCrossB = a ^ b;
523  aCrossB.normalize();
524  osg::Vec3 aNorm = a;
525  aNorm.normalize();
526  osg::Vec3 bNorm = b;
527  bNorm.normalize();
528 
529  normals->push_back( aCrossB );
530  colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
531  texcoords0->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
532  texcoords0->push_back( aNorm );
533  texcoords0->push_back( aNorm + bNorm );
534  texcoords0->push_back( bNorm );
535 
536  // put it all together
537  osg::ref_ptr< deprecated_osg::Geometry > geometry = new deprecated_osg::Geometry();
538  geometry->setVertexArray( vertices );
539  geometry->setTexCoordArray( 0, texcoords0 );
540  geometry->setNormalBinding( deprecated_osg::Geometry::BIND_OVERALL );
541  geometry->setColorBinding( deprecated_osg::Geometry::BIND_OVERALL );
542  geometry->setNormalArray( normals );
543  geometry->setColorArray( colors );
544  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
545 
546  osg::ref_ptr< osg::Geode > geode = new osg::Geode();
547  geode->addDrawable( geometry );
548  return geode;
549 }
550 
551 osg::ref_ptr< WGESubdividedPlane > wge::genUnitSubdividedPlane( size_t resX, size_t resY, double spacing )
552 {
553  WAssert( resX > 0 && resY > 0, "A Plane with no quad is not supported, use another datatype for that!" );
554  double dx = ( resX > 1 ? 1.0 / ( resX - 1 ) : 1.0 );
555  double dy = ( resY > 1 ? 1.0 / ( resY - 1 ) : 1.0 );
556 
557  size_t numQuads = resX * resY;
558 
559  using osg::ref_ptr;
560  ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array( numQuads * 4 ) );
561  ref_ptr< osg::Vec3Array > centers = ref_ptr< osg::Vec3Array >( new osg::Vec3Array( numQuads ) );
562  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array( numQuads ) );
563 
564  for( size_t yQuad = 0; yQuad < resY; ++yQuad )
565  {
566  for( size_t xQuad = 0; xQuad < resX; ++xQuad )
567  {
568  size_t qIndex = yQuad * resX + xQuad;
569  size_t vIndex = qIndex * 4; // since there are 4 corners
570  vertices->at( vIndex ) = osg::Vec3( xQuad * dx + spacing, yQuad * dy + spacing, 0.0 );
571  vertices->at( vIndex + 1 ) = osg::Vec3( xQuad * dx + dx - spacing, yQuad * dy + spacing, 0.0 );
572  vertices->at( vIndex + 2 ) = osg::Vec3( xQuad * dx + dx - spacing, yQuad * dy + dy - spacing, 0.0 );
573  vertices->at( vIndex + 3 ) = osg::Vec3( xQuad * dx + spacing, yQuad * dy + dy - spacing, 0.0 );
574  centers->at( qIndex ) = osg::Vec3( xQuad * dx + dx / 2.0, yQuad * dy + dy / 2.0, 0.0 );
575  colors->at( qIndex ) = osg::Vec4( 0.1 + static_cast< double >( qIndex ) / numQuads * 0.6,
576  0.1 + static_cast< double >( qIndex ) / numQuads * 0.6,
577  1.0, 1.0 );
578  }
579  }
580 
581  ref_ptr< deprecated_osg::Geometry > geometry = ref_ptr< deprecated_osg::Geometry >( new deprecated_osg::Geometry );
582  geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, vertices->size() ) );
583  geometry->setVertexArray( vertices );
584  geometry->setColorArray( colors );
585  geometry->setColorBinding( deprecated_osg::Geometry::BIND_PER_PRIMITIVE );
586 
587  ref_ptr< osg::Vec3Array > normals = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
588  normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
589  geometry->setNormalArray( normals );
590  geometry->setNormalBinding( deprecated_osg::Geometry::BIND_OVERALL );
591  osg::ref_ptr< WGESubdividedPlane > geode = osg::ref_ptr< WGESubdividedPlane >( new WGESubdividedPlane );
592  geode->addDrawable( geometry );
593  geode->setCenterArray( centers );
594 
595  // we need to disable light, since the order of the vertices may be wrong and with lighting you won't see anything but black surfaces
596  osg::StateSet* state = geode->getOrCreateStateSet();
597  state->setMode( GL_BLEND, osg::StateAttribute::ON );
598  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
599 
600  return geode;
601 }
602 
603 osg::ref_ptr< osg::Group > wge::creatCoordinateSystem(
604  osg::Vec3 middle,
605  double sizeX,
606  double sizeY,
607  double sizeZ
608 )
609 {
610  osg::ref_ptr< WGEGroupNode >groupNode = new WGEGroupNode();
611  osg::ref_ptr< WGEShader > shaderCoordinateSystem( new WGEShader( "WGECoordinateSystem" ) );
612 
613  osg::ref_ptr< osg::Geode > graphX( new osg::Geode );
614  osg::ref_ptr< osg::Geode > graphY( new osg::Geode );
615  osg::ref_ptr< osg::Geode > graphZ( new osg::Geode );
616 
617  osg::ref_ptr< osg::Geode > graphXCylinder( new osg::Geode );
618  osg::ref_ptr< osg::Geode > graphYCylinder( new osg::Geode );
619  osg::ref_ptr< osg::Geode > graphZCylinder( new osg::Geode );
620 
621  // X
622  osg::ref_ptr< osg::ShapeDrawable > cylinderX = new osg::ShapeDrawable( new osg::Cylinder(
623  middle, 1, sizeX + ( sizeX * 0.5 )
624  ) );
625  osg::ref_ptr< osg::ShapeDrawable > cylinderXEnd = new osg::ShapeDrawable( new osg::Cylinder(
626  osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 1.0, 1.0
627  ) );
628  osg::ref_ptr< osg::ShapeDrawable > coneX = new osg::ShapeDrawable( new osg::Cone(
629  osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 2.0, 5.0
630  ) );
631  cylinderXEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
632  graphXCylinder->addDrawable( cylinderX );
633  graphX->addDrawable( coneX );
634  graphX->addDrawable( cylinderXEnd );
635 
636  osg::ref_ptr< osg::Material > matX = new osg::Material();
637  matX->setDiffuse( osg::Material::FRONT, WColor( 1.0, 0.0, 0.0, 1.0 ) );
638  cylinderX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON );
639  coneX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON );
640 
641  // Y
642  osg::ref_ptr< osg::ShapeDrawable > cylinderY = new osg::ShapeDrawable( new osg::Cylinder(
643  middle, 1, sizeY + ( sizeY * 0.5 )
644  ) );
645  osg::ref_ptr< osg::ShapeDrawable > cylinderYEnd = new osg::ShapeDrawable( new osg::Cylinder(
646  osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 1.0, 1.0
647  ) );
648  osg::ref_ptr< osg::ShapeDrawable > coneY = new osg::ShapeDrawable( new osg::Cone(
649  osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 2.0, 5.0
650  ) );
651  cylinderYEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
652 
653  graphYCylinder->addDrawable( cylinderY );
654  graphY->addDrawable( coneY );
655  graphY->addDrawable( cylinderYEnd );
656 
657  osg::ref_ptr< osg::Material > matY = new osg::Material();
658  matY->setDiffuse( osg::Material::FRONT, WColor( 0.0, 1.0, 0.0, 1.0 ) );
659  cylinderY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON );
660  coneY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON );
661 
662 
663  // Z
664  osg::ref_ptr< osg::ShapeDrawable > cylinderZ = new osg::ShapeDrawable( new osg::Cylinder(
665  middle, 1, sizeZ + ( sizeZ * 0.5 )
666  ) );
667  osg::ref_ptr< osg::ShapeDrawable > cylinderZEnd = new osg::ShapeDrawable( new osg::Cylinder(
668  osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 1.0, 1.0
669  ) );
670  osg::ref_ptr< osg::ShapeDrawable > coneZ = new osg::ShapeDrawable( new osg::Cone(
671  osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 2.0, 5.0
672  ) );
673  cylinderZEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
674 
675  graphZCylinder->addDrawable( cylinderZ );
676  graphZ->addDrawable( coneZ );
677  graphZ->addDrawable( cylinderZEnd );
678 
679  osg::ref_ptr< osg::Material > matZ = new osg::Material();
680  matZ->setDiffuse( osg::Material::FRONT, WColor( 0.0, 0.0, 1.0, 1.0 ) );
681  cylinderZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON );
682  coneZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON );
683 
684  shaderCoordinateSystem->apply( graphXCylinder );
685  shaderCoordinateSystem->apply( graphYCylinder );
686  shaderCoordinateSystem->apply( graphZCylinder );
687 
688  osg::ref_ptr< WGELabel > graphXLabel = new WGELabel();
689  graphXLabel->setText( "X" );
690  graphXLabel->setCharacterSize( 10 );
691  graphXLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 + 5.0 ) );
692  graphXLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
693  graphX->addDrawable( graphXLabel );
694 
695  osg::ref_ptr< WGELabel > graphYLabel = new WGELabel();
696  graphYLabel->setText( "Y" );
697  graphYLabel->setCharacterSize( 10 );
698  graphYLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 + 5.0 ) );
699  graphYLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
700  graphY->addDrawable( graphYLabel );
701 
702  osg::ref_ptr< WGELabel > graphZLabel = new WGELabel();
703  graphZLabel->setText( "Z" );
704  graphZLabel->setCharacterSize( 10 );
705  graphZLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 + 5.0 ) );
706  graphZLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
707  graphZ->addDrawable( graphZLabel );
708 
709 
710  osg::ref_ptr< osg::MatrixTransform > graphXTransform = new osg::MatrixTransform();
711  graphXTransform->addChild( graphX );
712  graphXTransform->addChild( graphXCylinder );
713  osg::ref_ptr< osg::MatrixTransform > graphYTransform = new osg::MatrixTransform();
714  graphYTransform->addChild( graphY );
715  graphYTransform->addChild( graphYCylinder );
716  osg::ref_ptr< osg::MatrixTransform > graphZTransform = new osg::MatrixTransform();
717  graphZTransform->addChild( graphZ );
718  graphZTransform->addChild( graphZCylinder );
719 
720  osg::Matrixd matrixTranslateTo0 = osg::Matrixd::translate( -middle.x(), -middle.y(), -middle.z() );
721  osg::Matrixd matrixTranslateFrom0 = osg::Matrixd::translate( middle.x(), middle.y(), middle.z() );
722 
723  graphXTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate(
724  90.0 * piDouble / 180.0,
725  osg::Vec3f( 0.0, 1.0, 0.0 ) ) * matrixTranslateFrom0
726  );
727  graphYTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate(
728  -90.0 * piDouble / 180.0,
729  osg::Vec3f( 1.0, 0.0, 0.0 ) ) * matrixTranslateFrom0
730  );
731 
732  groupNode->insert( graphXTransform );
733  groupNode->insert( graphYTransform );
734  groupNode->insert( graphZTransform );
735 
736  return groupNode;
737 }