1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-19 04:52:12 +01:00

LP-29 replace OSGModelNode with more straightforward OSGGeoTransformNode

This commit is contained in:
Philippe Renon 2016-03-06 18:21:03 +01:00
parent 72d4d6a79b
commit 94b4d68400
11 changed files with 346 additions and 411 deletions

View File

@ -0,0 +1,302 @@
/**
******************************************************************************
*
* @file OSGTransformNode.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @addtogroup
* @{
* @addtogroup
* @{
* @brief
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OSGGeoTransformNode.hpp"
#include "../utility.h"
#include <osg/ComputeBoundsVisitor>
#include <osgearth/GeoTransform>
#include <osgEarth/MapNode>
#include <osgEarth/GeoData>
#include <QDebug>
namespace osgQtQuick {
struct OSGGeoTransformNode::Hidden : public QObject {
Q_OBJECT
struct NodeUpdateCallback : public osg::NodeCallback {
public:
NodeUpdateCallback(Hidden *h) : h(h) {}
void operator()(osg::Node *node, osg::NodeVisitor *nv);
mutable Hidden *h;
};
friend class NodeUpdateCallback;
public:
Hidden(OSGGeoTransformNode *parent) : QObject(parent), self(parent), childNode(NULL), sceneNode(NULL), offset(-1.0), clampToTerrain(false), intoTerrain(false), dirty(false)
{}
~Hidden()
{}
bool acceptChildNode(OSGNode *node)
{
qDebug() << "OSGGeoTransformNode::acceptChildNode" << node;
if (childNode == node) {
return false;
}
if (childNode) {
disconnect(childNode);
}
childNode = node;
dirty = true;
if (childNode) {
connect(childNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onChildNodeChanged(osg::Node *)));
}
return true;
}
bool acceptSceneNode(OSGNode *node)
{
qDebug() << "OSGGeoTransformNode::acceptSceneNode" << node;
if (sceneNode == node) {
return false;
}
if (sceneNode) {
disconnect(sceneNode);
}
sceneNode = node;
dirty = true;
if (sceneNode) {
connect(sceneNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onSceneNodeChanged(osg::Node *)));
}
return true;
}
void updateNode()
{
if (!dirty) {
return;
}
dirty = false;
// qDebug() << "OSGGeoTransformNode::updateNode" << this;
osgEarth::GeoTransform *transform = getOrCreateTransform();
if (transform->getNumChildren() == 0) {
if (childNode && childNode->node()) {
transform->addChild(childNode->node());
}
} else {
if (childNode && childNode->node()) {
if (transform->getChild(0) != childNode->node()) {
transform->removeChild(0, 1);
transform->addChild(childNode->node());
}
} else {
transform->removeChild(0, 1);
}
}
osgEarth::MapNode *mapNode = NULL;
if (sceneNode && sceneNode->node()) {
mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
if (mapNode) {
transform->setTerrain(mapNode->getTerrain());
} else {
qWarning() << "OSGGeoTransformNode::updateNode - scene data does not contain a map node";
}
}
osgEarth::GeoPoint geoPoint;
if (mapNode) {
geoPoint = osgQtQuick::toGeoPoint(mapNode->getTerrain()->getSRS(), position);
} else {
geoPoint = osgQtQuick::toGeoPoint(position);
}
if (clampToTerrain && mapNode) {
// get "size" of model
// TODO this should be done once only...
osg::ComputeBoundsVisitor cbv;
childNode->node()->accept(cbv);
const osg::BoundingBox & bbox = cbv.getBoundingBox();
offset = bbox.radius();
// qDebug() << "OSGGeoTransformNode::updateNode - offset" << offset;
// clamp model to terrain if needed
intoTerrain = clampGeoPoint(geoPoint, offset, mapNode);
}
transform->setPosition(geoPoint);
}
osgEarth::GeoTransform *getOrCreateTransform()
{
if (transform.valid()) {
return transform.get();
}
transform = new osgEarth::GeoTransform();
transform->setAutoRecomputeHeights(true);
transform->addUpdateCallback(new NodeUpdateCallback(this));
self->setNode(transform);
return transform.get();
}
OSGGeoTransformNode *const self;
OSGNode *childNode;
OSGNode *sceneNode;
osg::ref_ptr<osgEarth::GeoTransform> transform;
float offset;
bool clampToTerrain;
bool intoTerrain;
QVector3D position;
bool dirty;
private slots:
void onChildNodeChanged(osg::Node *node)
{
qDebug() << "OSGGeoTransformNode::onChildNodeChanged" << node;
dirty = true;
}
void onSceneNodeChanged(osg::Node *node)
{
qDebug() << "OSGGeoTransformNode::onSceneNodeChanged" << node;
dirty = true;
}
};
/* struct Hidden::NodeUpdateCallback */
void OSGGeoTransformNode::Hidden::NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv)
{
nv->traverse(*node);
h->updateNode();
}
OSGGeoTransformNode::OSGGeoTransformNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
{
qDebug() << "OSGGeoTransformNode::OSGGeoTransformNode";
}
OSGGeoTransformNode::~OSGGeoTransformNode()
{
qDebug() << "OSGGeoTransformNode::~OSGGeoTransformNode";
}
OSGNode *OSGGeoTransformNode::modelData()
{
return h->childNode;
}
void OSGGeoTransformNode::setModelData(OSGNode *node)
{
if (h->acceptChildNode(node)) {
emit modelDataChanged(node);
}
}
OSGNode *OSGGeoTransformNode::sceneData()
{
return h->sceneNode;
}
void OSGGeoTransformNode::setSceneData(OSGNode *node)
{
if (h->acceptSceneNode(node)) {
emit sceneDataChanged(node);
}
}
bool OSGGeoTransformNode::clampToTerrain() const
{
return h->clampToTerrain;
}
void OSGGeoTransformNode::setClampToTerrain(bool arg)
{
if (h->clampToTerrain != arg) {
h->clampToTerrain = arg;
h->dirty = true;
emit clampToTerrainChanged(clampToTerrain());
}
}
bool OSGGeoTransformNode::intoTerrain() const
{
return h->intoTerrain;
}
QVector3D OSGGeoTransformNode::position() const
{
return h->position;
}
void OSGGeoTransformNode::setPosition(QVector3D arg)
{
if (h->position != arg) {
h->position = arg;
h->dirty = true;
emit positionChanged(position());
}
}
void OSGGeoTransformNode::attach(osgViewer::View *view)
{
// qDebug() << "OSGGeoTransformNode::attach " << view;
if (h->childNode) {
h->childNode->attach(view);
}
h->updateNode();
}
void OSGGeoTransformNode::detach(osgViewer::View *view)
{
// qDebug() << "OSGGeoTransformNode::detach " << view;
if (h->childNode) {
h->childNode->detach(view);
}
}
} // namespace osgQtQuick
#include "OSGGeoTransformNode.moc"

