OpenWalnut 1.3.1
WGEBorderLayout.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 <osgText/Text>
00026 #include <osg/LineWidth>
00027 #include <osg/Geometry>
00028 
00029 #include "../../WGraphicsEngine.h"
00030 
00031 #include "WGEBorderLayout.h"
00032 
00033 WGEBorderLayout::WGEBorderLayout():
00034     WGEGroupNode(),
00035     m_geode( new osg::Geode() ),
00036     m_lineGeode( new osg::Geode() ),
00037     m_screen( new osg::Projection() )
00038 
00039 {
00040     // initialize members
00041     osg::ref_ptr< osg::MatrixTransform > matrix = new osg::MatrixTransform();
00042     setDataVariance( osg::Object::DYNAMIC );
00043     matrix->setMatrix( osg::Matrix::identity() );
00044     matrix->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
00045     matrix->addChild( m_geode );
00046     matrix->addChild( m_lineGeode );
00047     m_screen->addChild( matrix );
00048     insert( m_screen );
00049 
00050     m_geode->setDataVariance( osg::Object::DYNAMIC );
00051     m_lineGeode->setDataVariance( osg::Object::DYNAMIC );
00052     m_screen->setDataVariance( osg::Object::DYNAMIC );
00053 
00054     addUpdateCallback( new SafeUpdateCallback( this ) );
00055 
00056     // ensure it is drawn the last
00057     getOrCreateStateSet()->setRenderBinDetails( 11, "RenderBin" );
00058     getOrCreateStateSet()->setDataVariance( osg::Object::DYNAMIC );
00059     getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
00060     getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00061 }
00062 
00063 WGEBorderLayout::~WGEBorderLayout()
00064 {
00065     // cleanup
00066 }
00067 
00068 void WGEBorderLayout::addLayoutable( osg::ref_ptr< WGELabel > obj )
00069 {
00070     m_geode->addDrawable( obj );
00071 }
00072 
00073 void WGEBorderLayout::SafeUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
00074 {
00075     osg::ref_ptr<osg::Camera> cam = WGraphicsEngine::getGraphicsEngine()->getViewer()->getCamera();
00076 
00077     // set up projection
00078     unsigned int  vwidth = cam->getViewport()->width();
00079     unsigned int  vheight = cam->getViewport()->height();
00080     m_layouter->m_screen->setMatrix( osg::Matrix::ortho2D( 0, vwidth, 0, vheight ) );
00081 
00082     // the geometry for the lead lines
00083     osg::ref_ptr< osg::Vec3Array > v = new osg::Vec3Array;
00084 
00085     for( unsigned int i = 0; i < m_layouter->m_geode->getNumDrawables(); ++i )
00086     {
00087         // each drawable is a WGELabel:
00088         osg::ref_ptr< WGELabel > t = static_cast< WGELabel* >( m_layouter->m_geode->getDrawable( i ) );
00089 
00090         // get anchor position in screen space for this item
00091         osg::Vec4 anchor = osg::Vec4( t->getAnchor(), 1.0 );
00092         osg::Matrixd projection = cam->getProjectionMatrix();
00093         osg::Matrixd view = cam->getViewMatrix();
00094         osg::Matrixd window = cam->getViewport()->computeWindowMatrix();
00095         osg::Vec4 anchorScreen = anchor * view * projection * window;
00096 
00097         // is the anchor on this or the other side of the screen?
00098         //int b = static_cast< int >( anchorScreen.y() / vheight * 10.0  ) % 10;
00099 
00100         // draw a line
00101         osg::Vec3 leadPos;
00102 
00103         if( anchorScreen.x() >= vwidth / 2 )
00104         {
00105             leadPos = osg::Vec3( vwidth - 10.0, anchorScreen.y(), 0.0 );
00106 
00107             t->setPosition( osg::Vec3( vwidth - 10.0, anchorScreen.y() + 5, 0.0 ) );
00108             t->setAlignment( osgText::Text::RIGHT_BOTTOM );
00109         }
00110         else
00111         {
00112             leadPos = osg::Vec3( 10.0, anchorScreen.y(), 0.0 );
00113 
00114             t->setPosition( osg::Vec3( 10.0, anchorScreen.y() + 5, 0.0 ) );
00115             t->setAlignment( osgText::Text::LEFT_BOTTOM );
00116         }
00117 
00118         v->push_back( leadPos );
00119         v->push_back( osg::Vec3( anchorScreen.x(), anchorScreen.y(), anchorScreen.z() ) );
00120     }
00121 
00122     // create geometry for the lines calculated above
00123     osg::ref_ptr< osg::Geometry > g = new osg::Geometry;
00124     g->setDataVariance( osg::Object::DYNAMIC );
00125     osg::ref_ptr< osg::DrawArrays > da = new osg::DrawArrays( osg::PrimitiveSet::LINES, 0, v->size() );
00126     g->setVertexArray( v );
00127     osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array;
00128     colors->push_back( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
00129     g->setColorArray( colors );
00130     g->setColorBinding( osg::Geometry::BIND_OVERALL );
00131     g->addPrimitiveSet( da );
00132 
00133     osg::LineWidth* linewidth = new osg::LineWidth();
00134     linewidth->setWidth( 2.0f );
00135     g->getOrCreateStateSet()->setAttributeAndModes( linewidth, osg::StateAttribute::ON );
00136 
00137     // remove all previous drawables and insert new
00138     m_layouter->m_lineGeode->removeDrawables( 0, m_layouter->m_lineGeode->getNumDrawables() );
00139     m_layouter->m_lineGeode->addDrawable( g );
00140 
00141     traverse( node, nv );
00142 }
00143