GCC Code Coverage Report


Directory: ./
File: src/window-manager.cpp
Date: 2024-12-20 15:53:58
Exec Total Coverage
Lines: 0 406 0.0%
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 */
722