View File

@ -1,7 +1,7 @@
/**
******************************************************************************
*
* @file OSGModelNode.hpp
* @file OSGTransformNode.hpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @addtogroup
* @{
@ -25,35 +25,31 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_OSGQTQUICK_MODELNODE_H_
#define _H_OSGQTQUICK_MODELNODE_H_
#ifndef _H_OSGQTQUICK_GEOTRANSFORMNODE_H_
#define _H_OSGQTQUICK_GEOTRANSFORMNODE_H_
#include "Export.hpp"
#include "OSGNode.hpp"
#include <QVector3D>
#include <QUrl>
namespace osgViewer {
class View;
}
// TODO derive from OSGGroup...
namespace osgQtQuick {
class OSGQTQUICK_EXPORT OSGModelNode : public OSGNode {
class OSGQTQUICK_EXPORT OSGGeoTransformNode : public OSGNode {
Q_OBJECT
// TODO rename to parentNode and modelNode
// TODO rename to childNode
Q_PROPERTY(osgQtQuick::OSGNode *modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
// TODO rename to sceneNode
Q_PROPERTY(osgQtQuick::OSGNode * sceneData READ sceneData WRITE setSceneData NOTIFY sceneDataChanged)
Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged)
Q_PROPERTY(bool intoTerrain READ intoTerrain NOTIFY intoTerrainChanged)
Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged)
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
public:
OSGModelNode(QObject *parent = 0);
virtual ~OSGModelNode();
OSGGeoTransformNode(QObject *parent = 0);
virtual ~OSGGeoTransformNode();
OSGNode *modelData();
void setModelData(OSGNode *node);
@ -66,9 +62,6 @@ public:
bool intoTerrain() const;
QVector3D attitude() const;
void setAttitude(QVector3D arg);
QVector3D position() const;
void setPosition(QVector3D arg);
@ -77,12 +70,12 @@ public:
signals:
void modelDataChanged(OSGNode *node);
void sceneDataChanged(OSGNode *node);
void clampToTerrainChanged(bool arg);
void intoTerrainChanged(bool arg);
void attitudeChanged(QVector3D arg);
void positionChanged(QVector3D arg);
private:
@ -91,4 +84,4 @@ private:
};
} // namespace osgQtQuick
#endif // _H_OSGQTQUICK_MODELNODE_H_
#endif // _H_OSGQTQUICK_GEOTRANSFORMNODE_H_

View File

@ -1,367 +0,0 @@
/**
******************************************************************************
*
* @file OSGModelNode.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @addtogroup
* @{
* @addtogroup
* @{
* @brief
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OSGModelNode.hpp"
#include "../utility.h"
#include <osg/Quat>
#include <osg/ComputeBoundsVisitor>
#include <osgViewer/View>
#include <osgEarth/MapNode>
#include <osgEarth/GeoData>
#include <osgEarthSymbology/Style>
#include <osgEarthSymbology/ModelSymbol>
#include <osgEarthAnnotation/ModelNode>
#include <QDebug>
namespace osgQtQuick {
struct OSGModelNode::Hidden : public QObject {
Q_OBJECT
struct NodeUpdateCallback : public osg::NodeCallback {
public:
NodeUpdateCallback(Hidden *h) : h(h) {}
void operator()(osg::Node *node, osg::NodeVisitor *nv);
mutable Hidden *h;
};
friend class NodeUpdateCallback;
public:
Hidden(OSGModelNode *parent) : QObject(parent), self(parent), modelData(NULL), sceneData(NULL), offset(-1.0), clampToTerrain(false), intoTerrain(false), dirty(false)
{}
~Hidden()
{}
bool acceptModelData(OSGNode *node)
{
qDebug() << "OSGModelNode::acceptModelData" << node;
if (modelData == node) {
return false;
}
if (modelData) {
disconnect(modelData);
}
modelData = node;
if (modelData) {
acceptModelNode(modelData->node());
connect(modelData, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onModelNodeChanged(osg::Node *)));
}
return true;
}
bool acceptModelNode(osg::Node *node)
{
qDebug() << "OSGModelNode::acceptModelNode" << node;
if (!node) {
qWarning() << "OSGModelNode::acceptModelNode - node is null";
return false;
}
if (!sceneData || !sceneData->node()) {
qWarning() << "OSGModelNode::acceptModelNode - no scene data";
return false;
}
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node());
if (!mapNode) {
qWarning() << "OSGModelNode::acceptModelNode - scene data does not contain a map node";
return false;
}
// establish the coordinate system we wish to use:
// const osgEarth::SpatialReference* latLong = osgEarth::SpatialReference::get("wgs84");
osgEarth::Symbology::Style style;
// construct the symbology
osgEarth::Symbology::ModelSymbol *modelSymbol = style.getOrCreate<osgEarth::Symbology::ModelSymbol>();
modelSymbol->setModel(node);
// create ModelNode
modelNode = new osgEarth::Annotation::ModelNode(mapNode, style);
// add update callback
if (!nodeUpdateCallback.valid()) {
nodeUpdateCallback = new NodeUpdateCallback(this);
}
modelNode->addUpdateCallback(nodeUpdateCallback.get());
self->setNode(modelNode);
dirty = true;
return true;
}
bool acceptSceneData(OSGNode *node)
{
qDebug() << "OSGModelNode::acceptSceneData" << node;
if (sceneData == node) {
return false;
}
if (sceneData) {
disconnect(sceneData);
}
sceneData = node;
if (sceneData) {
// TODO find a better way
if (modelData && modelData->node()) {
acceptModelNode(modelData->node());
}
connect(sceneData, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onSceneNodeChanged(osg::Node *)));
}
return true;
}
// TODO model update gets jitter if camera is thrown (i.e animated)
void updateNode()
{
if (!dirty || !modelNode.valid()) {
return;
}
dirty = false;
osgEarth::GeoPoint geoPoint = osgQtQuick::toGeoPoint(position);
if (clampToTerrain) {
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node());
if (mapNode) {
// get "size" of model
// TODO this should be done once only...
osg::ComputeBoundsVisitor cbv;
modelNode->accept(cbv);
const osg::BoundingBox & bbox = cbv.getBoundingBox();
offset = bbox.radius();
// clamp model to terrain if needed
intoTerrain = clampGeoPoint(geoPoint, offset, mapNode);
} else {
qWarning() << "OSGModelNode::updateNode - scene data does not contain a map node";
}
}
modelNode->setPosition(geoPoint);
modelNode->setLocalRotation(localRotation());
}
osg::Quat localRotation()
{
double roll = osg::DegreesToRadians(attitude.x());
double pitch = osg::DegreesToRadians(attitude.y());
double yaw = osg::DegreesToRadians(attitude.z());
osg::Quat q = osg::Quat(
roll, osg::Vec3d(0, 1, 0),
pitch, osg::Vec3d(1, 0, 0),
yaw, osg::Vec3d(0, 0, -1));
return q;
}
OSGModelNode *const self;
OSGNode *modelData;
OSGNode *sceneData;
osg::ref_ptr<osgEarth::Annotation::ModelNode> modelNode;
float offset;
bool clampToTerrain;
bool intoTerrain;
QVector3D attitude;
QVector3D position;
// handle attitude/position/etc independently
bool dirty;
osg::observer_ptr<NodeUpdateCallback> nodeUpdateCallback;
private slots:
void onModelNodeChanged(osg::Node *node)
{
qDebug() << "OSGModelNode::onModelNodeChanged" << node;
if (modelData) {
if (modelNode.valid()) {
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node());
if (mapNode) {
mapNode->removeChild(modelNode);
}
if (nodeUpdateCallback.valid()) {
modelNode->removeUpdateCallback(nodeUpdateCallback.get());
}
}
if (node) {
acceptModelNode(node);
}
}
}
void onSceneNodeChanged(osg::Node *node)
{
qDebug() << "OSGModelNode::onSceneNodeChanged" << node;
// TODO needs to be improved...
if (modelData) {
if (modelNode.valid()) {
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node());
if (mapNode) {
mapNode->removeChild(modelNode);
}
if (nodeUpdateCallback.valid()) {
modelNode->removeUpdateCallback(nodeUpdateCallback.get());
}
}
if (modelData->node()) {
acceptModelNode(modelData->node());
}
}
}
};
/* struct Hidden::NodeUpdateCallback */
void OSGModelNode::Hidden::NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv)
{
h->updateNode();
}
OSGModelNode::OSGModelNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
{
qDebug() << "OSGModelNode::OSGModelNode";
}
OSGModelNode::~OSGModelNode()
{
qDebug() << "OSGModelNode::~OSGModelNode";
}
OSGNode *OSGModelNode::modelData()
{
return h->modelData;
}
void OSGModelNode::setModelData(OSGNode *node)
{
if (h->acceptModelData(node)) {
emit modelDataChanged(node);
}
}
OSGNode *OSGModelNode::sceneData()
{
return h->sceneData;
}
void OSGModelNode::setSceneData(OSGNode *node)
{
if (h->acceptSceneData(node)) {
emit sceneDataChanged(node);
}
}
bool OSGModelNode::clampToTerrain() const
{
return h->clampToTerrain;
}
void OSGModelNode::setClampToTerrain(bool arg)
{
if (h->clampToTerrain != arg) {
h->clampToTerrain = arg;
h->dirty = true;
emit clampToTerrainChanged(clampToTerrain());
}
}
bool OSGModelNode::intoTerrain() const
{
return h->intoTerrain;
}
QVector3D OSGModelNode::attitude() const
{
return h->attitude;
}
void OSGModelNode::setAttitude(QVector3D arg)
{
if (h->attitude != arg) {
h->attitude = arg;
h->dirty = true;
emit attitudeChanged(attitude());
}
}
QVector3D OSGModelNode::position() const
{
return h->position;
}
void OSGModelNode::setPosition(QVector3D arg)
{
if (h->position != arg) {
h->position = arg;
h->dirty = true;
emit positionChanged(position());
}
}
void OSGModelNode::attach(osgViewer::View *view)
{
// qDebug() << "OSGModelNode::attach " << view;
if (h->modelData) {
h->modelData->attach(view);
}
h->updateNode();
}
void OSGModelNode::detach(osgViewer::View *view)
{
// qDebug() << "OSGModelNode::detach " << view;
if (h->modelData) {
h->modelData->detach(view);
}
}
} // namespace osgQtQuick
#include "OSGModelNode.moc"

