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