OpenWalnut 1.3.1
WGEGeodeUtils.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #include <map>
00026 #include <string>
00027 #include <vector>
00028 
00029 #include <osg/Array>
00030 #include <osg/Geode>
00031 #include <osg/Geometry>
00032 #include <osg/LightModel>
00033 #include <osg/LineWidth>
00034 #include <osg/Material>
00035 #include <osg/MatrixTransform>
00036 #include <osg/ShapeDrawable>
00037 #include <osg/Vec3>
00038 
00039 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00040 #include "../common/math/WMath.h"
00041 #include "../common/WPathHelper.h"
00042 #include "../common/WStringUtils.h"
00043 
00044 #include "shaders/WGEShader.h"
00045 #include "WGEGeodeUtils.h"
00046 #include "WGEGeometryUtils.h"
00047 #include "WGEGroupNode.h"
00048 #include "WGESubdividedPlane.h"
00049 #include "WGEUtils.h"
00050 #include "widgets/labeling/WGELabel.h"
00051 
00052 osg::ref_ptr< osg::Geode > wge::generateBoundingBoxGeode( const WBoundingBox& bb, const WColor& color )
00053 {
00054     const WBoundingBox::vec_type& pos1 = bb.getMin();
00055     const WBoundingBox::vec_type& pos2 = bb.getMax();
00056 
00057     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!" );
00058     using osg::ref_ptr;
00059     ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00060     ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00061     ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
00062 
00063     vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) );
00064     vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) );
00065     vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) );
00066     vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) );
00067     vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) );
00068     vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) );
00069     vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) );
00070     vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) );
00071     vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) );
00072     vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) );
00073 
00074     geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) );
00075 
00076     vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) );
00077     vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) );
00078     vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) );
00079     vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) );
00080     vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) );
00081     vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) );
00082 
00083     geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) );
00084 
00085     geometry->setVertexArray( vertices );
00086     colors->push_back( color );
00087     geometry->setColorArray( colors );
00088     geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00089     osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
00090     geode->addDrawable( geometry );
00091 
00092     // disable light for this geode as lines can't be lit properly
00093     osg::StateSet* state = geode->getOrCreateStateSet();
00094     state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
00095 
00096     return geode;
00097 }
00098 
00099 osg::ref_ptr< osg::Geometry > wge::createUnitCube( const WColor& color )
00100 {
00101     // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
00102     osg::ref_ptr< osg::Geometry > cube = new osg::Geometry();
00103     osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00104     osg::ref_ptr< osg::Vec3Array > normals = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00105     osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00106 
00107     // front face
00108     vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
00109     vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
00110     vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
00111     vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
00112     normals->push_back( osg::Vec3( 0.0, 0.0, -1.0 ) );
00113 
00114     // back face
00115     vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
00116     vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
00117     vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
00118     vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
00119     normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
00120 
00121     // left
00122     vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
00123     vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
00124     vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
00125     vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
00126     normals->push_back( osg::Vec3( -1.0, 0.0, 0.0 ) );
00127 
00128     // right
00129     vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
00130     vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
00131     vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
00132     vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
00133     normals->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
00134 
00135     // bottom
00136     vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
00137     vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
00138     vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
00139     vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
00140     normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) );
00141 
00142     // top
00143     vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
00144     vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
00145     vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
00146     vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
00147     normals->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
00148 
00149     // set it up and set arrays
00150     cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, vertices->size() ) );
00151     cube->setVertexArray( vertices );
00152 
00153     // set 3D texture coordinates here.
00154     cube->setTexCoordArray( 0, vertices );
00155 
00156     // set normals
00157     cube->setNormalArray( normals );
00158     cube->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE );
00159 
00160     // finally, the colors
00161     colors->push_back( color );
00162     cube->setColorArray( colors );
00163     cube->setColorBinding( osg::Geometry::BIND_OVERALL );
00164 
00165     return cube;
00166 }
00167 
00168 osg::ref_ptr< osg::Geometry > wge::createUnitCubeAsLines( const WColor& color )
00169 {
00170     // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
00171     osg::ref_ptr< osg::Geometry > cube = new osg::Geometry();
00172     osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00173     osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00174 
00175     vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
00176     vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
00177     vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
00178     vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
00179     vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
00180     vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
00181     vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
00182     vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
00183     vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
00184     vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
00185 
00186     cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) );
00187 
00188     vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
00189     vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
00190     vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
00191     vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
00192     vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
00193     vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
00194 
00195     cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) );
00196 
00197     // set it up and set arrays
00198     cube->setVertexArray( vertices );
00199 
00200     // set 3D texture coordinates here.
00201     cube->setTexCoordArray( 0, vertices );
00202 
00203     // finally, the colors
00204     colors->push_back( color );
00205     cube->setColorArray( colors );
00206     cube->setColorBinding( osg::Geometry::BIND_OVERALL );
00207 
00208     return cube;
00209 }
00210 
00211 osg::ref_ptr< osg::Node > wge::generateSolidBoundingBoxNode( const WBoundingBox& bb, const WColor& color, bool threeDTexCoords )
00212 {
00213     WAssert( bb.valid(), "Invalid bounding box!" );
00214 
00215     // create a uni cube
00216     osg::ref_ptr< osg::Geode > cube = new osg::Geode();
00217     cube->setName( "Solid Bounding Box" );
00218     if( threeDTexCoords )
00219     {
00220         cube->addDrawable( createUnitCube( color ) );
00221     }
00222     else
00223     {
00224         osg::ref_ptr< osg::ShapeDrawable > cubeDrawable = new osg::ShapeDrawable( new osg::Box( osg::Vec3( 0.5, 0.5, 0.5 ), 1.0 ) );
00225         cubeDrawable->setColor( color );
00226         cube->addDrawable( cubeDrawable );
00227     }
00228 
00229     // transform the cube to match the bbox
00230     osg::Matrixd transformM;
00231     osg::Matrixd scaleM;
00232     transformM.makeTranslate( bb.getMin() );
00233     scaleM.makeScale( bb.getMax() - bb.getMin() );
00234 
00235     // apply transformation to bbox
00236     osg::ref_ptr< osg::MatrixTransform > transform = new osg::MatrixTransform();
00237     transform->setMatrix( scaleM * transformM );
00238     transform->addChild( cube );
00239 
00240     // we do not need light
00241     osg::StateSet* state = cube->getOrCreateStateSet();
00242     state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
00243 
00244     return transform;
00245 }
00246 
00247 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh,
00248                                                          const WColor& defaultColor,
00249                                                          bool includeNormals,
00250                                                          bool lighting,
00251                                                          bool useMeshColor )
00252 {
00253     osg::ref_ptr< osg::Geometry> geometry( new osg::Geometry );
00254     geometry->setVertexArray( mesh->getVertexArray() );
00255 
00256     osg::DrawElementsUInt* surfaceElement;
00257 
00258     surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 );
00259 
00260     std::vector< size_t > tris = mesh->getTriangles();
00261     surfaceElement->reserve( tris.size() );
00262 
00263     for( unsigned int vertId = 0; vertId < tris.size(); ++vertId )
00264     {
00265         surfaceElement->push_back( tris[vertId] );
00266     }
00267     geometry->addPrimitiveSet( surfaceElement );
00268 
00269     // add the mesh colors
00270     if( mesh->getVertexColorArray() && useMeshColor )
00271     {
00272         geometry->setColorArray( mesh->getVertexColorArray() );
00273         geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
00274     }
00275     else
00276     {
00277         osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00278         colors->push_back( defaultColor );
00279         geometry->setColorArray( colors );
00280         geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00281     }
00282 
00283     // ------------------------------------------------
00284     // normals
00285     if( includeNormals )
00286     {
00287         geometry->setNormalArray( mesh->getVertexNormalArray() );
00288         geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
00289 
00290         if( lighting )
00291         {
00292             // if normals are specified, we also setup a default lighting.
00293             osg::StateSet* state = geometry->getOrCreateStateSet();
00294             osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel();
00295             lightModel->setTwoSided( true );
00296             state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
00297             state->setMode(  GL_BLEND, osg::StateAttribute::ON  );
00298             {
00299                 osg::ref_ptr< osg::Material > material = new osg::Material();
00300                 material->setDiffuse(   osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
00301                 material->setSpecular(  osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
00302                 material->setAmbient(   osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) );
00303                 material->setEmission(  osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
00304                 material->setShininess( osg::Material::FRONT, 25.0 );
00305                 state->setAttribute( material );
00306             }
00307         }
00308     }
00309 
00310     // enable VBO
00311     geometry->setUseDisplayList( false );
00312     geometry->setUseVertexBufferObjects( true );
00313 
00314     return geometry;
00315 }
00316 
00317 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh, const WColoredVertices& colorMap, const WColor& defaultColor,
00318                                                          bool includeNormals, bool lighting )
00319 {
00320     osg::Geometry* geometry = convertToOsgGeometry( mesh, defaultColor, includeNormals, lighting, false );
00321 
00322     // ------------------------------------------------
00323     // colors
00324     osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00325     for( size_t i = 0; i < mesh->vertSize(); ++i )
00326     {
00327         colors->push_back( defaultColor );
00328     }
00329     for( std::map< size_t, WColor >::const_iterator vc = colorMap.getData().begin(); vc != colorMap.getData().end(); ++vc )
00330     {
00331         // ATTENTION: the colormap might not be available and hence an old one, but the new mesh might have triggered the update
00332         if( vc->first < colors->size() )
00333         {
00334             colors->at( vc->first ) = vc->second;
00335         }
00336     }
00337 
00338     geometry->setColorArray( colors );
00339     geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
00340 
00341     return geometry;
00342 }
00343 
00344 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometryLines( WTriangleMesh::SPtr mesh,
00345                                                               const WColor& defaultColor,
00346                                                               bool useMeshColor )
00347 {
00348     osg::ref_ptr< osg::Geometry > geometry( new osg::Geometry );
00349     geometry->setVertexArray( mesh->getVertexArray() );
00350 
00351     osg::DrawElementsUInt* meshElement;
00352 
00353     meshElement = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
00354 
00355     std::vector< size_t > tris = mesh->getTriangles();
00356     meshElement->reserve( tris.size() * 3 );
00357 
00358     for( unsigned int triId = 0; triId < tris.size() / 3.; ++triId )
00359     {
00360         for( size_t edgeId = 0; edgeId < 3; ++edgeId )
00361         {
00362             meshElement->push_back( tris[triId*3 + edgeId] );
00363             meshElement->push_back( tris[triId*3 + ( edgeId + 1 ) % 3] );
00364         }
00365     }
00366     geometry->addPrimitiveSet( meshElement );
00367 
00368     // add the mesh colors
00369     if( mesh->getVertexColorArray() && useMeshColor )
00370     {
00371         geometry->setColorArray( mesh->getVertexColorArray() );
00372         geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
00373     }
00374     else
00375     {
00376         osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00377         colors->push_back( defaultColor );
00378         geometry->setColorArray( colors );
00379         geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00380     }
00381 
00382     osg::StateSet* stateset = geometry->getOrCreateStateSet();
00383     stateset->setAttributeAndModes( new osg::LineWidth( 1 ), osg::StateAttribute::ON );
00384     stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00385 
00386     return geometry;
00387 }
00388 
00389 osg::ref_ptr< osg::Geode > wge::generateLineStripGeode( const WLine& line, const float thickness, const WColor& color )
00390 {
00391     using osg::ref_ptr;
00392     ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00393     ref_ptr< osg::Vec4Array > colors   = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00394     ref_ptr< osg::Geometry >  geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
00395 
00396     for( size_t i = 1; i < line.size(); ++i )
00397     {
00398         vertices->push_back( osg::Vec3( line[i-1][0], line[i-1][1], line[i-1][2] ) );
00399         colors->push_back( wge::getRGBAColorFromDirection( line[i-1], line[i] ) );
00400     }
00401     vertices->push_back( osg::Vec3( line.back()[0], line.back()[1], line.back()[2] ) );
00402     colors->push_back( colors->back() );
00403 
00404     geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, line.size() ) );
00405     geometry->setVertexArray( vertices );
00406 
00407     if( color != WColor( 0, 0, 0, 0 ) )
00408     {
00409         colors->clear();
00410         colors->push_back( color );
00411         geometry->setColorArray( colors );
00412         geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00413     }
00414     else
00415     {
00416         geometry->setColorArray( colors );
00417         geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
00418     }
00419 
00420     // line width
00421     osg::StateSet* stateset = geometry->getOrCreateStateSet();
00422     stateset->setAttributeAndModes( new osg::LineWidth( thickness ), osg::StateAttribute::ON );
00423     stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00424 
00425     osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
00426     geode->addDrawable( geometry );
00427     return geode;
00428 }
00429 
00430 osg::ref_ptr< osg::PositionAttitudeTransform > wge::addLabel( osg::Vec3 position, std::string text )
00431 {
00432     osg::ref_ptr< osgText::Text > label = osg::ref_ptr< osgText::Text >( new osgText::Text() );
00433     osg::ref_ptr< osg::Geode > labelGeode = osg::ref_ptr< osg::Geode >( new osg::Geode() );
00434 
00435     labelGeode->addDrawable( label );
00436 
00437     // setup font
00438     label->setFont( WPathHelper::getAllFonts().Default.string() );
00439     label->setBackdropType( osgText::Text::OUTLINE );
00440     label->setCharacterSize( 6 );
00441 
00442     label->setText( text );
00443     label->setAxisAlignment( osgText::Text::SCREEN );
00444     label->setDrawMode( osgText::Text::TEXT );
00445     label->setAlignment( osgText::Text::CENTER_TOP );
00446     label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) );
00447     label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
00448 
00449     osg::ref_ptr< osg::PositionAttitudeTransform > labelXform =
00450         osg::ref_ptr< osg::PositionAttitudeTransform >( new osg::PositionAttitudeTransform() );
00451     labelXform->setPosition( position );
00452 
00453     labelXform->addChild( labelGeode );
00454 
00455     return labelXform;
00456 }
00457 
00458 osg::ref_ptr< osg::PositionAttitudeTransform > wge::vector2label( osg::Vec3 position )
00459 {
00460     std::string label = "(" + string_utils::toString( position[0] ) + "," +
00461     string_utils::toString( position[1] ) + "," + string_utils::toString( position[2] ) + ")";
00462     return ( addLabel( position, label ) );
00463 }
00464 
00465 osg::ref_ptr< osg::Geode > wge::genFinitePlane( double xSize, double ySize, const WPlane& p, const WColor& color, bool border )
00466 {
00467     using osg::ref_ptr;
00468     ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00469     ref_ptr< osg::Vec4Array > colors   = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00470     ref_ptr< osg::Geometry >  geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
00471 
00472     colors->push_back( color );
00473 
00474     vertices->push_back( p.getPointInPlane(  xSize,  ySize ) );
00475     vertices->push_back( p.getPointInPlane( -xSize,  ySize ) );
00476     vertices->push_back( p.getPointInPlane( -xSize, -ySize ) );
00477     vertices->push_back( p.getPointInPlane(  xSize, -ySize ) );
00478 
00479     geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
00480     geometry->setVertexArray( vertices );
00481     geometry->setColorArray( colors );
00482     geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00483 
00484     osg::StateSet* stateset = new osg::StateSet;
00485     stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00486     geometry->setStateSet( stateset );
00487 
00488     osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
00489     geode->addDrawable( geometry );
00490 
00491     if( border )
00492     {
00493         vertices->push_back( vertices->front() );
00494         ref_ptr< osg::Geometry >  borderGeom = ref_ptr< osg::Geometry >( new osg::Geometry );
00495         borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, 4 ) );
00496         borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 3, 2 ) );
00497         ref_ptr< osg::Vec4Array > colors   = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
00498         colors->push_back( inverseColor( color ) );
00499         borderGeom->setColorArray( colors );
00500         borderGeom->setColorBinding( osg::Geometry::BIND_OVERALL );
00501         borderGeom->setVertexArray( vertices );
00502         geode->addDrawable( borderGeom );
00503     }
00504     return geode;
00505 }
00506 
00507 osg::ref_ptr< osg::Geode > wge::genFinitePlane( osg::Vec3 const& base, osg::Vec3 const& a, osg::Vec3 const& b )
00508 {
00509     // the stuff needed by the OSG to create a geometry instance
00510     osg::ref_ptr< osg::Vec3Array > vertices = new osg::Vec3Array;
00511     osg::ref_ptr< osg::Vec3Array > texcoords0 = new osg::Vec3Array;
00512     osg::ref_ptr< osg::Vec3Array > normals = new osg::Vec3Array;
00513     osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array;
00514 
00515     osg::Vec3 aPlusB = a + b;
00516 
00517     vertices->push_back( base );
00518     vertices->push_back( base + a );
00519     vertices->push_back( base + aPlusB );
00520     vertices->push_back( base + b );
00521 
00522     osg::Vec3 aCrossB = a ^ b;
00523     aCrossB.normalize();
00524     osg::Vec3 aNorm = a;
00525     aNorm.normalize();
00526     osg::Vec3 bNorm = b;
00527     bNorm.normalize();
00528 
00529     normals->push_back( aCrossB );
00530     colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
00531     texcoords0->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
00532     texcoords0->push_back( aNorm );
00533     texcoords0->push_back( aNorm + bNorm );
00534     texcoords0->push_back( bNorm );
00535 
00536     // put it all together
00537     osg::ref_ptr< osg::Geometry > geometry = new osg::Geometry();
00538     geometry->setVertexArray( vertices );
00539     geometry->setTexCoordArray( 0, texcoords0 );
00540     geometry->setNormalBinding( osg::Geometry::BIND_OVERALL );
00541     geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00542     geometry->setNormalArray( normals );
00543     geometry->setColorArray( colors );
00544     geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );
00545 
00546     osg::ref_ptr< osg::Geode > geode = new osg::Geode();
00547     geode->addDrawable( geometry );
00548     return geode;
00549 }
00550 
00551 osg::ref_ptr< WGESubdividedPlane > wge::genUnitSubdividedPlane( size_t resX, size_t resY, double spacing )
00552 {
00553     WAssert( resX > 0 && resY > 0, "A Plane with no quad is not supported, use another datatype for that!" );
00554     double dx = ( resX > 1 ? 1.0 / ( resX - 1 ) : 1.0 );
00555     double dy = ( resY > 1 ? 1.0 / ( resY - 1 ) : 1.0 );
00556 
00557     size_t numQuads = resX * resY;
00558 
00559     using osg::ref_ptr;
00560     ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array( numQuads * 4 ) );
00561     ref_ptr< osg::Vec3Array > centers = ref_ptr< osg::Vec3Array >( new osg::Vec3Array( numQuads ) );
00562     ref_ptr< osg::Vec4Array > colors   = ref_ptr< osg::Vec4Array >( new osg::Vec4Array( numQuads ) );
00563 
00564     for( size_t yQuad = 0; yQuad < resY; ++yQuad )
00565     {
00566         for( size_t xQuad = 0; xQuad < resX; ++xQuad )
00567         {
00568             size_t qIndex = yQuad * resX + xQuad;
00569             size_t vIndex = qIndex * 4; // since there are 4 corners
00570             vertices->at( vIndex     ) = osg::Vec3( xQuad * dx + spacing,      yQuad * dy + spacing,      0.0 );
00571             vertices->at( vIndex + 1 ) = osg::Vec3( xQuad * dx + dx - spacing, yQuad * dy + spacing,      0.0 );
00572             vertices->at( vIndex + 2 ) = osg::Vec3( xQuad * dx + dx - spacing, yQuad * dy + dy - spacing, 0.0 );
00573             vertices->at( vIndex + 3 ) = osg::Vec3( xQuad * dx + spacing,      yQuad * dy + dy - spacing, 0.0 );
00574             centers->at( qIndex ) = osg::Vec3( xQuad * dx + dx / 2.0, yQuad * dy + dy / 2.0, 0.0 );
00575             colors->at( qIndex ) = osg::Vec4( 0.1 +  static_cast< double >( qIndex ) / numQuads * 0.6,
00576                                               0.1 +  static_cast< double >( qIndex ) / numQuads * 0.6,
00577                                               1.0, 1.0 );
00578         }
00579     }
00580 
00581     ref_ptr< osg::Geometry >  geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
00582     geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, vertices->size() ) );
00583     geometry->setVertexArray( vertices );
00584     geometry->setColorArray( colors );
00585     geometry->setColorBinding( osg::Geometry::BIND_PER_PRIMITIVE );
00586 
00587     ref_ptr< osg::Vec3Array > normals = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00588     normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
00589     geometry->setNormalArray( normals );
00590     geometry->setNormalBinding( osg::Geometry::BIND_OVERALL );
00591     osg::ref_ptr< WGESubdividedPlane > geode = osg::ref_ptr< WGESubdividedPlane >( new WGESubdividedPlane );
00592     geode->addDrawable( geometry );
00593     geode->setCenterArray( centers );
00594 
00595     // 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
00596     osg::StateSet* state = geode->getOrCreateStateSet();
00597     state->setMode( GL_BLEND, osg::StateAttribute::ON );
00598     state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
00599 
00600     return geode;
00601 }
00602 
00603 osg::ref_ptr< osg::Group > wge::creatCoordinateSystem(
00604     osg::Vec3 middle,
00605     double sizeX,
00606     double sizeY,
00607     double sizeZ
00608 )
00609 {
00610     osg::ref_ptr< WGEGroupNode >groupNode = new WGEGroupNode();
00611     osg::ref_ptr< WGEShader > shaderCoordinateSystem( new WGEShader( "WGECoordinateSystem" ) );
00612 
00613     osg::ref_ptr< osg::Geode > graphX( new osg::Geode );
00614     osg::ref_ptr< osg::Geode > graphY( new osg::Geode );
00615     osg::ref_ptr< osg::Geode > graphZ( new osg::Geode );
00616 
00617     osg::ref_ptr< osg::Geode > graphXCylinder( new osg::Geode );
00618     osg::ref_ptr< osg::Geode > graphYCylinder( new osg::Geode );
00619     osg::ref_ptr< osg::Geode > graphZCylinder( new osg::Geode );
00620 
00621     // X
00622     osg::ref_ptr< osg::ShapeDrawable > cylinderX = new osg::ShapeDrawable( new osg::Cylinder(
00623         middle, 1, sizeX + ( sizeX * 0.5 )
00624     ) );
00625     osg::ref_ptr< osg::ShapeDrawable > cylinderXEnd = new osg::ShapeDrawable( new osg::Cylinder(
00626         osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 1.0, 1.0
00627     ) );
00628     osg::ref_ptr< osg::ShapeDrawable > coneX = new osg::ShapeDrawable( new osg::Cone(
00629         osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 2.0, 5.0
00630     ) );
00631     cylinderXEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00632     graphXCylinder->addDrawable( cylinderX );
00633     graphX->addDrawable( coneX );
00634     graphX->addDrawable( cylinderXEnd );
00635 
00636     osg::ref_ptr< osg::Material > matX = new osg::Material();
00637     matX->setDiffuse( osg::Material::FRONT, WColor( 1.0, 0.0, 0.0, 1.0 ) );
00638     cylinderX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON );
00639     coneX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON );
00640 
00641     // Y
00642     osg::ref_ptr< osg::ShapeDrawable > cylinderY = new osg::ShapeDrawable( new osg::Cylinder(
00643         middle, 1, sizeY + ( sizeY * 0.5 )
00644     ) );
00645     osg::ref_ptr< osg::ShapeDrawable > cylinderYEnd = new osg::ShapeDrawable( new osg::Cylinder(
00646         osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 1.0, 1.0
00647     ) );
00648     osg::ref_ptr< osg::ShapeDrawable > coneY = new osg::ShapeDrawable( new osg::Cone(
00649         osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 2.0, 5.0
00650     ) );
00651     cylinderYEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00652 
00653     graphYCylinder->addDrawable( cylinderY );
00654     graphY->addDrawable( coneY );
00655     graphY->addDrawable( cylinderYEnd );
00656 
00657     osg::ref_ptr< osg::Material > matY = new osg::Material();
00658     matY->setDiffuse( osg::Material::FRONT, WColor( 0.0, 1.0, 0.0, 1.0 ) );
00659     cylinderY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON );
00660     coneY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON );
00661 
00662 
00663     // Z
00664     osg::ref_ptr< osg::ShapeDrawable > cylinderZ = new osg::ShapeDrawable( new osg::Cylinder(
00665         middle, 1, sizeZ + ( sizeZ * 0.5 )
00666     ) );
00667     osg::ref_ptr< osg::ShapeDrawable > cylinderZEnd = new osg::ShapeDrawable( new osg::Cylinder(
00668         osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 1.0, 1.0
00669     ) );
00670     osg::ref_ptr< osg::ShapeDrawable > coneZ = new osg::ShapeDrawable( new osg::Cone(
00671         osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 2.0, 5.0
00672     ) );
00673     cylinderZEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00674 
00675     graphZCylinder->addDrawable( cylinderZ );
00676     graphZ->addDrawable( coneZ );
00677     graphZ->addDrawable( cylinderZEnd );
00678 
00679     osg::ref_ptr< osg::Material > matZ = new osg::Material();
00680     matZ->setDiffuse( osg::Material::FRONT, WColor( 0.0, 0.0, 1.0, 1.0 ) );
00681     cylinderZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON );
00682     coneZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON );
00683 
00684     shaderCoordinateSystem->apply( graphXCylinder );
00685     shaderCoordinateSystem->apply( graphYCylinder );
00686     shaderCoordinateSystem->apply( graphZCylinder );
00687 
00688     osg::ref_ptr< WGELabel > graphXLabel = new WGELabel();
00689     graphXLabel->setText( "X" );
00690     graphXLabel->setCharacterSize( 10 );
00691     graphXLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 + 5.0 ) );
00692     graphXLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00693     graphX->addDrawable( graphXLabel );
00694 
00695     osg::ref_ptr< WGELabel > graphYLabel = new WGELabel();
00696     graphYLabel->setText( "Y" );
00697     graphYLabel->setCharacterSize( 10 );
00698     graphYLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 + 5.0 ) );
00699     graphYLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00700     graphY->addDrawable( graphYLabel );
00701 
00702     osg::ref_ptr< WGELabel > graphZLabel = new WGELabel();
00703     graphZLabel->setText( "Z" );
00704     graphZLabel->setCharacterSize( 10 );
00705     graphZLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 + 5.0 ) );
00706     graphZLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00707     graphZ->addDrawable( graphZLabel );
00708 
00709 
00710     osg::ref_ptr< osg::MatrixTransform > graphXTransform = new osg::MatrixTransform();
00711     graphXTransform->addChild( graphX );
00712     graphXTransform->addChild( graphXCylinder );
00713     osg::ref_ptr< osg::MatrixTransform > graphYTransform = new osg::MatrixTransform();
00714     graphYTransform->addChild( graphY );
00715     graphYTransform->addChild( graphYCylinder );
00716     osg::ref_ptr< osg::MatrixTransform > graphZTransform = new osg::MatrixTransform();
00717     graphZTransform->addChild( graphZ );
00718     graphZTransform->addChild( graphZCylinder );
00719 
00720     osg::Matrixd matrixTranslateTo0 = osg::Matrixd::translate( -middle.x(), -middle.y(), -middle.z() );
00721     osg::Matrixd matrixTranslateFrom0 = osg::Matrixd::translate( middle.x(), middle.y(), middle.z() );
00722 
00723     graphXTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate(
00724         90.0 * piDouble / 180.0,
00725         osg::Vec3f( 0.0, 1.0, 0.0 ) ) * matrixTranslateFrom0
00726     );
00727     graphYTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate(
00728         -90.0 * piDouble / 180.0,
00729         osg::Vec3f( 1.0, 0.0, 0.0 ) ) * matrixTranslateFrom0
00730     );
00731 
00732     groupNode->insert( graphXTransform );
00733     groupNode->insert( graphYTransform );
00734     groupNode->insert( graphZTransform );
00735 
00736     return groupNode;
00737 }