mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
LP-29 factorize update callback handling up into OSGNode
allows "on demand" mode to work which can drastically reduce cpu usage in some cases
This commit is contained in:
parent
a4fb576d4b
commit
223d8f30e0
@ -100,6 +100,7 @@ OSGBackgroundNode::OSGBackgroundNode(QObject *parent) : OSGNode(parent), h(new H
|
||||
OSGBackgroundNode::~OSGBackgroundNode()
|
||||
{
|
||||
// qDebug() << "OSGBackgroundNode::~OSGBackgroundNode";
|
||||
delete h;
|
||||
}
|
||||
|
||||
const QUrl OSGBackgroundNode::imageFile() const
|
||||
|
@ -54,29 +54,14 @@ namespace osgQtQuick {
|
||||
struct OSGCamera::Hidden : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
struct CameraUpdateCallback : public osg::NodeCallback {
|
||||
public:
|
||||
CameraUpdateCallback(Hidden *h) : h(h) {}
|
||||
|
||||
void operator()(osg::Node *node, osg::NodeVisitor *nv);
|
||||
|
||||
mutable Hidden *h;
|
||||
};
|
||||
friend class CameraUpdateCallback;
|
||||
|
||||
public:
|
||||
|
||||
Hidden(OSGCamera *parent) :
|
||||
QObject(parent), sceneData(NULL), manipulatorMode(ManipulatorMode::Default), node(NULL),
|
||||
trackerMode(TrackerMode::NodeCenterAndAzim), trackNode(NULL),
|
||||
logDepthBufferEnabled(false), clampToTerrain(false)
|
||||
Hidden(OSGCamera *camera) :
|
||||
QObject(camera), self(camera), sceneNode(NULL),
|
||||
manipulatorMode(ManipulatorMode::Default), trackerMode(TrackerMode::NodeCenterAndAzim), trackNode(NULL),
|
||||
logDepthBufferEnabled(false), clampToTerrain(false), intoTerrain(false)
|
||||
{
|
||||
fieldOfView = 90.0;
|
||||
|
||||
first = true;
|
||||
|
||||
dirty = false;
|
||||
fovDirty = false;
|
||||
fieldOfView = 90.0;
|
||||
|
||||
#ifdef USE_OSGEARTH
|
||||
logDepthBuffer = NULL;
|
||||
@ -93,21 +78,21 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
bool acceptSceneData(OSGNode *node)
|
||||
bool acceptSceneNode(OSGNode *node)
|
||||
{
|
||||
qDebug() << "OSGCamera::acceptSceneData" << node;
|
||||
if (sceneData == node) {
|
||||
qDebug() << "OSGCamera::acceptSceneNode" << node;
|
||||
if (sceneNode == node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sceneData) {
|
||||
disconnect(sceneData);
|
||||
if (sceneNode) {
|
||||
disconnect(sceneNode);
|
||||
}
|
||||
|
||||
sceneData = node;
|
||||
sceneNode = node;
|
||||
|
||||
if (sceneData) {
|
||||
// connect(sceneData, &OSGNode::nodeChanged, this, &Hidden::onSceneDataChanged);
|
||||
if (sceneNode) {
|
||||
connect(sceneNode, &OSGNode::nodeChanged, this, &Hidden::onSceneNodeChanged);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -125,26 +110,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acceptNode(OSGNode *node)
|
||||
{
|
||||
qDebug() << "OSGCamera::acceptNode" << node;
|
||||
if (this->node == node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->node) {
|
||||
disconnect(this->node);
|
||||
}
|
||||
|
||||
this->node = node;
|
||||
|
||||
if (this->node) {
|
||||
connect(this->node, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onNodeChanged(osg::Node *)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acceptTrackNode(OSGNode *node)
|
||||
{
|
||||
qDebug() << "OSGCamera::acceptTrackNode" << node;
|
||||
@ -170,12 +135,7 @@ public:
|
||||
qDebug() << "OSGCamera::attach" << camera;
|
||||
|
||||
this->camera = camera;
|
||||
|
||||
// TODO don't add update callback as this disables ON_DEMAND frame update scheme
|
||||
// see https://github.com/gwaldron/osgearth/commit/796daf4792ccaf18ae7eb6a5cb268eef0d42888d
|
||||
// see ViewportRenderer::render() in OSGViewport.cpp
|
||||
cameraUpdateCallback = new CameraUpdateCallback(this);
|
||||
camera->addUpdateCallback(cameraUpdateCallback);
|
||||
self->setNode(this->camera.get());
|
||||
|
||||
#ifdef USE_OSGEARTH
|
||||
// install log depth buffer if requested
|
||||
@ -187,9 +147,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
dirty = true;
|
||||
fovDirty = true;
|
||||
updateCamera();
|
||||
updateFieldOfView();
|
||||
updateAspectRatio();
|
||||
}
|
||||
|
||||
@ -203,11 +161,6 @@ public:
|
||||
}
|
||||
this->camera = NULL;
|
||||
|
||||
if (cameraUpdateCallback.valid()) {
|
||||
camera->removeUpdateCallback(cameraUpdateCallback);
|
||||
cameraUpdateCallback = NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_OSGEARTH
|
||||
if (logDepthBuffer) {
|
||||
logDepthBuffer->uninstall(camera);
|
||||
@ -283,11 +236,11 @@ public:
|
||||
}
|
||||
|
||||
view->setCameraManipulator(cm, false);
|
||||
if (cm && node && node->node()) {
|
||||
qDebug() << "OSGCamera::attachManipulator - camera node" << node;
|
||||
if (cm && sceneNode && sceneNode->node()) {
|
||||
qDebug() << "OSGCamera::attachManipulator - camera node" << sceneNode;
|
||||
// set node used to auto compute home position
|
||||
// needs to be done after setting the manipulator on the view as the view will set its scene as the node
|
||||
cm->setNode(node->node());
|
||||
cm->setNode(sceneNode->node());
|
||||
}
|
||||
if (cm) {
|
||||
view->home();
|
||||
@ -301,21 +254,8 @@ public:
|
||||
view->setCameraManipulator(NULL, false);
|
||||
}
|
||||
|
||||
void updateCamera()
|
||||
void updateFieldOfView()
|
||||
{
|
||||
updateCameraFOV();
|
||||
if (manipulatorMode == ManipulatorMode::User) {
|
||||
updateCameraPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void updateCameraFOV()
|
||||
{
|
||||
if (!fovDirty || !camera.valid()) {
|
||||
return;
|
||||
}
|
||||
fovDirty = false;
|
||||
|
||||
qDebug() << "OSGCamera::updateCameraFOV" << fieldOfView;
|
||||
|
||||
double fovy, ar, zn, zf;
|
||||
@ -337,13 +277,11 @@ public:
|
||||
camera->setProjectionMatrixAsPerspective(fovy, ar, zn, zf);
|
||||
}
|
||||
|
||||
void updateCameraPosition()
|
||||
void updatePosition()
|
||||
{
|
||||
if (!dirty || !camera.valid()) {
|
||||
if (manipulatorMode != ManipulatorMode::User) {
|
||||
return;
|
||||
}
|
||||
dirty = false;
|
||||
|
||||
// Altitude mode is absolute (absolute height above MSL/HAE)
|
||||
// HAE : Height above ellipsoid. This is the default.
|
||||
// MSL : Height above Mean Sea Level (MSL) if a geoid separation value is specified.
|
||||
@ -357,8 +295,8 @@ public:
|
||||
#ifdef USE_OSGEARTH
|
||||
osgEarth::GeoPoint geoPoint = osgQtQuick::toGeoPoint(position);
|
||||
if (clampToTerrain) {
|
||||
if (sceneData) {
|
||||
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneData->node());
|
||||
if (sceneNode) {
|
||||
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
||||
if (mapNode) {
|
||||
intoTerrain = clampGeoPoint(geoPoint, 0.5f, mapNode);
|
||||
} else {
|
||||
@ -391,18 +329,18 @@ public:
|
||||
camera->setViewMatrix(cameraMatrix);
|
||||
}
|
||||
|
||||
qreal fieldOfView;
|
||||
bool fovDirty;
|
||||
OSGCamera *const self;
|
||||
|
||||
OSGNode *sceneData;
|
||||
osg::ref_ptr<osg::Camera> camera;
|
||||
|
||||
qreal fieldOfView;
|
||||
|
||||
OSGNode *sceneNode;
|
||||
|
||||
ManipulatorMode::Enum manipulatorMode;
|
||||
|
||||
// to compute home position
|
||||
OSGNode *node;
|
||||
|
||||
// for NodeTrackerManipulator
|
||||
TrackerMode::Enum trackerMode;
|
||||
TrackerMode::Enum trackerMode;
|
||||
OSGNode *trackNode;
|
||||
|
||||
bool logDepthBufferEnabled;
|
||||
@ -410,25 +348,17 @@ public:
|
||||
osgEarth::Util::LogarithmicDepthBuffer *logDepthBuffer;
|
||||
#endif
|
||||
|
||||
bool first;
|
||||
|
||||
// for User manipulator
|
||||
bool dirty;
|
||||
|
||||
bool clampToTerrain;
|
||||
bool intoTerrain;
|
||||
|
||||
QVector3D attitude;
|
||||
QVector3D position;
|
||||
|
||||
osg::ref_ptr<osg::Camera> camera;
|
||||
osg::ref_ptr<CameraUpdateCallback> cameraUpdateCallback;
|
||||
|
||||
private slots:
|
||||
void onNodeChanged(osg::Node *node)
|
||||
void onSceneNodeChanged(osg::Node *node)
|
||||
{
|
||||
qDebug() << "OSGCamera::onNodeChanged" << node;
|
||||
qWarning() << "OSGCamera::onNodeChanged - needs to be implemented";
|
||||
qDebug() << "OSGCamera::onSceneNodeChanged" << node;
|
||||
qWarning() << "OSGCamera::onSceneNodeChanged - needs to be implemented";
|
||||
}
|
||||
|
||||
void onTrackNodeChanged(osg::Node *node)
|
||||
@ -438,16 +368,9 @@ private slots:
|
||||
}
|
||||
};
|
||||
|
||||
/* struct Hidden::CameraUpdateCallback */
|
||||
|
||||
void OSGCamera::Hidden::CameraUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv)
|
||||
{
|
||||
h->updateCamera();
|
||||
}
|
||||
|
||||
/* class OSGCamera */
|
||||
|
||||
OSGCamera::OSGCamera(QObject *parent) : QObject(parent), h(new Hidden(this))
|
||||
OSGCamera::OSGCamera(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
||||
{
|
||||
qDebug() << "OSGCamera::OSGCamera";
|
||||
}
|
||||
@ -455,6 +378,7 @@ OSGCamera::OSGCamera(QObject *parent) : QObject(parent), h(new Hidden(this))
|
||||
OSGCamera::~OSGCamera()
|
||||
{
|
||||
qDebug() << "OSGCamera::~OSGCamera";
|
||||
delete h;
|
||||
}
|
||||
|
||||
qreal OSGCamera::fieldOfView() const
|
||||
@ -467,20 +391,20 @@ void OSGCamera::setFieldOfView(qreal arg)
|
||||
{
|
||||
if (h->fieldOfView != arg) {
|
||||
h->fieldOfView = arg;
|
||||
h->fovDirty = true;
|
||||
setDirty(OSGCamera::FieldOfView);
|
||||
emit fieldOfViewChanged(fieldOfView());
|
||||
}
|
||||
}
|
||||
|
||||
OSGNode *OSGCamera::sceneData()
|
||||
OSGNode *OSGCamera::sceneNode()
|
||||
{
|
||||
return h->sceneData;
|
||||
return h->sceneNode;
|
||||
}
|
||||
|
||||
void OSGCamera::setSceneData(OSGNode *node)
|
||||
void OSGCamera::setSceneNode(OSGNode *node)
|
||||
{
|
||||
if (h->acceptSceneData(node)) {
|
||||
emit sceneDataChanged(node);
|
||||
if (h->acceptSceneNode(node)) {
|
||||
emit sceneNodeChanged(node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,18 +420,6 @@ void OSGCamera::setManipulatorMode(ManipulatorMode::Enum mode)
|
||||
}
|
||||
}
|
||||
|
||||
OSGNode *OSGCamera::node() const
|
||||
{
|
||||
return h->node;
|
||||
}
|
||||
|
||||
void OSGCamera::setNode(OSGNode *node)
|
||||
{
|
||||
if (h->acceptNode(node)) {
|
||||
emit nodeChanged(node);
|
||||
}
|
||||
}
|
||||
|
||||
OSGNode *OSGCamera::trackNode() const
|
||||
{
|
||||
return h->trackNode;
|
||||
@ -542,7 +454,7 @@ void OSGCamera::setClampToTerrain(bool arg)
|
||||
{
|
||||
if (h->clampToTerrain != arg) {
|
||||
h->clampToTerrain = arg;
|
||||
h->dirty = true;
|
||||
setDirty(OSGCamera::All);
|
||||
emit clampToTerrainChanged(clampToTerrain());
|
||||
}
|
||||
}
|
||||
@ -561,7 +473,7 @@ void OSGCamera::setAttitude(QVector3D arg)
|
||||
{
|
||||
if (h->attitude != arg) {
|
||||
h->attitude = arg;
|
||||
h->dirty = true;
|
||||
setDirty(OSGCamera::Attitude);
|
||||
emit attitudeChanged(attitude());
|
||||
}
|
||||
}
|
||||
@ -575,7 +487,7 @@ void OSGCamera::setPosition(QVector3D arg)
|
||||
{
|
||||
if (h->position != arg) {
|
||||
h->position = arg;
|
||||
h->dirty = true;
|
||||
setDirty(OSGCamera::Position);
|
||||
emit positionChanged(position());
|
||||
}
|
||||
}
|
||||
@ -593,6 +505,18 @@ void OSGCamera::setLogarithmicDepthBuffer(bool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
void OSGCamera::update()
|
||||
{
|
||||
// h->updateAspectRatio();
|
||||
if (isDirty(OSGCamera::FieldOfView)) {
|
||||
h->updateFieldOfView();
|
||||
}
|
||||
if (isDirty(OSGCamera::Position) || isDirty(OSGCamera::Attitude) || isDirty(OSGCamera::All)) {
|
||||
h->updatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OSGCamera::attach(osgViewer::View *view)
|
||||
{
|
||||
h->attachCamera(view->getCamera());
|
||||
|
@ -29,6 +29,7 @@
|
||||
#define _H_OSGQTQUICK_OSGCAMERA_H_
|
||||
|
||||
#include "Export.hpp"
|
||||
#include "OSGNode.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector3D>
|
||||
@ -38,8 +39,6 @@ class View;
|
||||
}
|
||||
|
||||
namespace osgQtQuick {
|
||||
class OSGNode;
|
||||
|
||||
class ManipulatorMode : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -64,11 +63,10 @@ public:
|
||||
// TODO
|
||||
// - expose track mode
|
||||
// - provide good default distance and attitude for tracker camera
|
||||
class OSGQTQUICK_EXPORT OSGCamera : public QObject {
|
||||
class OSGQTQUICK_EXPORT OSGCamera : public OSGNode {
|
||||
Q_OBJECT Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged)
|
||||
Q_PROPERTY(osgQtQuick::OSGNode * sceneData READ sceneData WRITE setSceneData NOTIFY sceneDataChanged)
|
||||
Q_PROPERTY(osgQtQuick::OSGNode * sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
||||
Q_PROPERTY(osgQtQuick::ManipulatorMode::Enum manipulatorMode READ manipulatorMode WRITE setManipulatorMode NOTIFY manipulatorModeChanged)
|
||||
Q_PROPERTY(osgQtQuick::OSGNode * node READ node WRITE setNode NOTIFY nodeChanged)
|
||||
Q_PROPERTY(osgQtQuick::OSGNode * trackNode READ trackNode WRITE setTrackNode NOTIFY trackNodeChanged)
|
||||
Q_PROPERTY(osgQtQuick::TrackerMode::Enum trackerMode READ trackerMode WRITE setTrackerMode NOTIFY trackerModeChanged)
|
||||
Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged)
|
||||
@ -77,6 +75,9 @@ class OSGQTQUICK_EXPORT OSGCamera : public QObject {
|
||||
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
||||
Q_PROPERTY(bool logarithmicDepthBuffer READ logarithmicDepthBuffer WRITE setLogarithmicDepthBuffer NOTIFY logarithmicDepthBufferChanged)
|
||||
|
||||
enum DirtyFlag { Position, Attitude, FieldOfView, All };
|
||||
|
||||
|
||||
public:
|
||||
explicit OSGCamera(QObject *parent = 0);
|
||||
virtual ~OSGCamera();
|
||||
@ -88,15 +89,12 @@ public:
|
||||
qreal fieldOfView() const;
|
||||
void setFieldOfView(qreal arg);
|
||||
|
||||
OSGNode *sceneData();
|
||||
void setSceneData(OSGNode *node);
|
||||
OSGNode *sceneNode();
|
||||
void setSceneNode(OSGNode *node);
|
||||
|
||||
ManipulatorMode::Enum manipulatorMode() const;
|
||||
void setManipulatorMode(ManipulatorMode::Enum);
|
||||
|
||||
OSGNode *node() const;
|
||||
void setNode(OSGNode *node);
|
||||
|
||||
OSGNode *trackNode() const;
|
||||
void setTrackNode(OSGNode *node);
|
||||
|
||||
@ -123,12 +121,10 @@ public:
|
||||
signals:
|
||||
void fieldOfViewChanged(qreal arg);
|
||||
|
||||
void sceneDataChanged(OSGNode *node);
|
||||
void sceneNodeChanged(OSGNode *node);
|
||||
|
||||
void manipulatorModeChanged(ManipulatorMode::Enum);
|
||||
|
||||
void nodeChanged(OSGNode *node);
|
||||
|
||||
void trackNodeChanged(OSGNode *node);
|
||||
void trackerModeChanged(TrackerMode::Enum);
|
||||
|
||||
@ -143,6 +139,8 @@ signals:
|
||||
private:
|
||||
struct Hidden;
|
||||
Hidden *h;
|
||||
|
||||
void update();
|
||||
};
|
||||
} // namespace osgQtQuick
|
||||
|
||||
|
@ -75,7 +75,7 @@ private:
|
||||
OSGFileNode * const self;
|
||||
|
||||
public:
|
||||
Hidden(OSGFileNode *parent) : QObject(parent), self(parent), url(), async(false), optimizeMode(OptimizeMode::None) {}
|
||||
Hidden(OSGFileNode *node) : QObject(node), self(node), url(), async(false), optimizeMode(OptimizeMode::None) {}
|
||||
|
||||
bool acceptSource(QUrl url)
|
||||
{
|
||||
@ -157,6 +157,7 @@ OSGFileNode::OSGFileNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
||||
OSGFileNode::~OSGFileNode()
|
||||
{
|
||||
qDebug() << "OSGFileNode::~OSGFileNode";
|
||||
delete h;
|
||||
}
|
||||
|
||||
const QUrl OSGFileNode::source() const
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file OSGTransformNode.cpp
|
||||
* @file OSGGeoTransformNode.cpp
|
||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
||||
* @addtogroup
|
||||
* @{
|
||||
@ -41,22 +41,9 @@ 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()
|
||||
Hidden(OSGGeoTransformNode *node) : QObject(node), self(node), childNode(NULL), sceneNode(NULL), offset(-1.0), clampToTerrain(false), intoTerrain(false)
|
||||
{}
|
||||
|
||||
bool acceptChildNode(OSGNode *node)
|
||||
@ -71,7 +58,6 @@ public:
|
||||
}
|
||||
|
||||
childNode = node;
|
||||
dirty = true;
|
||||
|
||||
if (childNode) {
|
||||
connect(childNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onChildNodeChanged(osg::Node *)));
|
||||
@ -92,7 +78,6 @@ public:
|
||||
}
|
||||
|
||||
sceneNode = node;
|
||||
dirty = true;
|
||||
|
||||
if (sceneNode) {
|
||||
connect(sceneNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onSceneNodeChanged(osg::Node *)));
|
||||
@ -103,11 +88,6 @@ public:
|
||||
|
||||
void updateNode()
|
||||
{
|
||||
if (!dirty) {
|
||||
return;
|
||||
}
|
||||
dirty = false;
|
||||
|
||||
// qDebug() << "OSGGeoTransformNode::updateNode" << this;
|
||||
|
||||
osgEarth::GeoTransform *transform = getOrCreateTransform();
|
||||
@ -168,8 +148,6 @@ public:
|
||||
transform = new osgEarth::GeoTransform();
|
||||
transform->setAutoRecomputeHeights(true);
|
||||
|
||||
transform->addUpdateCallback(new NodeUpdateCallback(this));
|
||||
|
||||
self->setNode(transform);
|
||||
|
||||
return transform.get();
|
||||
@ -177,11 +155,11 @@ public:
|
||||
|
||||
OSGGeoTransformNode *const self;
|
||||
|
||||
OSGNode *childNode;
|
||||
OSGNode *sceneNode;
|
||||
|
||||
osg::ref_ptr<osgEarth::GeoTransform> transform;
|
||||
|
||||
OSGNode *childNode;
|
||||
OSGNode *sceneNode;
|
||||
|
||||
float offset;
|
||||
|
||||
bool clampToTerrain;
|
||||
@ -189,31 +167,21 @@ public:
|
||||
|
||||
QVector3D position;
|
||||
|
||||
bool dirty;
|
||||
|
||||
private slots:
|
||||
|
||||
void onChildNodeChanged(osg::Node *node)
|
||||
{
|
||||
qDebug() << "OSGGeoTransformNode::onChildNodeChanged" << node;
|
||||
dirty = true;
|
||||
self->setDirty();
|
||||
}
|
||||
|
||||
void onSceneNodeChanged(osg::Node *node)
|
||||
{
|
||||
qDebug() << "OSGGeoTransformNode::onSceneNodeChanged" << node;
|
||||
dirty = true;
|
||||
self->setDirty();
|
||||
}
|
||||
};
|
||||
|
||||
/* 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";
|
||||
@ -222,6 +190,7 @@ OSGGeoTransformNode::OSGGeoTransformNode(QObject *parent) : OSGNode(parent), h(n
|
||||
OSGGeoTransformNode::~OSGGeoTransformNode()
|
||||
{
|
||||
qDebug() << "OSGGeoTransformNode::~OSGGeoTransformNode";
|
||||
delete h;
|
||||
}
|
||||
|
||||
OSGNode *OSGGeoTransformNode::modelData()
|
||||
@ -257,7 +226,7 @@ void OSGGeoTransformNode::setClampToTerrain(bool arg)
|
||||
{
|
||||
if (h->clampToTerrain != arg) {
|
||||
h->clampToTerrain = arg;
|
||||
h->dirty = true;
|
||||
setDirty();
|
||||
emit clampToTerrainChanged(clampToTerrain());
|
||||
}
|
||||
}
|
||||
@ -276,18 +245,23 @@ void OSGGeoTransformNode::setPosition(QVector3D arg)
|
||||
{
|
||||
if (h->position != arg) {
|
||||
h->position = arg;
|
||||
h->dirty = true;
|
||||
setDirty();
|
||||
emit positionChanged(position());
|
||||
}
|
||||
}
|
||||
|
||||
void OSGGeoTransformNode::update()
|
||||
{
|
||||
h->updateNode();
|
||||
}
|
||||
|
||||
void OSGGeoTransformNode::attach(osgViewer::View *view)
|
||||
{
|
||||
// qDebug() << "OSGGeoTransformNode::attach " << view;
|
||||
if (h->childNode) {
|
||||
h->childNode->attach(view);
|
||||
}
|
||||
h->updateNode();
|
||||
update();
|
||||
}
|
||||
|
||||
void OSGGeoTransformNode::detach(osgViewer::View *view)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file OSGTransformNode.hpp
|
||||
* @file OSGGeoTransformNode.hpp
|
||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
||||
* @addtogroup
|
||||
* @{
|
||||
@ -81,6 +81,8 @@ signals:
|
||||
private:
|
||||
struct Hidden;
|
||||
Hidden *h;
|
||||
|
||||
virtual void update();
|
||||
};
|
||||
} // namespace osgQtQuick
|
||||
|
||||
|
@ -37,10 +37,8 @@ struct OSGGroup::Hidden : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Hidden(OSGGroup *parent) : QObject(parent), self(parent)
|
||||
{
|
||||
group = new osg::Group;
|
||||
}
|
||||
Hidden(OSGGroup *node) : QObject(node), self(node), group(new osg::Group)
|
||||
{}
|
||||
|
||||
OSGGroup *self;
|
||||
|
||||
@ -135,6 +133,7 @@ OSGGroup::OSGGroup(QObject *parent) :
|
||||
OSGGroup::~OSGGroup()
|
||||
{
|
||||
qDebug() << "OSGGroup::~OSGGroup";
|
||||
delete h;
|
||||
}
|
||||
|
||||
QQmlListProperty<OSGNode> OSGGroup::children()
|
||||
|
@ -28,15 +28,118 @@
|
||||
#include "OSGNode.hpp"
|
||||
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
|
||||
#include <QListIterator>
|
||||
#include <qDebug>
|
||||
|
||||
namespace osgQtQuick {
|
||||
struct OSGNode::Hidden {
|
||||
osg::ref_ptr<osg::Node> node;
|
||||
class OSGNode;
|
||||
class Hidden;
|
||||
|
||||
struct NodeUpdateCallback : public osg::NodeCallback {
|
||||
public:
|
||||
NodeUpdateCallback(OSGNode::Hidden *h) : h(h) {}
|
||||
|
||||
void operator()(osg::Node *node, osg::NodeVisitor *nv);
|
||||
|
||||
private:
|
||||
OSGNode::Hidden *const h;
|
||||
};
|
||||
|
||||
OSGNode::OSGNode(QObject *parent) : QObject(parent), h(new Hidden)
|
||||
|
||||
struct OSGNode::Hidden /*: public QObject*/ {
|
||||
// Q_OBJECT
|
||||
|
||||
friend class OSGNode;
|
||||
public:
|
||||
Hidden(OSGNode *node) : /*QObject(node),*/ self(node), dirty(0)
|
||||
{}
|
||||
|
||||
bool isDirty(int flag)
|
||||
{
|
||||
return (dirty && (1 << flag)) != 0;
|
||||
}
|
||||
|
||||
void setDirty(int flag)
|
||||
{
|
||||
// qDebug() << "OSGNode::setDirty BEGIN";
|
||||
if (!dirty) {
|
||||
if (node) {
|
||||
if (!nodeUpdateCallback.valid()) {
|
||||
// lazy creation
|
||||
// qDebug() << "OSGNode::setDirty CREATE";
|
||||
nodeUpdateCallback = new NodeUpdateCallback(this);
|
||||
}
|
||||
// qDebug() << "OSGNode::setDirty ADD" << node;
|
||||
node->setUpdateCallback(nodeUpdateCallback);
|
||||
}
|
||||
}
|
||||
dirty |= 1 << flag;
|
||||
// qDebug() << "OSGNode::setDirty DONE";
|
||||
}
|
||||
|
||||
void clearDirty()
|
||||
{
|
||||
dirty = 0;
|
||||
if (node && nodeUpdateCallback.valid()) {
|
||||
// qDebug() << "OSGNode::clearDirty REMOVE CALLBACK";
|
||||
node->setUpdateCallback(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
// qDebug() << "OSGNode::update BEGIN";
|
||||
if (dirty) {
|
||||
// qDebug() << "OSGNode::update UPDATE";
|
||||
self->update();
|
||||
}
|
||||
clearDirty();
|
||||
// qDebug() << "OSGNode::update DONE";
|
||||
}
|
||||
|
||||
bool acceptNode(osg::Node *aNode)
|
||||
{
|
||||
if (node == aNode) {
|
||||
return false;
|
||||
}
|
||||
if (node && dirty) {
|
||||
// qDebug() << "OSGNode::acceptNode REMOVE CALLBACK" << node;
|
||||
node->setUpdateCallback(NULL);
|
||||
}
|
||||
node = aNode;
|
||||
if (node) {
|
||||
if (dirty) {
|
||||
if (!nodeUpdateCallback.valid()) {
|
||||
// lazy creation
|
||||
// qDebug() << "OSGNode::acceptNode CREATE CALLBACK";
|
||||
nodeUpdateCallback = new NodeUpdateCallback(this);
|
||||
}
|
||||
// qDebug() << "OSGNode::acceptNode ADD CALLBACK";
|
||||
node->setUpdateCallback(nodeUpdateCallback);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
OSGNode *const self;
|
||||
|
||||
osg::ref_ptr<osg::Node> node;
|
||||
|
||||
osg::ref_ptr<osg::NodeCallback> nodeUpdateCallback;
|
||||
|
||||
int dirty;
|
||||
};
|
||||
|
||||
void NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv)
|
||||
{
|
||||
// qDebug() << "NodeUpdateCallback::";
|
||||
nv->traverse(*node);
|
||||
h->update();
|
||||
}
|
||||
|
||||
OSGNode::OSGNode(QObject *parent) : QObject(parent), h(new Hidden(this))
|
||||
{}
|
||||
|
||||
OSGNode::~OSGNode()
|
||||
@ -51,12 +154,31 @@ osg::Node *OSGNode::node() const
|
||||
|
||||
void OSGNode::setNode(osg::Node *node)
|
||||
{
|
||||
if (h->node.get() != node) {
|
||||
h->node = node;
|
||||
if (h->acceptNode(node)) {
|
||||
emit nodeChanged(node);
|
||||
}
|
||||
}
|
||||
|
||||
bool OSGNode::isDirty()
|
||||
{
|
||||
return h->isDirty(1);
|
||||
}
|
||||
|
||||
bool OSGNode::isDirty(int flag)
|
||||
{
|
||||
return h->isDirty(flag);
|
||||
}
|
||||
|
||||
void OSGNode::setDirty()
|
||||
{
|
||||
h->setDirty(1);
|
||||
}
|
||||
|
||||
void OSGNode::setDirty(int flag)
|
||||
{
|
||||
h->setDirty(flag);
|
||||
}
|
||||
|
||||
void OSGNode::attach(osgViewer::View *view)
|
||||
{}
|
||||
|
||||
|
@ -32,6 +32,18 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
/**
|
||||
* Only update() methods are allowed to update the OSG scenegraph.
|
||||
* All other methods should call setDirty() which will later trigger an update.
|
||||
* Exceptions:
|
||||
* - node change events should be handled right away.
|
||||
*
|
||||
* Setting an OSGNode dirty will trigger the addition of a one time update callback.
|
||||
* *
|
||||
* This approach leads to some potential issues:
|
||||
* - if a child sets a parent dirty, the parent will be updated later on the next update traversal (i.e. before the next frame).
|
||||
*
|
||||
*/
|
||||
namespace osg {
|
||||
class Node;
|
||||
} // namespace osg
|
||||
@ -44,6 +56,8 @@ namespace osgQtQuick {
|
||||
class OSGQTQUICK_EXPORT OSGNode : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
friend class NodeUpdateCallback;
|
||||
|
||||
public:
|
||||
explicit OSGNode(QObject *parent = 0);
|
||||
virtual ~OSGNode();
|
||||
@ -54,12 +68,20 @@ public:
|
||||
virtual void attach(osgViewer::View *view);
|
||||
virtual void detach(osgViewer::View *view);
|
||||
|
||||
protected:
|
||||
bool isDirty();
|
||||
bool isDirty(int flag);
|
||||
void setDirty();
|
||||
void setDirty(int flag);
|
||||
|
||||
signals:
|
||||
void nodeChanged(osg::Node *node) const;
|
||||
|
||||
private:
|
||||
struct Hidden;
|
||||
Hidden *h;
|
||||
|
||||
virtual void update() {};
|
||||
};
|
||||
} // namespace osgQtQuick
|
||||
|
||||
|
@ -41,7 +41,7 @@ struct OSGShapeNode::Hidden : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Hidden(OSGShapeNode *parent) : QObject(parent), self(parent), shapeType(ShapeType::Sphere) {}
|
||||
Hidden(OSGShapeNode *node) : QObject(node), self(node), shapeType(ShapeType::Sphere) {}
|
||||
|
||||
void realize()
|
||||
{
|
||||
@ -97,6 +97,7 @@ OSGShapeNode::OSGShapeNode(QObject *parent) : OSGNode(parent), h(new Hidden(this
|
||||
OSGShapeNode::~OSGShapeNode()
|
||||
{
|
||||
qDebug() << "OSGShapeNode::~OSGShapeNode";
|
||||
delete h;
|
||||
}
|
||||
|
||||
ShapeType::Enum OSGShapeNode::shapeType() const
|
||||
|
@ -43,8 +43,7 @@ struct OSGSkyNode::Hidden : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Hidden(OSGSkyNode *parent) : QObject(parent),
|
||||
self(parent), sceneData(NULL), sunLightEnabled(true), minimumAmbientLight(0.03)
|
||||
Hidden(OSGSkyNode *node) : QObject(node), self(node), sceneData(NULL), sunLightEnabled(true), minimumAmbientLight(0.03)
|
||||
{
|
||||
dateTime = QDateTime::currentDateTime();
|
||||
}
|
||||
@ -223,6 +222,7 @@ OSGSkyNode::OSGSkyNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
||||
OSGSkyNode::~OSGSkyNode()
|
||||
{
|
||||
qDebug() << "OSGSkyNode::~OSGSkyNode";
|
||||
delete h;
|
||||
}
|
||||
|
||||
OSGNode *OSGSkyNode::sceneData()
|
||||
|
@ -42,9 +42,7 @@ public:
|
||||
osg::ref_ptr<osgText::Text> text;
|
||||
};
|
||||
|
||||
OSGTextNode::OSGTextNode(QObject *parent) :
|
||||
osgQtQuick::OSGNode(parent),
|
||||
h(new Hidden)
|
||||
OSGTextNode::OSGTextNode(QObject *node) : OSGNode(node), h(new Hidden)
|
||||
{
|
||||
osg::ref_ptr<osgText::Font> textFont = createFont(QFont("Times"));
|
||||
|
||||
|
@ -37,22 +37,9 @@ namespace osgQtQuick {
|
||||
struct OSGTransformNode::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(OSGTransformNode *parent) : QObject(parent), self(parent), childNode(NULL), dirty(false)
|
||||
{}
|
||||
|
||||
~Hidden()
|
||||
Hidden(OSGTransformNode *node) : QObject(node), self(node), childNode(NULL)
|
||||
{}
|
||||
|
||||
bool acceptChildNode(OSGNode *node)
|
||||
@ -67,7 +54,6 @@ public:
|
||||
}
|
||||
|
||||
childNode = node;
|
||||
dirty = true;
|
||||
|
||||
if (childNode) {
|
||||
connect(childNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onChildNodeChanged(osg::Node *)));
|
||||
@ -78,11 +64,6 @@ public:
|
||||
|
||||
void updateNode()
|
||||
{
|
||||
if (!dirty) {
|
||||
return;
|
||||
}
|
||||
dirty = false;
|
||||
|
||||
// qDebug() << "OSGTransformNode::updateNode" << this;
|
||||
|
||||
osg::PositionAttitudeTransform *transform = getOrCreateTransform();
|
||||
@ -131,7 +112,6 @@ public:
|
||||
|
||||
transform = new osg::PositionAttitudeTransform();
|
||||
|
||||
transform->addUpdateCallback(new NodeUpdateCallback(this));
|
||||
|
||||
self->setNode(transform);
|
||||
|
||||
@ -140,33 +120,23 @@ public:
|
||||
|
||||
OSGTransformNode *const self;
|
||||
|
||||
OSGNode *childNode;
|
||||
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> transform;
|
||||
|
||||
OSGNode *childNode;
|
||||
|
||||
QVector3D scale;
|
||||
QVector3D attitude;
|
||||
QVector3D position;
|
||||
|
||||
bool dirty;
|
||||
|
||||
private slots:
|
||||
|
||||
void onChildNodeChanged(osg::Node *node)
|
||||
{
|
||||
qDebug() << "OSGTransformNode::onChildNodeChanged" << node;
|
||||
dirty = true;
|
||||
self->setDirty();
|
||||
}
|
||||
};
|
||||
|
||||
/* struct Hidden::NodeUpdateCallback */
|
||||
|
||||
void OSGTransformNode::Hidden::NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv)
|
||||
{
|
||||
nv->traverse(*node);
|
||||
h->updateNode();
|
||||
}
|
||||
|
||||
OSGTransformNode::OSGTransformNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
||||
{
|
||||
qDebug() << "OSGTransformNode::OSGTransformNode";
|
||||
@ -175,6 +145,7 @@ OSGTransformNode::OSGTransformNode(QObject *parent) : OSGNode(parent), h(new Hid
|
||||
OSGTransformNode::~OSGTransformNode()
|
||||
{
|
||||
qDebug() << "OSGTransformNode::~OSGTransformNode";
|
||||
delete h;
|
||||
}
|
||||
|
||||
OSGNode *OSGTransformNode::modelData()
|
||||
@ -198,7 +169,7 @@ void OSGTransformNode::setScale(QVector3D arg)
|
||||
{
|
||||
if (h->scale != arg) {
|
||||
h->scale = arg;
|
||||
h->dirty = true;
|
||||
setDirty();
|
||||
emit scaleChanged(scale());
|
||||
}
|
||||
}
|
||||
@ -212,7 +183,7 @@ void OSGTransformNode::setAttitude(QVector3D arg)
|
||||
{
|
||||
if (h->attitude != arg) {
|
||||
h->attitude = arg;
|
||||
h->dirty = true;
|
||||
setDirty();
|
||||
emit attitudeChanged(attitude());
|
||||
}
|
||||
}
|
||||
@ -226,18 +197,23 @@ void OSGTransformNode::setPosition(QVector3D arg)
|
||||
{
|
||||
if (h->position != arg) {
|
||||
h->position = arg;
|
||||
h->dirty = true;
|
||||
setDirty();
|
||||
emit positionChanged(position());
|
||||
}
|
||||
}
|
||||
|
||||
void OSGTransformNode::update()
|
||||
{
|
||||
h->updateNode();
|
||||
}
|
||||
|
||||
void OSGTransformNode::attach(osgViewer::View *view)
|
||||
{
|
||||
// qDebug() << "OSGTransformNode::attach " << view;
|
||||
if (h->childNode) {
|
||||
h->childNode->attach(view);
|
||||
}
|
||||
h->updateNode();
|
||||
update();
|
||||
}
|
||||
|
||||
void OSGTransformNode::detach(osgViewer::View *view)
|
||||
|
@ -73,6 +73,8 @@ signals:
|
||||
private:
|
||||
struct Hidden;
|
||||
Hidden *h;
|
||||
|
||||
virtual void update();
|
||||
};
|
||||
} // namespace osgQtQuick
|
||||
|
||||
|
@ -84,8 +84,8 @@ struct OSGViewport::Hidden : public QObject {
|
||||
|
||||
public:
|
||||
|
||||
Hidden(OSGViewport *quickItem) : QObject(quickItem),
|
||||
self(quickItem),
|
||||
Hidden(OSGViewport *viewport) : QObject(viewport),
|
||||
self(viewport),
|
||||
window(NULL),
|
||||
sceneData(NULL),
|
||||
camera(NULL),
|
||||
@ -96,7 +96,7 @@ public:
|
||||
|
||||
createViewer();
|
||||
|
||||
connect(quickItem, &OSGViewport::windowChanged, this, &Hidden::onWindowChanged);
|
||||
connect(self, &OSGViewport::windowChanged, this, &Hidden::onWindowChanged);
|
||||
}
|
||||
|
||||
~Hidden()
|
||||
@ -493,20 +493,28 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
needToDoFrame = h->viewer->checkNeedToDoFrame();
|
||||
if (needToDoFrame) {
|
||||
if (firstFrame) {
|
||||
h->view->init();
|
||||
if (!h->viewer->isRealized()) {
|
||||
h->viewer->realize();
|
||||
}
|
||||
firstFrame = false;
|
||||
}
|
||||
osg::Viewport *viewport = h->view->getCamera()->getViewport();
|
||||
if ((viewport->width() != item->width()) || (viewport->height() != item->height())) {
|
||||
h->view->getCamera()->getGraphicsContext()->resized(0, 0, item->width(), item->height());
|
||||
if (firstFrame) {
|
||||
h->view->init();
|
||||
if (!h->viewer->isRealized()) {
|
||||
h->viewer->realize();
|
||||
}
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
needToDoFrame = false;
|
||||
osg::Viewport *viewport = h->view->getCamera()->getViewport();
|
||||
if ((viewport->width() != item->width()) || (viewport->height() != item->height())) {
|
||||
needToDoFrame = true;
|
||||
h->view->getCamera()->getGraphicsContext()->resized(0, 0, item->width(), item->height());
|
||||
}
|
||||
|
||||
if (!needToDoFrame) {
|
||||
needToDoFrame = h->viewer->checkNeedToDoFrame();
|
||||
}
|
||||
if (!needToDoFrame) {
|
||||
needToDoFrame = !h->view->getEventQueue()->empty();
|
||||
}
|
||||
if (needToDoFrame) {
|
||||
h->viewer->advance();
|
||||
h->viewer->eventTraversal();
|
||||
h->viewer->updateTraversal();
|
||||
@ -577,6 +585,7 @@ OSGViewport::OSGViewport(QQuickItem *parent) : QQuickFramebufferObject(parent),
|
||||
OSGViewport::~OSGViewport()
|
||||
{
|
||||
qDebug() << "OSGViewport::~OSGViewport";
|
||||
delete h;
|
||||
}
|
||||
|
||||
UpdateMode::Enum OSGViewport::updateMode() const
|
||||
|
@ -444,6 +444,7 @@ QString getUsageString(osgViewer::CompositeViewer *viewer)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ OSGViewport {
|
||||
logarithmicDepthBuffer: true
|
||||
manipulatorMode: ManipulatorMode.Track
|
||||
// use model to compute camera home position
|
||||
node: modelTransformNode
|
||||
sceneNode: modelTransformNode
|
||||
// model will be tracked
|
||||
trackNode: modelTransformNode
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ Item {
|
||||
OSGCamera {
|
||||
id: camera
|
||||
fieldOfView: 90
|
||||
node: transformNode
|
||||
sceneNode: transformNode
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ OSGViewport {
|
||||
OSGCamera {
|
||||
id: camera
|
||||
fieldOfView: 100
|
||||
sceneData: terrainNode
|
||||
sceneNode: terrainNode
|
||||
logarithmicDepthBuffer: true
|
||||
clampToTerrain: true
|
||||
manipulatorMode: ManipulatorMode.User
|
||||
|
Loading…
Reference in New Issue
Block a user