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