GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/window-manager.cpp Lines: 0 406 0.0 %
Date: 2024-04-14 11:13:22 Branches: 0 774 0.0 %

Line Branch Exec Source
1
//
2
//  window-manager.cpp
3
//  gepetto-viewer
4
//
5
//  Created by Justin Carpentier, Mathieu Geisert in November 2014.
6
//  Copyright (c) 2014 LAAS-CNRS. All rights reserved.
7
//
8
9
#include <gepetto/viewer/OSGManipulator/keyboard-manipulator.h>
10
#include <gepetto/viewer/window-manager.h>
11
12
#include <osg/Camera>
13
#include <osg/DisplaySettings>
14
#include <osgDB/WriteFile>
15
#include <osgGA/NodeTrackerManipulator>
16
#include <osgGA/TrackballManipulator>
17
#include <stdexcept>
18
19
#include "internal/configuration.hh"
20
#include "is-dirty-visitor.h"
21
#include "log.hh"
22
23
namespace gepetto {
24
namespace viewer {
25
namespace {
26
struct ScreenShot : public osg::Camera::DrawCallback {
27
  ScreenShot(const std::string& fn) : fn_(fn) {}
28
29
  virtual void operator()(osg::RenderInfo& renderInfo) const;
30
31
  std::string fn_;
32
};
33
34
void ScreenShot::operator()(osg::RenderInfo& renderInfo) const {
35
  osg::Timer* timer = osg::Timer::instance();
36
  osg::Timer_t tick_start = timer->tick();
37
38
  osg::ref_ptr<osg::Image> image = new osg::Image;
39
  assert(renderInfo.getState());
40
  osg::GraphicsContext* gc = renderInfo.getState()->getGraphicsContext();
41
  assert(gc);
42
43
  // glReadBuffer(GL_BACK);
44
  osg::Camera* camera = renderInfo.getCurrentCamera();
45
  camera->setReadBuffer(GL_BACK);
46
  // osg::Viewport* viewport = camera ? camera->getViewport() : 0;
47
  // image->readPixels(viewport->x(),viewport->y(),viewport->width(),viewport->height(),
48
  image->readPixels(0, 0, gc->getTraits()->width, gc->getTraits()->height,
49
                    GL_RGBA, GL_UNSIGNED_BYTE, 1);
50
51
  osgDB::writeImageFile(*image, fn_);
52
53
  bool res = osgDB::writeImageFile(*image, fn_);
54
  if (!res) {
55
    std::cerr << "Failed to write image " << fn_ << std::endl;
56
  } else {
57
    osg::Timer_t tick_end = timer->tick();
58
    log() << "Time to generate image " << fn_ << " = "
59
          << timer->delta_s(tick_start, tick_end) << " seconds" << std::endl;
60
  }
61
}
62
63
struct ResizeHandler : osgGA::GUIEventHandler {
64
  ResizeHandler(osg::Camera* camera) : camera_(camera) {}
65
66
  virtual bool handle(const osgGA::GUIEventAdapter& gea,
67
                      osgGA::GUIActionAdapter& /*gaa*/, osg::Object* /*obj*/,
68
                      osg::NodeVisitor* /*nv*/
69
  ) {
70
    osgGA::GUIEventAdapter::EventType ev = gea.getEventType();
71
72
    if (ev != osgGA::GUIEventAdapter::RESIZE) return false;
73
74
    float w = (float)gea.getWindowWidth();
75
    float h = (float)gea.getWindowHeight();
76
77
    if (camera_.valid())
78
      camera_->setProjectionMatrix(osg::Matrix::ortho2D(0.0f, w, 0.0f, h));
79
80
    float m = w * 0.01f;
81
82
    texts_[WindowManager::BOTTOM][WindowManager::LEFT]->setPosition(
83
        osgVector3(m, m, 0.f));
84
    texts_[WindowManager::BOTTOM][WindowManager::CENTER]->setPosition(
85
        osgVector3(w / 2, m, 0.f));
86
    texts_[WindowManager::BOTTOM][WindowManager::RIGHT]->setPosition(
87
        osgVector3(w - m, m, 0.f));
88
    texts_[WindowManager::CENTER][WindowManager::LEFT]->setPosition(
89
        osgVector3(m, h / 2, 0.f));
90
    texts_[WindowManager::CENTER][WindowManager::CENTER]->setPosition(
91
        osgVector3(w / 2, h / 2, 0.f));
92
    texts_[WindowManager::CENTER][WindowManager::RIGHT]->setPosition(
93
        osgVector3(w - m, h / 2, 0.f));
94
    texts_[WindowManager::TOP][WindowManager::LEFT]->setPosition(
95
        osgVector3(m, h - m, 0.f));
96
    texts_[WindowManager::TOP][WindowManager::CENTER]->setPosition(
97
        osgVector3(w / 2, h - m, 0.f));
98
    texts_[WindowManager::TOP][WindowManager::RIGHT]->setPosition(
99
        osgVector3(w - m, h - m, 0.f));
100
    return true;
101
  }
102
103
  osg::ref_ptr<osgText::Text> texts_[3][3];
104
  osg::observer_ptr<osg::Camera> camera_;
105
};
106
107
struct WriteToFile : osgViewer::ScreenCaptureHandler::CaptureOperation {
108
  WriteToFile(const std::string& filename, const std::string& extension)
109
      : basename(filename), ext(extension), counter(0) {}
110
111
  virtual void operator()(const osg::Image& image,
112
                          const unsigned int /*context_id*/) {
113
    std::stringstream filename;
114
    filename << basename << "_" << counter++ << '.' << ext;
115
116
    osgDB::writeImageFile(image, filename.str());
117
118
    OSG_INFO << "ScreenCaptureHandler: Taking a screenshot, saved as '"
119
             << filename.str() << "'" << std::endl;
120
  }
121
122
  const std::string basename;
123
  const std::string ext;
124
  unsigned int counter;
125
};
126
}  // namespace
127
128
void WindowManager::createManipulator() {
129
  osgViewer::Viewer::Windows windows;
130
  viewer_ptr_->getWindows(windows);
131
  manipulator_ptr = new ::osgGA::KeySwitchMatrixManipulator;
132
  manipulator_ptr->addMatrixManipulator('1', "trackball",
133
                                        new ::osgGA::TrackballManipulator);
134
  if (windows.empty()) {
135
    throw std::runtime_error(
136
        "Failed to create a window. This might be due to "
137
        "incorrect GPU driver installation or hardware issue.");
138
  }
139
  manipulator_ptr->addMatrixManipulator(
140
      '2', "keyboard", new ::osgGA::KeyboardManipulator(windows.front()));
141
  manipulator_ptr->addMatrixManipulator('3', "tracker",
142
                                        new ::osgGA::NodeTrackerManipulator);
143
  viewer_ptr_->setCameraManipulator(manipulator_ptr);
144
}
145
146
void WindowManager::createBackground() {
147
  // Enable Outline highlight state.
148
  main_camera_->setCullMask(VisibilityBit);
149
  main_camera_->setClearMask(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
150
  main_camera_->setClearColor(osg::Vec4(0., 0., 0., 0.));
151
  // Create background camera
152
  bg_camera_ = new osg::Camera;
153
  bg_camera_->setName("bg_camera");
154
  bg_camera_->setCullMask(VisibilityBit);
155
  const osg::Node::NodeMask mask = ~IntersectionBit;
156
  bg_camera_->setNodeMask(mask);
157
158
  osg::ref_ptr<const osg::GraphicsContext::Traits> traits_ptr =
159
      gc_->getTraits();
160
161
  // set the projection matrix
162
  bg_camera_->setProjectionMatrix(osg::Matrix::ortho2D(
163
      traits_ptr->x, traits_ptr->width, traits_ptr->y, traits_ptr->height));
164
165
  bg_camera_->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
166
  bg_camera_->setViewMatrix(osg::Matrix::identity());
167
168
  // only clear the depth buffer
169
  //      bg_camera_->setClearMask(GL_DEPTH_BUFFER_BIT);
170
  bg_camera_->setClearColor(osg::Vec4(0., 0., 0., 0.));
171
172
  // draw subgraph before main camera view.
173
  bg_camera_->setRenderOrder(osg::Camera::PRE_RENDER);
174
  bg_camera_->setCullingActive(false);
175
  bg_camera_->setAllowEventFocus(false);
176
177
  bg_color1_ = osg::Vec4(0.4f, 0.4f, 0.6f, 1.0f);
178
  bg_color2_ = osg::Vec4(0.6f, 0.6f, 0.6f, 1.0f);
179
180
  // Create the background geometry here
181
  {
182
    osg::Geode* geode = new osg::Geode();
183
    geode->setName("background");
184
    osg::StateSet* stateset = geode->getOrCreateStateSet();
185
    stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
186
187
    bg_geom_ = new osg::Geometry;
188
189
    const float depth = (float)-0.1;
190
    osg::Vec3Array* vertices = new osg::Vec3Array;
191
    vertices->push_back(osg::Vec3(0., (float)traits_ptr->height, depth));
192
    vertices->push_back(osg::Vec3(0., 0., depth));
193
    vertices->push_back(osg::Vec3((float)traits_ptr->width, 0., depth));
194
    vertices->push_back(
195
        osg::Vec3((float)traits_ptr->width, (float)traits_ptr->height, depth));
196
    bg_geom_->setVertexArray(vertices);
197
198
    osg::Vec3Array* normals = new osg::Vec3Array;
199
    normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
200
    bg_geom_->setNormalArray(normals, osg::Array::BIND_OVERALL);
201
202
    applyBackgroundColor();
203
204
    bg_geom_->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
205
206
    stateset = bg_geom_->getOrCreateStateSet();
207
    stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
208
    stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
209
210
    geode->addDrawable(bg_geom_);
211
    bg_camera_->addChild(geode);
212
213
    bg_geom_->setDataVariance(osg::Object::STATIC);
214
    bg_camera_->setDataVariance(osg::Object::STATIC);
215
    geode->setDataVariance(osg::Object::STATIC);
216
    // bg_camera_->setGraphicsContext(camera->getGraphicsContext());
217
  }
218
219
  asGroup()->addChild(bg_camera_);
220
}
221
222
void WindowManager::createHUDcamera() {
223
  // Create HUD camera
224
  osg::ref_ptr<const osg::GraphicsContext::Traits> traits_ptr =
225
      gc_->getTraits();
226
227
  hud_camera_ = new osg::Camera;
228
  hud_camera_->setName("hud_camera");
229
  const osg::Node::NodeMask mask = ~IntersectionBit;
230
  hud_camera_->setNodeMask(mask);
231
232
  hud_camera_->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
233
  hud_camera_->setClearMask(GL_DEPTH_BUFFER_BIT);
234
  hud_camera_->setRenderOrder(osg::Camera::POST_RENDER);
235
  hud_camera_->setAllowEventFocus(false);
236
  hud_camera_->setProjectionMatrix(osg::Matrix::ortho2D(
237
      traits_ptr->x, traits_ptr->width, traits_ptr->y, traits_ptr->height));
238
  hud_camera_->getOrCreateStateSet()->setMode(GL_LIGHTING,
239
                                              osg::StateAttribute::OFF);
240
241
  textGeode_ = new osg::Geode;
242
  hud_camera_->addChild(textGeode_);
243
244
  ResizeHandler* rh = new ResizeHandler(hud_camera_);
245
  static osg::ref_ptr<osgText::Font> font = defaultFont();
246
  for (int i = 0; i < 3; ++i)
247
    for (int j = 0; j < 3; ++j) {
248
      osg::ref_ptr<osgText::Text>& text = texts_[i][j];
249
      text = new osgText::Text;
250
      text->setAxisAlignment(osgText::TextBase::XY_PLANE);
251
      text->setDataVariance(osg::Object::DYNAMIC);
252
      text->setFont(font);
253
      switch (i) {
254
        case TOP:
255
          switch (j) {
256
            case LEFT:
257
              text->setAlignment(osgText::TextBase::LEFT_TOP);
258
              break;
259
            case CENTER:
260
              text->setAlignment(osgText::TextBase::CENTER_TOP);
261
              break;
262
            case RIGHT:
263
              text->setAlignment(osgText::TextBase::RIGHT_TOP);
264
              break;
265
          }
266
          break;
267
        case CENTER:
268
          switch (j) {
269
            case LEFT:
270
              text->setAlignment(osgText::TextBase::LEFT_CENTER);
271
              break;
272
            case CENTER:
273
              text->setAlignment(osgText::TextBase::CENTER_CENTER);
274
              break;
275
            case RIGHT:
276
              text->setAlignment(osgText::TextBase::RIGHT_CENTER);
277
              break;
278
          }
279
          break;
280
        case BOTTOM:
281
          switch (j) {
282
            case LEFT:
283
              text->setAlignment(osgText::TextBase::LEFT_BOTTOM);
284
              break;
285
            case CENTER:
286
              text->setAlignment(osgText::TextBase::CENTER_BOTTOM);
287
              break;
288
            case RIGHT:
289
              text->setAlignment(osgText::TextBase::RIGHT_BOTTOM);
290
              break;
291
          }
292
          break;
293
      }
294
295
      rh->texts_[i][j] = text;
296
      textActive_[i][j] = false;
297
    }
298
  viewer_ptr_->addEventHandler(rh);
299
300
  // Property to scene
301
  addProperty(StringProperty::create(
302
      "Text/TopLeft", boost::bind(&WindowManager::getText, this, TOP, LEFT),
303
      boost::bind(&WindowManager::setText, this, TOP, LEFT, _1, 20)));
304
  addProperty(StringProperty::create(
305
      "Text/TopCenter", boost::bind(&WindowManager::getText, this, TOP, CENTER),
306
      boost::bind(&WindowManager::setText, this, TOP, CENTER, _1, 20)));
307
  addProperty(StringProperty::create(
308
      "Text/TopRight", boost::bind(&WindowManager::getText, this, TOP, RIGHT),
309
      boost::bind(&WindowManager::setText, this, TOP, RIGHT, _1, 20)));
310
  addProperty(StringProperty::create(
311
      "Text/CenterLeft",
312
      boost::bind(&WindowManager::getText, this, CENTER, LEFT),
313
      boost::bind(&WindowManager::setText, this, CENTER, LEFT, _1, 20)));
314
  addProperty(StringProperty::create(
315
      "Text/CenterCenter",
316
      boost::bind(&WindowManager::getText, this, CENTER, CENTER),
317
      boost::bind(&WindowManager::setText, this, CENTER, CENTER, _1, 20)));
318
  addProperty(StringProperty::create(
319
      "Text/CenterRight",
320
      boost::bind(&WindowManager::getText, this, CENTER, RIGHT),
321
      boost::bind(&WindowManager::setText, this, CENTER, RIGHT, _1, 20)));
322
  addProperty(StringProperty::create(
323
      "Text/BottomLeft",
324
      boost::bind(&WindowManager::getText, this, BOTTOM, LEFT),
325
      boost::bind(&WindowManager::setText, this, BOTTOM, LEFT, _1, 20)));
326
  addProperty(StringProperty::create(
327
      "Text/BottomCenter",
328
      boost::bind(&WindowManager::getText, this, BOTTOM, CENTER),
329
      boost::bind(&WindowManager::setText, this, BOTTOM, CENTER, _1, 20)));
330
  addProperty(StringProperty::create(
331
      "Text/BottomRight",
332
      boost::bind(&WindowManager::getText, this, BOTTOM, RIGHT),
333
      boost::bind(&WindowManager::setText, this, BOTTOM, RIGHT, _1, 20)));
334
}
335
336
std::string WindowManager::getText(TextAlignment vPos,
337
                                   TextAlignment hPos) const {
338
  osg::ref_ptr<osgText::Text> text = texts_[vPos][hPos];
339
  if (!text)
340
    return std::string();
341
  else
342
    return text->getText().createUTF8EncodedString();
343
}
344
345
void WindowManager::setText(TextAlignment vPos, TextAlignment hPos,
346
                            const std::string& content, float size) {
347
  if (content.size() == 0) {
348
    textGeode_->removeDrawable(texts_[vPos][hPos]);
349
    textActive_[vPos][hPos] = false;
350
351
    for (int i = 0; i < 3; ++i)
352
      for (int j = 0; j < 3; ++j)
353
        if (textActive_[i][j]) return;
354
    asGroup()->removeChild(hud_camera_);
355
    setDirty();
356
    return;
357
  }
358
359
  osg::ref_ptr<osgText::Text>& text = texts_[vPos][hPos];
360
  if (!textActive_[vPos][hPos]) {
361
    textGeode_->addDrawable(text);
362
    textActive_[vPos][hPos] = true;
363
  }
364
  text->setCharacterSize(size);
365
  text->setText(content);
366
367
  if (!asGroup()->containsNode(hud_camera_)) {
368
    osg::Viewport* vp = viewer_ptr_->getCamera()->getViewport();
369
    viewer_ptr_->getEventQueue()->windowResize(
370
        (int)vp->x(), (int)vp->y(), (int)vp->width(), (int)vp->height());
371
372
    asGroup()->addChild(hud_camera_);
373
  }
374
  setDirty();
375
}
376
377
void WindowManager::applyBackgroundColor() {
378
  osg::Vec4Array* colors = new osg::Vec4Array;
379
  colors->push_back(bg_color1_);
380
  colors->push_back(bg_color2_);
381
  colors->push_back(bg_color2_);
382
  colors->push_back(bg_color1_);
383
  bg_geom_->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
384
}
385
386
void WindowManager::captureFrame(const std::string& filename) {
387
  osg::ref_ptr<ScreenShot> screenshot_ = new ScreenShot(filename);
388
  main_camera_->setFinalDrawCallback(screenshot_);
389
  viewer_ptr_->renderingTraversals();
390
  main_camera_->setFinalDrawCallback(0);
391
}
392
393
/* Declaration of private function members */
394
void WindowManager::init(const unsigned int& x, const unsigned int& y,
395
                         const unsigned int& width,
396
                         const unsigned int& height) {
397
  osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
398
  osg::TraitsRefPtr traits_ptr = new ::osg::GraphicsContext::Traits(ds);
399
400
  traits_ptr->windowName = "Gepetto Viewer";
401
  traits_ptr->x = x;
402
  traits_ptr->y = y;
403
  traits_ptr->width = width;
404
  traits_ptr->height = height;
405
  traits_ptr->windowDecoration = true;
406
  traits_ptr->doubleBuffer = true;
407
  traits_ptr->sharedContext = 0;
408
409
  traits_ptr->vsync = true;
410
  traits_ptr->readDISPLAY();
411
  traits_ptr->setUndefinedScreenDetailsToDefaultScreen();
412
413
  osg::ref_ptr<osg::GraphicsContext> gc =
414
      osg::GraphicsContext::createGraphicsContext(traits_ptr);
415
416
  init(gc.get());
417
}
418
419
void WindowManager::init(osg::GraphicsContext* gc) {
420
  ::osgViewer::ViewerRefPtr viewer = new ::osgViewer::Viewer();
421
422
  /* init main camera */
423
  ::osg::CameraRefPtr camera = viewer->getCamera();
424
  camera->setName("main_camera");
425
426
  const osg::GraphicsContext::Traits* traits_ptr = gc->getTraits();
427
  camera->setGraphicsContext(gc);
428
  camera->setViewport(
429
      new osg::Viewport(0, 0, traits_ptr->width, traits_ptr->height));
430
  camera->setProjectionMatrixAsPerspective(
431
      30.0f,
432
      static_cast<double>(traits_ptr->width) /
433
          static_cast<double>(traits_ptr->height),
434
      1.0f, 10000.0f);
435
  GLenum buffer = traits_ptr->doubleBuffer ? GL_BACK : GL_FRONT;
436
  camera->setDrawBuffer(buffer);
437
  camera->setReadBuffer(buffer);
438
439
  /* Disable small features culling */
440
  osg::CullStack::CullingMode cullingMode = camera->getCullingMode();
441
  cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING);
442
  camera->setCullingMode(cullingMode);
443
444
  /* avoid ending */
445
  viewer->setKeyEventSetsDone(0);
446
  viewer->addEventHandler(new osgViewer::HelpHandler);
447
448
  init(viewer, gc);
449
}
450
451
void WindowManager::init(osgViewer::Viewer* v, osg::GraphicsContext* gc) {
452
  setID(gc->getTraits()->windowName);
453
454
  viewer_ptr_ = v;
455
  viewer_ptr_->setSceneData(asGroup());
456
  lastSceneWasDisrty_ = true;
457
458
  /* init main camera */
459
  main_camera_ = viewer_ptr_->getCamera();
460
461
  // Enable Outline highlight state.
462
  main_camera_->setClearStencil(0);
463
  osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
464
  if (ds->getMinimumNumStencilBits() == 0) ds->setMinimumNumStencilBits(1);
465
466
  gc_ = osg::GraphicsContextRefPtr(gc);
467
  createBackground();
468
  createManipulator();
469
  createHUDcamera();
470
471
  main_camera_->setNearFarRatio(0.1);
472
473
  auto prop = RangedFloatProperty::create(
474
      "Camera/NearFarRatio",
475
      [this]() -> float { return (float)main_camera_->getNearFarRatio(); },
476
      [this](const float& ratio) { main_camera_->setNearFarRatio(ratio); });
477
  prop->setRange(0., 1., 0.05f);
478
  addProperty(prop);
479
}
480
481
WindowManager::WindowManager() : GroupNode(""), nodeTrackerManipulatorIndex(2) {
482
  init(0, 0, 600, 480);
483
}
484
485
WindowManager::WindowManager(osg::GraphicsContext* gc)
486
    : GroupNode(""), nodeTrackerManipulatorIndex(2) {
487
  init(gc);
488
}
489
490
WindowManager::WindowManager(osgViewer::Viewer* v, osg::GraphicsContext* gc)
491
    : GroupNode(""), nodeTrackerManipulatorIndex(2) {
492
  init(v, gc);
493
}
494
495
WindowManager::WindowManager(const unsigned int& x, const unsigned int& y,
496
                             const unsigned int& width,
497
                             const unsigned int& height)
498
    : GroupNode(""), nodeTrackerManipulatorIndex(2) {
499
  init(x, y, width, height);
500
}
501
502
WindowManager::WindowManager(const WindowManager& other)
503
    : GroupNode(other), nodeTrackerManipulatorIndex(2) {
504
  init(viewer_ptr_, gc_);
505
}
506
507
void WindowManager::initWeakPtr(WindowManagerWeakPtr other_weak_ptr) {
508
  weak_ptr_ = other_weak_ptr;
509
}
510
511
/* End declaration of private function members */
512
513
/* Declaration of protected function members */
514
515
WindowManagerPtr_t WindowManager::create() {
516
  WindowManagerPtr_t shared_ptr(new WindowManager());
517
518
  // Add reference to itself
519
  shared_ptr->initWeakPtr(shared_ptr);
520
521
  return shared_ptr;
522
}
523
524
WindowManagerPtr_t WindowManager::create(const unsigned int& x,
525
                                         const unsigned int& y,
526
                                         const unsigned int& width,
527
                                         const unsigned int& height) {
528
  WindowManagerPtr_t shared_ptr(new WindowManager(x, y, width, height));
529
530
  // Add reference to itself
531
  shared_ptr->initWeakPtr(shared_ptr);
532
533
  return shared_ptr;
534
}
535
536
WindowManagerPtr_t WindowManager::create(osg::GraphicsContext* gc) {
537
  WindowManagerPtr_t shared_ptr(new WindowManager(gc));
538
539
  // Add reference to itself
540
  shared_ptr->initWeakPtr(shared_ptr);
541
542
  return shared_ptr;
543
}
544
545
WindowManagerPtr_t WindowManager::create(osgViewer::Viewer* v,
546
                                         osg::GraphicsContext* gc) {
547
  WindowManagerPtr_t shared_ptr(new WindowManager(v, gc));
548
549
  // Add reference to itself
550
  shared_ptr->initWeakPtr(shared_ptr);
551
552
  return shared_ptr;
553
}
554
555
WindowManagerPtr_t WindowManager::createCopy(WindowManagerPtr_t other) {
556
  WindowManagerPtr_t shared_ptr(new WindowManager(*other));
557
558
  // Add reference to itself
559
  shared_ptr->initWeakPtr(shared_ptr);
560
561
  return shared_ptr;
562
}
563
564
/* End declaration of protected function members */
565
566
/* Declaration of public function members */
567
568
WindowManagerPtr_t WindowManager::clone(void) const {
569
  return WindowManager::createCopy(weak_ptr_.lock());
570
}
571
572
WindowManagerPtr_t WindowManager::self(void) const { return weak_ptr_.lock(); }
573
574
bool WindowManager::addNode(NodePtr_t graphical_object_ptr) {
575
  bool result = addChild(graphical_object_ptr);
576
  return result;
577
}
578
579
bool WindowManager::done() { return viewer_ptr_->done(); }
580
581
bool WindowManager::frame() {
582
  bool callFrame = screen_capture_ptr_;
583
  if (!callFrame) {
584
    IsDirtyVisitor isDirtyVisitor;
585
    accept(isDirtyVisitor);
586
    // FIXME For some reasons, when highlight state of a node is changed,
587
    // method frame must be called twice to get it rendered properly.
588
    // lastSceneWasDisrty_ forces to draw twice after a dirty scene.
589
    callFrame = lastSceneWasDisrty_ || isDirtyVisitor.isDirty() ||
590
                viewer_ptr_->checkNeedToDoFrame();
591
    lastSceneWasDisrty_ = isDirtyVisitor.isDirty();
592
  }
593
  if (callFrame)
594
    viewer_ptr_->frame();
595
  else
596
    return false;
597
598
  SetCleanVisitor setCleanVisitor;
599
  accept(setCleanVisitor);
600
  return true;
601
}
602
603
bool WindowManager::run() { return viewer_ptr_->run(); }
604
605
void WindowManager::setWindowDimension(const osgVector2& size) {
606
  /* Define new trait dimension of the main camera */
607
  const osg::GraphicsContext::Traits* traits_ptr = gc_->getTraits();
608
  gc_->resized(traits_ptr->x, traits_ptr->y, (int)size[0], (int)size[1]);
609
}
610
611
osgVector2 WindowManager::getWindowDimension() const {
612
  osgVector2 dimention;
613
  const osg::GraphicsContext::Traits* traits_ptr = gc_->getTraits();
614
  dimention.x() = (osg::Vec2f::value_type)traits_ptr->width;
615
  dimention.y() = (osg::Vec2f::value_type)traits_ptr->height;
616
  return dimention;
617
}
618
619
void WindowManager::setWindowPosition(const osgVector2& position) {
620
  /* Define new trait dimension of the main camera */
621
  const osg::GraphicsContext::Traits* traits_ptr = gc_->getTraits();
622
  gc_->resized((int)position[0], (int)position[1], traits_ptr->width,
623
               traits_ptr->height);
624
}
625
626
osgVector2 WindowManager::getWindowPosition() const {
627
  osgVector2 position;
628
  const osg::GraphicsContext::Traits* traits_ptr = gc_->getTraits();
629
  position.x() = (osg::Vec2f::value_type)traits_ptr->x;
630
  position.y() = (osg::Vec2f::value_type)traits_ptr->y;
631
  return position;
632
}
633
634
WindowManager::~WindowManager() {
635
  stopCapture();
636
  viewer_ptr_ = NULL;
637
}
638
639
osgViewer::ViewerRefPtr WindowManager::getViewerClone() {
640
  return ::osgViewer::ViewerRefPtr(viewer_ptr_.get());
641
}
642
643
void WindowManager::startCapture(const std::string& filename,
644
                                 const std::string& extension) {
645
  if (screen_capture_ptr_.valid()) {
646
    screen_capture_ptr_->startCapture();
647
    return;
648
  }
649
  /* Create an handler to save video */
650
  typedef osgViewer::ScreenCaptureHandler SCH_t;
651
  osg::ref_ptr<WriteToFile> wtf = new WriteToFile(filename, extension);
652
  screen_capture_ptr_ = new SCH_t(wtf.get(), -1);
653
  /* Screen capture can be stopped with stopCapture */
654
  screen_capture_ptr_->setKeyEventTakeScreenShot(0);
655
  screen_capture_ptr_->setKeyEventToggleContinuousCapture(0);
656
  viewer_ptr_->addEventHandler(screen_capture_ptr_);
657
  screen_capture_ptr_->startCapture();
658
}
659
660
void WindowManager::stopCapture() {
661
  if (!screen_capture_ptr_) return;
662
  screen_capture_ptr_->stopCapture();
663
  frame();
664
  // Remove event handler
665
  typedef osgViewer::View::EventHandlers EventHandlers;
666
  EventHandlers& handlers = viewer_ptr_->getEventHandlers();
667
  EventHandlers::iterator _handler =
668
      std::find(handlers.begin(), handlers.end(), screen_capture_ptr_);
669
  if (_handler != handlers.end()) {
670
    handlers.erase(_handler);
671
    screen_capture_ptr_.release();
672
  }
673
}
674
675
bool WindowManager::writeNodeFile(const std::string& fn) {
676
  osg::ref_ptr<osgDB::Options> options = new osgDB::Options;
677
  options->setOptionString("NoExtras");
678
  return osgDB::writeNodeFile(*(viewer_ptr_->getSceneData()), fn,
679
                              options.get());
680
}
681
682
void WindowManager::attachCameraToNode(NodePtr_t node) {
683
  osgGA::NodeTrackerManipulator* manip =
684
      dynamic_cast<osgGA::NodeTrackerManipulator*>(
685
          manipulator_ptr->getMatrixManipulatorWithIndex(
686
              nodeTrackerManipulatorIndex));
687
688
  if (manip) {
689
    manip->setTrackNode(node->getOsgNode().get());
690
    // manip->setRotationMode(osgGA::NodeTrackerManipulator::TRACKBALL);
691
    manip->setTrackerMode(
692
        osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION);
693
    manipulator_ptr->selectMatrixManipulator(nodeTrackerManipulatorIndex);
694
  } else
695
    log() << "Unexpected manipulator in viewer" << std::endl;
696
}
697
698
void WindowManager::detachCamera() {
699
  manipulator_ptr->selectMatrixManipulator(0);
700
}
701
702
void WindowManager::getCameraTransform(osg::Vec3d& pos, osg::Quat& rot) {
703
  osg::Matrixd matrix = manipulator_ptr->getMatrix();
704
  rot = matrix.getRotate();
705
  pos = matrix.getTrans();
706
}
707
708
void WindowManager::setCameraTransform(const osg::Vec3d& pos,
709
                                       const osg::Quat& rot) {
710
  osg::Matrixd matrix = osg::Matrixd();
711
  matrix.setTrans(pos.x(), pos.y(), pos.z());
712
  matrix.setRotate(rot);
713
  manipulator_ptr->setByMatrix(matrix);
714
  lastSceneWasDisrty_ = true;
715
}
716
717
/* End declaration of public function members */
718
719
} /* namespace viewer */
720
721
} /* namespace gepetto */