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