OpenWalnut  1.3.1
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 #include <osg/Geometry>
28 
29 #include "../../WGraphicsEngine.h"
30 
31 #include "WGEBorderLayout.h"
32 
34  WGEGroupNode(),
35  m_geode( new osg::Geode() ),
36  m_lineGeode( new osg::Geode() ),
37  m_screen( new osg::Projection() )
38 
39 {
40  // initialize members
41  osg::ref_ptr< osg::MatrixTransform > matrix = new osg::MatrixTransform();
42  setDataVariance( osg::Object::DYNAMIC );
43  matrix->setMatrix( osg::Matrix::identity() );
44  matrix->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
45  matrix->addChild( m_geode );
46  matrix->addChild( m_lineGeode );
47  m_screen->addChild( matrix );
48  insert( m_screen );
49 
50  m_geode->setDataVariance( osg::Object::DYNAMIC );
51  m_lineGeode->setDataVariance( osg::Object::DYNAMIC );
52  m_screen->setDataVariance( osg::Object::DYNAMIC );
53 
54  addUpdateCallback( new SafeUpdateCallback( this ) );
55 
56  // ensure it is drawn the last
57  getOrCreateStateSet()->setRenderBinDetails( 11, "RenderBin" );
58  getOrCreateStateSet()->setDataVariance( osg::Object::DYNAMIC );
59  getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
60  getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
61 }
62 
64 {
65  // cleanup
66 }
67 
68 void WGEBorderLayout::addLayoutable( osg::ref_ptr< WGELabel > obj )
69 {
70  m_geode->addDrawable( obj );
71 }
72 
73 void WGEBorderLayout::SafeUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
74 {
75  osg::ref_ptr<osg::Camera> cam = WGraphicsEngine::getGraphicsEngine()->getViewer()->getCamera();
76 
77  // set up projection
78  unsigned int vwidth = cam->getViewport()->width();
79  unsigned int vheight = cam->getViewport()->height();
80  m_layouter->m_screen->setMatrix( osg::Matrix::ortho2D( 0, vwidth, 0, vheight ) );
81 
82  // the geometry for the lead lines
83  osg::ref_ptr< osg::Vec3Array > v = new osg::Vec3Array;
84 
85  for( unsigned int i = 0; i < m_layouter->m_geode->getNumDrawables(); ++i )
86  {
87  // each drawable is a WGELabel:
88  osg::ref_ptr< WGELabel > t = static_cast< WGELabel* >( m_layouter->m_geode->getDrawable( i ) );
89 
90  // get anchor position in screen space for this item
91  osg::Vec4 anchor = osg::Vec4( t->getAnchor(), 1.0 );
92  osg::Matrixd projection = cam->getProjectionMatrix();
93  osg::Matrixd view = cam->getViewMatrix();
94  osg::Matrixd window = cam->getViewport()->computeWindowMatrix();
95  osg::Vec4 anchorScreen = anchor * view * projection * window;
96 
97  // is the anchor on this or the other side of the screen?
98  //int b = static_cast< int >( anchorScreen.y() / vheight * 10.0 ) % 10;
99 
100  // draw a line
101  osg::Vec3 leadPos;
102 
103  if( anchorScreen.x() >= vwidth / 2 )
104  {
105  leadPos = osg::Vec3( vwidth - 10.0, anchorScreen.y(), 0.0 );
106 
107  t->setPosition( osg::Vec3( vwidth - 10.0, anchorScreen.y() + 5, 0.0 ) );
108  t->setAlignment( osgText::Text::RIGHT_BOTTOM );
109  }
110  else
111  {
112  leadPos = osg::Vec3( 10.0, anchorScreen.y(), 0.0 );
113 
114  t->setPosition( osg::Vec3( 10.0, anchorScreen.y() + 5, 0.0 ) );
115  t->setAlignment( osgText::Text::LEFT_BOTTOM );
116  }
117 
118  v->push_back( leadPos );
119  v->push_back( osg::Vec3( anchorScreen.x(), anchorScreen.y(), anchorScreen.z() ) );
120  }
121 
122  // create geometry for the lines calculated above
123  osg::ref_ptr< osg::Geometry > g = new osg::Geometry;
124  g->setDataVariance( osg::Object::DYNAMIC );
125  osg::ref_ptr< osg::DrawArrays > da = new osg::DrawArrays( osg::PrimitiveSet::LINES, 0, v->size() );
126  g->setVertexArray( v );
127  osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array;
128  colors->push_back( osg::Vec4( 0.0f, 0.0f, 0.0f, 1.0f ) );
129  g->setColorArray( colors );
130  g->setColorBinding( osg::Geometry::BIND_OVERALL );
131  g->addPrimitiveSet( da );
132 
133  osg::LineWidth* linewidth = new osg::LineWidth();
134  linewidth->setWidth( 2.0f );
135  g->getOrCreateStateSet()->setAttributeAndModes( linewidth, osg::StateAttribute::ON );
136 
137  // remove all previous drawables and insert new
138  m_layouter->m_lineGeode->removeDrawables( 0, m_layouter->m_lineGeode->getNumDrawables() );
139  m_layouter->m_lineGeode->addDrawable( g );
140 
141  traverse( node, nv );
142 }
143