Equalizer  1.8.0
Parallel Rendering Framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
eVolve/config.cpp
1 
2 /* Copyright (c) 2006-2013, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2007-2011, Maxim Makhinya <maxmah@gmail.com>
4  * 2012, Daniel Nachbaur <danielnachbaur@gmail.com>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * - Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * - Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  * - Neither the name of Eyescale Software GmbH nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 
33 
34 namespace eVolve
35 {
36 
37 Config::Config( eq::ServerPtr parent )
38  : eq::Config( parent )
39  , _spinX( 5 )
40  , _spinY( 5 )
41  , _currentCanvas( 0 )
42  , _messageTime( 0 ){}
43 
45 
47 {
48  // init distributed objects
49  LBCHECK( registerObject( &_frameData ));
50 
51  _frameData.setOrtho( _initData.getOrtho( ));
52  _initData.setFrameDataID( _frameData.getID( ));
53 
54  _frameData.setAutoObsolete( getLatency( ));
55 
56  LBCHECK( registerObject( &_initData ));
57 
58  // init config
59  if( !eq::Config::init( _initData.getID( )))
60  {
61  _deregisterData();
62  return false;
63  }
64 
65  const eq::Canvases& canvases = getCanvases();
66  if( canvases.empty( ))
67  _currentCanvas = 0;
68  else
69  _currentCanvas = canvases.front();
70 
71  _setMessage( "Welcome to eVolve\nPress F1 for help" );
72 
73  return true;
74 }
75 
76 bool Config::loadInitData( const eq::uint128_t& id )
77 {
78  LBASSERT( !_initData.isAttached( ));
79  return getClient()->syncObject( &_initData, getApplicationNode(), id );
80 }
81 
83 {
84  const bool ret = eq::Config::exit();
85  _deregisterData();
86 
87  return ret;
88 }
89 
90 void Config::_deregisterData()
91 {
92  deregisterObject( &_initData );
93  deregisterObject( &_frameData );
94 
95  _initData.setFrameDataID( co::uint128_t( ));
96 }
97 
98 
100 {
101  // update database
102  _frameData.spinCamera( -0.001f * _spinX, -0.001f * _spinY );
103  const eq::uint128_t& version = _frameData.commit();
104 
105  _resetMessage();
106 
107  return eq::Config::startFrame( version );
108 }
109 
110 void Config::_resetMessage()
111 {
112  // reset message after two seconds
113  if( _messageTime > 0 && getTime() - _messageTime > 2000 )
114  {
115  _messageTime = 0;
116  _frameData.setMessage( "" );
117  }
118 }
119 
121 {
122  switch( event->data.type )
123  {
124  case eq::Event::KEY_PRESS:
125  if( _handleKeyEvent( event->data.keyPress ))
126  return true;
127  break;
128 
129  case eq::Event::CHANNEL_POINTER_BUTTON_PRESS:
130  {
131  const eq::uint128_t& viewID = event->data.context.view.identifier;
132  _frameData.setCurrentViewID( viewID );
133  if( viewID == 0 )
134  {
135  _currentCanvas = 0;
136  return true;
137  }
138 
139  const eq::View* view = find< eq::View >( viewID );
140  const eq::Layout* layout = view->getLayout();
141  const eq::Canvases& canvases = getCanvases();
142  for( eq::Canvases::const_iterator i = canvases.begin();
143  i != canvases.end(); ++i )
144  {
145  eq::Canvas* canvas = *i;
146  const eq::Layout* canvasLayout = canvas->getActiveLayout();
147 
148  if( canvasLayout == layout )
149  {
150  _currentCanvas = canvas;
151  return true;
152  }
153  }
154  return true;
155  }
156 
157  case eq::Event::CHANNEL_POINTER_BUTTON_RELEASE:
158  if( event->data.pointerButtonRelease.buttons == eq::PTR_BUTTON_NONE
159  && event->data.pointerButtonRelease.button == eq::PTR_BUTTON1 )
160  {
161  _spinY = event->data.pointerButtonRelease.dx;
162  _spinX = event->data.pointerButtonRelease.dy;
163  }
164  return true;
165 
166  case eq::Event::CHANNEL_POINTER_MOTION:
167  if( event->data.pointerMotion.buttons == eq::PTR_BUTTON1 )
168  {
169  _spinX = 0;
170  _spinY = 0;
171 
172  _frameData.spinCamera( -0.005f * event->data.pointerMotion.dy,
173  -0.005f * event->data.pointerMotion.dx);
174  return true;
175  }
176  if( event->data.pointerMotion.buttons == eq::PTR_BUTTON2 ||
177  event->data.pointerMotion.buttons == ( eq::PTR_BUTTON1 |
178  eq::PTR_BUTTON3 ))
179  {
180  _frameData.moveCamera( .0, .0,
181  .005f*event->data.pointerMotion.dy );
182  return true;
183  }
184  if( event->data.pointerMotion.buttons == eq::PTR_BUTTON3 )
185  {
186  _frameData.moveCamera( .0005f * event->data.pointerMotion.dx,
187  -.0005f * event->data.pointerMotion.dy,
188  .0f );
189  return true;
190  }
191  break;
192 
193  default:
194  break;
195  }
196  return eq::Config::handleEvent( event );
197 }
198 
199 bool Config::_handleKeyEvent( const eq::KeyEvent& event )
200 {
201  switch( event.key )
202  {
203  case 'b':
204  case 'B':
205  _frameData.toggleBackground();
206  return true;
207 
208  case 'd':
209  case 'D':
210  _frameData.toggleColorMode();
211  return true;
212 
213  case eq::KC_F1:
214  case 'h':
215  case 'H':
216  _frameData.toggleHelp();
217  return true;
218 
219  case 'r':
220  case 'R':
221  case ' ':
222  _spinX = 0;
223  _spinY = 0;
224  _frameData.reset();
225  return true;
226 
227  case 'n':
228  case 'N':
229  _frameData.toggleNormalsQuality();
230  return true;
231 
232  case 'o':
233  case 'O':
234  _frameData.toggleOrtho();
235  return true;
236 
237  case 's':
238  case 'S':
239  _frameData.toggleStatistics();
240  return true;
241 
242  case 'l':
243  _switchLayout( 1 );
244  return true;
245  case 'L':
246  _switchLayout( -1 );
247  return true;
248 
249  case 'q':
250  _frameData.adjustQuality( -.1f );
251  return true;
252 
253  case 'Q':
254  _frameData.adjustQuality( .1f );
255  return true;
256 
257  case 'c':
258  case 'C':
259  {
260  const eq::Canvases& canvases = getCanvases();
261  if( canvases.empty( ))
262  return true;
263 
264  _frameData.setCurrentViewID( co::uint128_t( ));
265 
266  if( !_currentCanvas )
267  {
268  _currentCanvas = canvases.front();
269  return true;
270  }
271 
272  eq::Canvases::const_iterator i = std::find( canvases.begin(),
273  canvases.end(),
274  _currentCanvas );
275  LBASSERT( i != canvases.end( ));
276 
277  ++i;
278  if( i == canvases.end( ))
279  _currentCanvas = canvases.front();
280  else
281  _currentCanvas = *i;
282  return true;
283  }
284 
285  case 'v':
286  case 'V':
287  {
288  const eq::Canvases& canvases = getCanvases();
289  if( !_currentCanvas && !canvases.empty( ))
290  _currentCanvas = canvases.front();
291 
292  if( !_currentCanvas )
293  return true;
294 
295  const eq::Layout* layout = _currentCanvas->getActiveLayout();
296  if( !layout )
297  return true;
298 
299  const eq::View* current =
300  find< eq::View >( _frameData.getCurrentViewID( ));
301 
302  const eq::Views& views = layout->getViews();
303  LBASSERT( !views.empty( ))
304 
305  if( !current )
306  {
307  _frameData.setCurrentViewID( views.front()->getID( ));
308  return true;
309  }
310 
311  eq::Views::const_iterator i = std::find( views.begin(),
312  views.end(),
313  current );
314  LBASSERT( i != views.end( ));
315 
316  ++i;
317  if( i == views.end( ))
318  _frameData.setCurrentViewID( co::uint128_t( ));
319  else
320  _frameData.setCurrentViewID( (*i)->getID( ));
321  return true;
322  }
323 
324  default:
325  break;
326  }
327  return false;
328 }
329 
330 void Config::_setMessage( const std::string& message )
331 {
332  _frameData.setMessage( message );
333  _messageTime = getTime();
334 }
335 
336 void Config::_switchLayout( int32_t increment )
337 {
338  if( !_currentCanvas )
339  return;
340 
341  _frameData.setCurrentViewID( co::uint128_t( ));
342 
343  size_t index = _currentCanvas->getActiveLayoutIndex() + increment;
344  const eq::Layouts& layouts = _currentCanvas->getLayouts();
345  LBASSERT( !layouts.empty( ));
346 
347  index = ( index % layouts.size( ));
348  _currentCanvas->useLayout( uint32_t( index ));
349 
350  const eq::Layout* layout = _currentCanvas->getActiveLayout();
351  std::ostringstream stream;
352  stream << "Layout ";
353  if( layout )
354  {
355  const std::string& name = layout->getName();
356  if( name.empty( ))
357  stream << index;
358  else
359  stream << name;
360  }
361  else
362  stream << "NONE";
363 
364  stream << " active";
365  _setMessage( stream.str( ));
366 }
367 
368 }
virtual EQ_API bool init(const uint128_t &initID)
Initialize this configuration.
A canvas represents a logical 2D projection surface.
Definition: client/canvas.h:50
virtual EQ_API bool exit()
Exit this configuration.
virtual bool handleEvent(const eq::ConfigEvent *event)
uint32_t getActiveLayoutIndex() const
Definition: fabric/canvas.h:54
virtual uint32_t startFrame()
const Layouts & getLayouts() const
Definition: fabric/canvas.h:69
virtual EQ_API uint32_t startFrame(const uint128_t &frameID)
Request a new frame of rendering.
EQ_API int64_t getTime() const
Get the current time in milliseconds.
std::vector< Layout * > Layouts
A vector of pointers to eq::Layout.
lunchbox::RefPtr< Server > ServerPtr
A reference-counted pointer to an eq::Server.
virtual bool init()
EQFABRIC_API const std::string & getName() const
virtual EQFABRIC_INL bool useLayout(const uint32_t index)
Activate the given layout on this canvas.
virtual bool exit()
EQFABRIC_INL const L * getActiveLayout() const
std::vector< View * > Views
A vector of pointers to eq::View.
bool loadInitData(const eq::uint128_t &initDataID)
Map per-config data to the local node process.
std::vector< Canvas * > Canvases
A vector of pointers to eq::Canvas.
A layout groups one or more View, logically belonging together.
Definition: client/layout.h:46
A View is a 2D area of a Layout.
EQ_API ClientPtr getClient()
virtual EQ_API bool registerObject(co::Object *object)
Register a distributed object.
EQ_API co::NodePtr getApplicationNode()
virtual ~Config()
Destruct a config.
virtual EQ_API bool handleEvent(const ConfigEvent *event)
Handle one (old) config event.
virtual EQ_API void deregisterObject(co::Object *object)
Deregister a distributed object.
const Views & getViews() const
Get the list of views.
Definition: fabric/layout.h:47