renderworldwrapperwidget.cpp
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2014 *
4  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
5  * Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it> *
6  * Gianluca Massera <emmegian@yahoo.it> *
7  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the Free Software *
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
22  ********************************************************************************/
23 
24 #include "renderworldwrapperwidget.h"
25 #include "renderworld.h"
26 #include "logger.h"
27 #include <QVBoxLayout>
28 
29 using namespace qglviewer;
30 
31 // All the suff below is to avoid warnings on Windows about the use of unsafe
32 // functions. This should be only a temporary workaround, the solution is stop
33 // using C string and file functions...
34 #if defined(_MSC_VER)
35  #pragma warning(push)
36  #pragma warning(disable:4996)
37 #endif
38 
39 namespace farsa {
40 
41 namespace {
42  // A custom QEvent to force update of RenderWorldWrapperWidget
43  class ForceRenderWorldUpdateEvent : public QEvent
44  {
45  public:
46  ForceRenderWorldUpdateEvent() :
47  QEvent(QEvent::User)
48  {
49  }
50 
51  virtual ~ForceRenderWorldUpdateEvent()
52  {
53  }
54  };
55 }
56 
57 RenderWorldWrapperWidget::RenderWorldWrapperWidget(QWidget* parent, Qt::WindowFlags flags) :
58  QWidget(parent, flags),
60  m_renderWorld(new RenderWorld(this, "world")),
61  m_layout(new QVBoxLayout(this)),
62  m_setCameraToLookAtRobot(true),
63  m_robotTm(wMatrix::identity())
64 {
65  // Setting some window property and creating the layout that will contain renderworld
66  setWindowTitle("3D World");
67  m_layout->setContentsMargins(0, 0, 0, 0);
68  m_layout->addWidget(m_renderWorld);
69  const QString stateFileName = ".evolver.xml";
70  m_renderWorld->setStateFileName(stateFileName);
71 
72  // Declaring which resources we will need to use
73  usableResources(QStringList() << "robot");
74 
75  // timer used if selfUpdate is on
76  m_selfUpdateTimer = new QTimer(this);
77  // 40 ms correspond to 25 frame per seconds
78  m_selfUpdateTimer->setInterval( 40 );
79  m_selfUpdateTimer->setSingleShot( false );
80  connect( m_selfUpdateTimer, SIGNAL(timeout()), this, SLOT(updateRenderWorld()) );
81 }
82 
84 {
85  m_selfUpdateTimer->stop();
86 }
87 
89 {
90  // First of all calling parent function
92 
93  // Now sharing with RenderWorld
95 }
96 
98 {
100  lookAtRobot();
101 
102  m_setCameraToLookAtRobot = false;
103  }
104 
105  m_renderWorld->update();
106 }
107 
109  if ( on ) {
110  m_selfUpdateTimer->start();
111  } else {
112  m_selfUpdateTimer->stop();
113  }
114 }
115 
117  return m_selfUpdateTimer->isActive();
118 }
119 
120 void RenderWorldWrapperWidget::resourceChanged(QString resourceName, ResourceChangeType changeType)
121 {
122  if (resourceName == "robot") {
123  if ((changeType != Deleted) && (!m_renderWorld->viewerStateRestoredFromFile())) {
124  try {
125  m_robotTm = getResource<WObject>()->matrix();
126  } catch (const ResourceTypeMismatchException&) {
127  }
128 
130  }
131  } else {
132  Logger::info("Unknown resource " + resourceName + " for RenderWorldWrapperWidget widget");
133  }
134 
135  // Forcing renderworld update
136  QCoreApplication::postEvent(this, new ForceRenderWorldUpdateEvent());
137 }
138 
140 {
141  if (event->type() == QEvent::User) {
142  // Forcing RenderWorld update
144  }
145 }
146 
148 {
149  wVector cameraDefaultPosition = m_robotTm.transformVector(wVector(-0.8f, 0.0f, +0.6f));
150  m_renderWorld->camera()->setPosition(Vec(cameraDefaultPosition[0], cameraDefaultPosition[1], cameraDefaultPosition[2]));
151  m_renderWorld->camera()->setUpVector(Vec(0.0f, 0.0f, 1.0f));
152  m_renderWorld->camera()->lookAt(Vec(m_robotTm.w_pos[0], m_robotTm.w_pos[1], m_robotTm.w_pos[2]));
153 }
154 
155 } //end namespace farsa
156 
157 // All the suff below is to restore the warning state on Windows
158 #if defined(_MSC_VER)
159  #pragma warning(pop)
160 #endif
void usableResources(QStringList resources)
virtual void resourceChanged(QString resourceName, ResourceChangeType changeType)
The function called when a resource used here is changed.
bool viewerStateRestoredFromFile() const
void setStateFileName(const QString &name)
QVBoxLayout *const m_layout
The layout for this widget.
virtual void shareResourcesWith(ResourcesUser *buddy)
void setSelfUpdate(bool enable)
enable/disable the self updating features
virtual void shareResourcesWith(ResourcesUser *buddy)
Shares resources with the provided instance of ResourcesUser.
bool m_setCameraToLookAtRobot
True if we have to set camera to look at the robot.
static void info(QString msg)
bool isSelfUpdate()
return true if the self updating is active
wMatrix m_robotTm
The transformation matrix of the iCub.
qglviewer::Camera * camera() const
void lookAt(const Vec &target)
void setUpVector(const Vec &up, bool noMove=true)
void setPosition(const Vec &pos)
virtual void customEvent(QEvent *event)
The function that receives custom events.
void updateRenderWorld()
Triggers an update of the RenderWorld object.
QTimer * m_selfUpdateTimer
Timer used for self update the render world.
void lookAtRobot()
Brings the camera in front of the robot.
wVector transformVector(const wVector &v) const
RenderWorld *const m_renderWorld
The object actually rendering the world.