View File

@ -58,10 +58,8 @@ void OSGNode::setNode(osg::Node *node)
}
void OSGNode::attach(osgViewer::View *view)
{
}
{}
void OSGNode::detach(osgViewer::View *view)
{
}
{}
} // namespace osgQtQuick

View File

@ -41,7 +41,6 @@ class View;
} // namespace osgViewer
namespace osgQtQuick {
class OSGQTQUICK_EXPORT OSGNode : public QObject {
Q_OBJECT

View File

@ -67,7 +67,7 @@ public:
}
childNode = node;
dirty = true;
dirty = true;
if (childNode) {
connect(childNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onChildNodeChanged(osg::Node *)));
@ -91,15 +91,13 @@ public:
if (childNode && childNode->node()) {
transform->addChild(childNode->node());
}
}
else {
} else {
if (childNode && childNode->node()) {
if (transform->getChild(0) != childNode->node()) {
transform->removeChild(0, 1);
transform->addChild(childNode->node());
}
}
else {
} else {
transform->removeChild(0, 1);
}
}

View File

@ -187,7 +187,7 @@ public:
qDebug() << "OSGViewport::attach - found map node" << mapNode;
// remove light to prevent unnecessary state changes in SceneView
// scene will get light from sky
// scene will get light from sky (works only with latest > 2.7)
// view->setLightingMode(osg::View::NO_LIGHT);
}
#endif

