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