2 ******************************************************************************
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
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
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>
43 namespace osgQtQuick
{
44 enum DirtyFlag
{ Scene
= 1 << 0, Viewport
= 1 << 1, DateTime
= 1 << 2, Light
= 1 << 3 };
46 struct OSGSkyNode::Hidden
: public QObject
{
50 OSGSkyNode
* const self
;
52 osg::ref_ptr
<osgEarth::Util::SkyNode
> skyNode
;
56 OSGViewport
*viewport
;
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();
71 bool acceptSceneNode(OSGNode
*node
)
73 // qDebug() << "OSGSkyNode::acceptSceneNode" << node;
74 if (sceneNode
== node
) {
79 disconnect(sceneNode
);
85 connect(sceneNode
, &OSGNode::nodeChanged
, this, &OSGSkyNode::Hidden::onSceneNodeChanged
);
93 if (!sceneNode
|| !sceneNode
->node()) {
94 qWarning() << "OSGSkyNode::updateScene - scene node not valid";
98 // qDebug() << "OSGSkyNode::updateScene - scene node" << sceneNode->node();
99 osgEarth::MapNode
*mapNode
= osgEarth::MapNode::findMapNode(sceneNode
->node());
101 qWarning() << "OSGSkyNode::updateScene - scene node does not contain a map node";
105 if (!mapNode
->getMap()->isGeocentric()) {
106 qWarning() << "OSGSkyNode::updateScene - map node is not geocentric";
112 if (!skyNode
.valid()) {
113 skyNode
= createSimpleSky(mapNode
);
114 // skyNode = createSilverLiningSky(mapNode);
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
);
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);
152 void updateViewport()
154 // qDebug() << "OSGSkyNode::updateViewport" << skyNode;
155 if (!skyNode
.valid()) {
156 qWarning() << "OSGSkyNode::updateViewport - invalid sky node" << skyNode
;
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";
169 if (!skyNode
.valid()) {
172 // skyNode->setLighting(sunLightEnabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
175 void updateDateTime()
177 if (!skyNode
.valid()) {
178 qWarning() << "OSGSkyNode::updateDateTime - invalid sky node";
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";
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
;
208 skyNode
->attach(view
);
211 void detachSkyNode(osgViewer::View
*view
)
213 // TODO find a way to detach the skyNode (?)
217 void onSceneNodeChanged(osg::Node
*node
)
219 // qDebug() << "OSGSkyNode::onSceneNodeChanged" << node;
224 /* class OSGSkyNode */
226 OSGSkyNode::OSGSkyNode(QObject
*parent
) : Inherited(parent
), h(new Hidden(this))
228 setDirty(DateTime
| Light
);
231 OSGSkyNode::~OSGSkyNode()
236 OSGNode
*OSGSkyNode::sceneNode() const
241 void OSGSkyNode::setSceneNode(OSGNode
*node
)
243 if (h
->acceptSceneNode(node
)) {
245 emit
sceneNodeChanged(node
);
249 OSGViewport
*OSGSkyNode::viewport() const
254 void OSGSkyNode::setViewport(OSGViewport
*viewport
)
256 if (h
->viewport
!= viewport
) {
257 h
->viewport
= 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
;
273 emit
sunLightEnabledChanged(enabled
);
277 QDateTime
OSGSkyNode::dateTime() const
282 void OSGSkyNode::setDateTime(QDateTime dateTime
)
284 if (h
->dateTime
!= dateTime
) {
285 h
->dateTime
= 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
;
301 emit
minimumAmbientLightChanged(ambient
);
305 osg::Node
*OSGSkyNode::createNode()
310 void OSGSkyNode::updateNode()
312 Inherited::updateNode();
314 if (isDirty(Scene
)) {
317 if (isDirty(Viewport
)) {
320 if (isDirty(Light
)) {
321 h
->updateSunLightEnabled();
322 h
->updateMinimumAmbientLight();
324 if (isDirty(DateTime
)) {
328 } // namespace osgQtQuick
330 #include "OSGSkyNode.moc"