View File

@ -70,11 +70,11 @@ SOURCES += \
osgQtQuick/OSGViewport.cpp
osgearth:HEADERS += \
osgQtQuick/OSGModelNode.hpp \
osgQtQuick/OSGSkyNode.hpp
osgQtQuick/OSGSkyNode.hpp \
osgQtQuick/OSGGeoTransformNode.hpp
osgearth:SOURCES += \
osgQtQuick/OSGModelNode.cpp \
osgQtQuick/OSGSkyNode.cpp
osgQtQuick/OSGSkyNode.cpp \
osgQtQuick/OSGGeoTransformNode.cpp
copy_osg:include(copydata.pro)

View File

@ -34,9 +34,7 @@
#include "osgQtQuick/OSGTransformNode.hpp"
#include "osgQtQuick/OSGShapeNode.hpp"
#include "osgQtQuick/OSGTextNode.hpp"
#include "osgQtQuick/OSGModelNode.hpp"
#include "osgQtQuick/OSGBackgroundNode.hpp"
#include "osgQtQuick/OSGSkyNode.hpp"
#include "osgQtQuick/OSGCamera.hpp"
#include "osgQtQuick/OSGViewport.hpp"
@ -60,6 +58,9 @@
#endif // USE_OSG_QT
#ifdef USE_OSGEARTH
#include "osgQtQuick/OSGSkyNode.hpp"
#include "osgQtQuick/OSGGeoTransformNode.hpp"
#include <osgEarth/Capabilities>
#include <osgEarth/MapNode>
#include <osgEarth/SpatialReference>
@ -440,12 +441,15 @@ QString getUsageString(osgViewer::CompositeViewer *viewer)
}
#ifdef USE_OSGEARTH
osgEarth::GeoPoint toGeoPoint(const osgEarth::SpatialReference *srs, const QVector3D &position)
{
osgEarth::GeoPoint geoPoint(srs, position.x(), position.y(), position.z(), osgEarth::ALTMODE_ABSOLUTE);
return geoPoint;
}
osgEarth::GeoPoint toGeoPoint(const QVector3D &position)
{
osgEarth::GeoPoint geoPoint(osgEarth::SpatialReference::get("wgs84"),
position.x(), position.y(), position.z(), osgEarth::ALTMODE_ABSOLUTE);
return geoPoint;
return toGeoPoint(osgEarth::SpatialReference::get("wgs84"), position);
}
bool clampGeoPoint(osgEarth::GeoPoint &geoPoint, float offset, osgEarth::MapNode *mapNode)
@ -542,8 +546,8 @@ void registerTypes()
qmlRegisterType<osgQtQuick::TrackerMode>("OsgQtQuick", maj, min, "TrackerMode");
#ifdef USE_OSGEARTH
qmlRegisterType<osgQtQuick::OSGModelNode>("OsgQtQuick", maj, min, "OSGModelNode");
qmlRegisterType<osgQtQuick::OSGSkyNode>("OsgQtQuick", maj, min, "OSGSkyNode");
qmlRegisterType<osgQtQuick::OSGGeoTransformNode>("OsgQtQuick", maj, min, "OSGGeoTransformNode");
#endif // USE_OSGEARTH
}
} // namespace osgQtQuick

