Merged in f5soh/librepilot/LP-575_fedora_package (pull request #491)
[librepilot.git] / ground / gcs / src / libs / osgearth / osgQtQuick / OSGSkyNode.cpp
blob17e2f21cc171943b8cc4ac4e8a19eded1b8b8078
1 /**
2 ******************************************************************************
4 * @file OSGSkyNode.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
6 * @addtogroup
7 * @{
8 * @addtogroup
9 * @{
10 * @brief
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "OSGSkyNode.hpp"
30 #include "OSGViewport.hpp"
32 #include <osgViewer/View>
34 #include <osgEarth/Config>
35 #include <osgEarth/DateTime>
36 #include <osgEarth/MapNode>
37 #include <osgEarthUtil/Sky>
39 // #include <osgEarthDrivers/sky_silverlining/SilverLiningOptions>
41 #include <QDebug>
43 namespace osgQtQuick {
44 enum DirtyFlag { Scene = 1 << 0, Viewport = 1 << 1, DateTime = 1 << 2, Light = 1 << 3 };
46 struct OSGSkyNode::Hidden : public QObject {
47 Q_OBJECT
49 private:
50 OSGSkyNode * const self;
52 osg::ref_ptr<osgEarth::Util::SkyNode> skyNode;
54 public:
55 OSGNode *sceneNode;
56 OSGViewport *viewport;
58 bool sunLightEnabled;
59 QDateTime dateTime;
60 double minimumAmbientLight;
62 Hidden(OSGSkyNode *self) : QObject(self), self(self), sceneNode(NULL), viewport(NULL),
63 sunLightEnabled(true), minimumAmbientLight(0.03)
65 dateTime = QDateTime::currentDateTime();
68 ~Hidden()
71 bool acceptSceneNode(OSGNode *node)
73 // qDebug() << "OSGSkyNode::acceptSceneNode" << node;
74 if (sceneNode == node) {
75 return false;
78 if (sceneNode) {
79 disconnect(sceneNode);
82 sceneNode = node;
84 if (sceneNode) {
85 connect(sceneNode, &OSGNode::nodeChanged, this, &OSGSkyNode::Hidden::onSceneNodeChanged);
88 return true;
91 void updateScene()
93 if (!sceneNode || !sceneNode->node()) {
94 qWarning() << "OSGSkyNode::updateScene - scene node not valid";
95 self->setNode(NULL);
96 return;
98 // qDebug() << "OSGSkyNode::updateScene - scene node" << sceneNode->node();
99 osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
100 if (!mapNode) {
101 qWarning() << "OSGSkyNode::updateScene - scene node does not contain a map node";
102 self->setNode(NULL);
103 return;
105 if (!mapNode->getMap()->isGeocentric()) {
106 qWarning() << "OSGSkyNode::updateScene - map node is not geocentric";
107 self->setNode(NULL);
108 return;
111 // create sky node
112 if (!skyNode.valid()) {
113 skyNode = createSimpleSky(mapNode);
114 // skyNode = createSilverLiningSky(mapNode);
116 // Ocean
117 // const osgEarth::Config & externals = mapNode->externalConfig();
118 // if (externals.hasChild("ocean")) {
119 // s_ocean = osgEarth::Util::OceanNode::create(osgEarth::Util::OceanOptions(externals.child("ocean")), mapNode);
120 // if (s_ocean) root->addChild(s_ocean);
122 skyNode->addChild(sceneNode->node());
123 self->setNode(skyNode);
124 } else {
125 skyNode->removeChild(0, 1);
126 skyNode->addChild(sceneNode->node());
127 // self->emitNodeChanged();
131 osgEarth::Util::SkyNode *createSimpleSky(osgEarth::MapNode *mapNode)
133 return osgEarth::Util::SkyNode::create(mapNode);
137 osgEarth::Util::SkyNode *createSilverLiningSky(osgEarth::MapNode *mapNode)
139 osgEarth::Drivers::SilverLining::SilverLiningOptions skyOptions;
140 skyOptions.user() = "OpenPilot";
141 skyOptions.licenseCode() = "1f02040d24000f0e18";
142 skyOptions.resourcePath() = "D:/Projects/OpenPilot/3rdparty/SilverLining-SDK-FullSource/Resources";
143 skyOptions.drawClouds() = true;
144 skyOptions.cloudsMaxAltitude() = 10000.0;
146 osgEarth::Util::SkyNode *skyNode = osgEarth::Util::SkyNode::create(skyOptions, mapNode);
148 return skyNode;
152 void updateViewport()
154 // qDebug() << "OSGSkyNode::updateViewport" << skyNode;
155 if (!skyNode.valid()) {
156 qWarning() << "OSGSkyNode::updateViewport - invalid sky node" << skyNode;
157 return;
159 // qDebug() << "OSGSkyNode::updateViewport - attaching to" << viewport->asView();
160 skyNode->attach(viewport->asView());
163 void updateSunLightEnabled()
165 if (!skyNode.valid()) {
166 qWarning() << "OSGSkyNode::updateSunLightEnabled - invalid sky node";
167 return;
169 if (!skyNode.valid()) {
170 return;
172 // skyNode->setLighting(sunLightEnabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
175 void updateDateTime()
177 if (!skyNode.valid()) {
178 qWarning() << "OSGSkyNode::updateDateTime - invalid sky node";
179 return;
181 if (!dateTime.isValid()) {
182 qWarning() << "OSGSkyNode::updateDateTime - invalid date/time" << dateTime;
185 QDate date = dateTime.date();
186 QTime time = dateTime.time();
187 double hours = time.hour() + (double)time.minute() / 60.0 + (double)time.second() / 3600.0;
188 skyNode->setDateTime(osgEarth::DateTime(date.year(), date.month(), date.day(), hours));
191 void updateMinimumAmbientLight()
193 if (!skyNode.valid()) {
194 qWarning() << "OSGSkyNode::updateMinimumAmbientLight - invalid sky node";
195 return;
197 double d = minimumAmbientLight;
198 // skyNode->getSunLight()->setAmbient(osg::Vec4(d, d, d, 1.0f));
199 skyNode->setMinimumAmbient(osg::Vec4(d, d, d, 1.0f));
202 void attachSkyNode(osgViewer::View *view)
204 if (!skyNode.valid()) {
205 qWarning() << "OSGSkyNode::attachSkyNode - invalid sky node" << skyNode;
206 return;
208 skyNode->attach(view);
211 void detachSkyNode(osgViewer::View *view)
213 // TODO find a way to detach the skyNode (?)
216 private slots:
217 void onSceneNodeChanged(osg::Node *node)
219 // qDebug() << "OSGSkyNode::onSceneNodeChanged" << node;
220 updateScene();
224 /* class OSGSkyNode */
226 OSGSkyNode::OSGSkyNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
228 setDirty(DateTime | Light);
231 OSGSkyNode::~OSGSkyNode()
233 delete h;
236 OSGNode *OSGSkyNode::sceneNode() const
238 return h->sceneNode;
241 void OSGSkyNode::setSceneNode(OSGNode *node)
243 if (h->acceptSceneNode(node)) {
244 setDirty(Scene);
245 emit sceneNodeChanged(node);
249 OSGViewport *OSGSkyNode::viewport() const
251 return h->viewport;
254 void OSGSkyNode::setViewport(OSGViewport *viewport)
256 if (h->viewport != viewport) {
257 h->viewport = viewport;
258 setDirty(Viewport);
259 emit viewportChanged(viewport);
263 bool OSGSkyNode::sunLightEnabled() const
265 return h->sunLightEnabled;
268 void OSGSkyNode::setSunLightEnabled(bool enabled)
270 if (h->sunLightEnabled != enabled) {
271 h->sunLightEnabled = enabled;
272 setDirty(Light);
273 emit sunLightEnabledChanged(enabled);
277 QDateTime OSGSkyNode::dateTime() const
279 return h->dateTime;
282 void OSGSkyNode::setDateTime(QDateTime dateTime)
284 if (h->dateTime != dateTime) {
285 h->dateTime = dateTime;
286 setDirty(DateTime);
287 emit dateTimeChanged(dateTime);
291 double OSGSkyNode::minimumAmbientLight() const
293 return h->minimumAmbientLight;
296 void OSGSkyNode::setMinimumAmbientLight(double ambient)
298 if (h->minimumAmbientLight != ambient) {
299 h->minimumAmbientLight = ambient;
300 setDirty(Light);
301 emit minimumAmbientLightChanged(ambient);
305 osg::Node *OSGSkyNode::createNode()
307 return NULL;
310 void OSGSkyNode::updateNode()
312 Inherited::updateNode();
314 if (isDirty(Scene)) {
315 h->updateScene();
317 if (isDirty(Viewport)) {
318 h->updateViewport();
320 if (isDirty(Light)) {
321 h->updateSunLightEnabled();
322 h->updateMinimumAmbientLight();
324 if (isDirty(DateTime)) {
325 h->updateDateTime();
328 } // namespace osgQtQuick
330 #include "OSGSkyNode.moc"