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:
parent
72d4d6a79b
commit
94b4d68400
302
ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.cpp
Normal file
302
ground/gcs/src/libs/osgearth/osgQtQuick/OSGGeoTransformNode.cpp
Normal 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"
|
@ -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_
|
@ -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"
|
@ -58,10 +58,8 @@ void OSGNode::setNode(osg::Node *node)
|
||||
}
|
||||
|
||||
void OSGNode::attach(osgViewer::View *view)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void OSGNode::detach(osgViewer::View *view)
|
||||
{
|
||||
}
|
||||
{}
|
||||
} // namespace osgQtQuick
|
||||
|
@ -41,7 +41,6 @@ class View;
|
||||
} // namespace osgViewer
|
||||
|
||||
namespace osgQtQuick {
|
||||
|
||||
class OSGQTQUICK_EXPORT OSGNode : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user