View File

@ -62,6 +62,7 @@ namespace osgEarth {
class Capabilities;
class GeoPoint;
class MapNode;
class SpatialReference;
} // namespace osgEarth
#endif
@ -145,6 +146,7 @@ QString getUsageString(osgViewer::CompositeViewer *viewer);
#ifdef USE_OSGEARTH
osgEarth::GeoPoint toGeoPoint(const QVector3D &position);
osgEarth::GeoPoint toGeoPoint(const osgEarth::SpatialReference *srs, const QVector3D &position);
bool clampGeoPoint(osgEarth::GeoPoint &geoPoint, float offset, osgEarth::MapNode *mapNode);
void capabilitiesInfo(const osgEarth::Capabilities & caps);
#endif

View File

@ -49,13 +49,14 @@ OSGViewport {
async: false
}
OSGModelNode {
OSGGeoTransformNode {
id: modelNode
clampToTerrain: true
modelData: modelTransformNode
sceneData: terrainNode
attitude: UAV.attitude()
clampToTerrain: true
position: UAV.position()
}
@ -64,11 +65,16 @@ OSGViewport {
modelData: modelFileNode
// model dimensions are in mm, scale to meters
scale: Qt.vector3d(0.001, 0.001, 0.001)
attitude: UAV.attitude()
}
OSGFileNode {
id: modelFileNode
source: pfdContext.modelFile
// use ShaderGen pseudoloader to generate the shaders expected by osgEarth
// see http://docs.osgearth.org/en/latest/faq.html#i-added-a-node-but-it-has-no-texture-lighting-etc-in-osgearth-why
source: pfdContext.modelFile + ".osgearth_shadergen"
async: false
optimizeMode: OptimizeMode.OptimizeAndCheck
}