OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WGEBorderLayout.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <osgText/Text>
26 #include <osg/LineWidth>
27 
28 #include "../../WGraphicsEngine.h"
29 
30 #include "WGEBorderLayout.h"
31 
33  WGEGroupNode(),
34  m_geode( new osg::Geode() ),
35  m_lineGeode( new osg::Geode() ),
36  m_screen( new osg::Projection() )
37 
38 {
39  // initialize members
40  osg::ref_ptr< osg::MatrixTransform > matrix = new osg::MatrixTransform();
41  setDataVariance( osg::Object::DYNAMIC );
42  matrix->setMatrix( osg::Matrix::identity() );
43  matrix->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
44  matrix->addChild( m_geode );
45  matrix->addChild( m_lineGeode );
46  m_screen->addChild( matrix );
47  insert( m_screen );
48 
49  m_geode->setDataVariance( osg::Object::DYNAMIC );
50  m_lineGeode->setDataVariance( osg::Object::DYNAMIC );
51  m_screen->setDataVariance( osg::Object::DYNAMIC );
52 
53  addUpdateCallback( new SafeUpdateCallback( this ) );
54 
55  // ensure it is drawn the last
56  getOrCreateStateSet()->setRenderBinDetails( 11, "RenderBin" );
57  getOrCreateStateSet()->setDataVariance( osg::Object::DYNAMIC );
58  getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
59  getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
60 }
61 
63 {
64  // cleanup
65 }
66 
67 void WGEBorderLayout::addLayoutable( osg::ref_ptr< WGELabel > obj )
68 {
69  m_geode->addDrawable( obj );
70 }
71 
72 void WGEBorderLayout::SafeUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
73 {
74  osg::ref_ptr<osg::Camera> cam = WGraphicsEngine::getGraphicsEngine()->getViewer()->getCamera();
75 
76  // set up projection
77  unsigned int vwidth = cam->getViewport()->width();
78  unsigned int vheight = cam->getViewport()->height();
79  m_layouter->m_screen->setMatrix( osg::Matrix::ortho2D( 0, vwidth, 0, vheight ) );
80 
81  // the geometry for the lead lines
82  osg::ref_ptr< osg::Vec3Array > v = new osg::Vec3Array;
83 
84  for( unsigned int i = 0; i < m_layouter->m_geode->getNumDrawables(); ++i )
85  {
86  // each drawable is a WGELabel:
87  osg::ref_ptr< WGELabel > t = static_cast< WGELabel* >( m_layouter->m_geode->getDrawable( i ) );
88 
89  // get anchor position in screen space for this item
90  osg::Vec4 anchor = osg::Vec4( t->getAnchor(), 1.0 );
91  osg::Matrixd projection = cam->getProjectionMatrix();
92  osg::Matrixd view = cam->getViewMatrix();
93  osg::Matrixd window = cam->getViewport()->computeWindowMatrix();
94  osg::Vec4 anchorScreen = anchor * view * projection * window;
95 
96  // is the anchor on this or the other side of the screen?
97  //int b = static_cast< int >( anchorScreen.y() / vheight * 10.0 ) % 10;
98 
99  // draw a line
100  osg::Vec3 leadPos;
101 
102  if( anchorScreen.x() >= vwidth / 2 )
103  {
104  leadPos = osg::Vec3( vwidth - 10.0, anchorScreen.y(), 0.0 );
105 
106  t->setPosition( osg::Vec3( vwidth - 10.0, anchorScreen.y() + 5, 0.0 ) );
107  t->setAlignment( osgText::Text::RIGHT_BOTTOM );
108  }
109  else
110  {
111  leadPos = osg::Vec3( 10.0, anchorScreen.y(), 0.0 );
112 
113  t->setPosition( osg::Vec3( 10.0, anchorScreen.y() + 5, 0.0 ) );
114  t->setAlignment( osgText::Text::LEFT_BOTTOM );
115  }
116 
117  v->push_back( leadPos );
118  v->push_back( osg::Vec3( anchorScreen.x(), anchorScreen.y(), anchorScreen.z() ) );
119  }
120 
121  // create geometry for the lines calculated above
122  osg::ref_ptr< osg::Geometry > g = new osg::Geometry;
123  g->setDataVariance( osg::Object::DYNAMIC );
124  osg::ref_ptr< osg::DrawArrays > da = new osg::DrawArrays( osg::PrimitiveSet::LINES, 0, v->size() );
125  g->setVertexArray( v );
126  osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array;
127  colors->push_back( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
128  g->setColorArray( colors );
129  g->setColorBinding( osg::Geometry::BIND_OVERALL );
130  g->addPrimitiveSet( da );
131 
132  osg::LineWidth* linewidth = new osg::LineWidth();
133  linewidth->setWidth( 2.0f );
134  g->getOrCreateStateSet()->setAttributeAndModes( linewidth, osg::StateAttribute::ON );
135 
136  // remove all previous drawables and insert new
137  m_layouter->m_lineGeode->removeDrawables( 0, m_layouter->m_lineGeode->getNumDrawables() );
138  m_layouter->m_lineGeode->addDrawable( g );
139 
140  traverse( node, nv );
141 }
142