2 ******************************************************************************
4 * @file OSGGeoTransformNode.cpp
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 "OSGGeoTransformNode.hpp"
30 #include "utils/utility.h"
32 #include <osg/ComputeBoundsVisitor>
34 #include <osgEarth/GeoTransform>
35 #include <osgEarth/MapNode>
36 #include <osgEarth/GeoData>
40 namespace osgQtQuick
{
41 // NOTE : these flags should not overlap with OSGGroup flags!!!
42 // TODO : find a better way...
43 enum DirtyFlag
{ Scene
= 1 << 10, Position
= 1 << 11, Clamp
= 1 << 12 };
45 struct OSGGeoTransformNode::Hidden
: public QObject
{
49 OSGGeoTransformNode
* const self
;
51 osg::ref_ptr
<osgEarth::GeoTransform
> transform
;
63 Hidden(OSGGeoTransformNode
*self
) : QObject(self
), self(self
), sceneNode(NULL
), offset(-1.0), clampToTerrain(false), intoTerrain(false)
66 osg::Node
*createNode()
68 transform
= new osgEarth::GeoTransform();
69 transform
->setAutoRecomputeHeights(true);
73 bool acceptSceneNode(OSGNode
*node
)
75 // qDebug() << "OSGGeoTransformNode::acceptSceneNode" << node;
76 if (sceneNode
== node
) {
81 disconnect(sceneNode
);
87 connect(sceneNode
, &OSGNode::nodeChanged
, this, &OSGGeoTransformNode::Hidden::onSceneNodeChanged
);
93 void updateSceneNode()
95 // qDebug() << "OSGGeoTransformNode::updateSceneNode" << sceneNode;
96 if (sceneNode
&& sceneNode
->node()) {
97 osgEarth::MapNode
*mapNode
= osgEarth::MapNode::findMapNode(sceneNode
->node());
99 transform
->setTerrain(mapNode
->getTerrain());
101 qWarning() << "OSGGeoTransformNode::updateScene - scene data does not contain a map node";
106 void updatePosition()
108 // qDebug() << "OSGGeoTransformNode::updatePosition" << position;
110 osgEarth::MapNode
*mapNode
= NULL
;
112 if (sceneNode
&& sceneNode
->node()) {
113 mapNode
= osgEarth::MapNode::findMapNode(sceneNode
->node());
115 qWarning() << "OSGGeoTransformNode::updatePosition - scene node does not contain a map node";
118 qWarning() << "OSGGeoTransformNode::updatePosition - scene node is not valid";
121 osgEarth::GeoPoint geoPoint
= createGeoPoint(position
, mapNode
);
122 if (clampToTerrain
) {
123 // get "size" of model
124 // TODO this should be done once only...
126 osg::ComputeBoundsVisitor cbv
;
127 transform
->accept(cbv
);
128 const osg::BoundingBox
& bbox
= cbv
.getBoundingBox();
129 offset
= bbox
.radius();
131 const osg::BoundingSphere
& boundingSphere
= transform
->getBound();
132 offset
= boundingSphere
.radius();
134 // clamp model to terrain if needed
135 intoTerrain
= clampGeoPoint(geoPoint
, offset
, mapNode
);
137 qDebug() << "OSGGeoTransformNode::updateNode - into terrain" << offset
;
139 } else if (clampToTerrain
) {
140 qWarning() << "OSGGeoTransformNode::onChildNodeChanged - cannot clamp without map node";
142 transform
->setPosition(geoPoint
);
147 void onSceneNodeChanged(osg::Node
*node
)
149 // qDebug() << "OSGGeoTransformNode::onSceneNodeChanged" << node;
155 /* class OSGGeoTransformNode */
157 OSGGeoTransformNode::OSGGeoTransformNode(QObject
*parent
) : Inherited(parent
), h(new Hidden(this))
160 OSGGeoTransformNode::~OSGGeoTransformNode()
165 OSGNode
*OSGGeoTransformNode::sceneNode() const
170 void OSGGeoTransformNode::setSceneNode(OSGNode
*node
)
172 if (h
->acceptSceneNode(node
)) {
174 emit
sceneNodeChanged(node
);
178 bool OSGGeoTransformNode::clampToTerrain() const
180 return h
->clampToTerrain
;
183 void OSGGeoTransformNode::setClampToTerrain(bool arg
)
185 if (h
->clampToTerrain
!= arg
) {
186 h
->clampToTerrain
= arg
;
188 emit
clampToTerrainChanged(clampToTerrain());
192 bool OSGGeoTransformNode::intoTerrain() const
194 return h
->intoTerrain
;
197 QVector3D
OSGGeoTransformNode::position() const
202 void OSGGeoTransformNode::setPosition(QVector3D arg
)
204 if (h
->position
!= arg
) {
207 emit
positionChanged(position());
211 osg::Node
*OSGGeoTransformNode::createNode()
213 return h
->createNode();
216 void OSGGeoTransformNode::updateNode()
218 Inherited::updateNode();
220 if (isDirty(Scene
)) {
221 h
->updateSceneNode();
223 if (isDirty(Clamp
)) {
226 if (isDirty(Scene
| Clamp
| Position
)) {
230 } // namespace osgQtQuick
232 #include "OSGGeoTransformNode.moc"