mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Merged in filnet/librepilot/filnet/LP-29_osgearth_integration (pull request #222)
LP-29_osgearth_integration
This commit is contained in:
commit
23f1867746
148
ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.cpp
Normal file
148
ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file DirtySupport.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "DirtySupport.hpp"
|
||||||
|
|
||||||
|
#include <osg/Node>
|
||||||
|
#include <osg/NodeVisitor>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
class Hidden;
|
||||||
|
|
||||||
|
struct DirtySupport::NodeUpdateCallback : public osg::NodeCallback {
|
||||||
|
public:
|
||||||
|
NodeUpdateCallback(DirtySupport::Hidden *h) : h(h)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(osg::Node *node, osg::NodeVisitor *nv);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DirtySupport::Hidden *const h;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DirtySupport::Hidden {
|
||||||
|
private:
|
||||||
|
DirtySupport *const self;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::NodeCallback> nodeUpdateCallback;
|
||||||
|
|
||||||
|
int dirtyFlags;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Hidden(DirtySupport *self) : self(self), dirtyFlags(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool isDirty(int mask) const
|
||||||
|
{
|
||||||
|
return (dirtyFlags & mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dirty() const
|
||||||
|
{
|
||||||
|
return dirtyFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDirty(int mask)
|
||||||
|
{
|
||||||
|
// qDebug() << "DirtySupport::setDirty" << mask;
|
||||||
|
if (!dirtyFlags) {
|
||||||
|
osg::Node *node = self->nodeToUpdate();
|
||||||
|
if (node) {
|
||||||
|
if (!nodeUpdateCallback.valid()) {
|
||||||
|
// lazy creation
|
||||||
|
nodeUpdateCallback = new NodeUpdateCallback(this);
|
||||||
|
}
|
||||||
|
node->addUpdateCallback(nodeUpdateCallback.get());
|
||||||
|
} else {
|
||||||
|
// qWarning() << "DirtySupport::setDirty - node to update is null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirtyFlags |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearDirty()
|
||||||
|
{
|
||||||
|
osg::Node *node = self->nodeToUpdate();
|
||||||
|
|
||||||
|
if (node && nodeUpdateCallback.valid()) {
|
||||||
|
node->removeUpdateCallback(nodeUpdateCallback.get());
|
||||||
|
}
|
||||||
|
dirtyFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
// qDebug() << "DirtySupport::update";
|
||||||
|
if (dirtyFlags) {
|
||||||
|
// qDebug() << "DirtySupport::update - updating...";
|
||||||
|
self->update();
|
||||||
|
}
|
||||||
|
clearDirty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* struct DirtySupport::NodeUpdateCallback */
|
||||||
|
|
||||||
|
void DirtySupport::NodeUpdateCallback::operator()(osg::Node *node, osg::NodeVisitor *nv)
|
||||||
|
{
|
||||||
|
// qDebug() << "DirtySupport::NodeUpdateCallback";
|
||||||
|
nv->traverse(*node);
|
||||||
|
h->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* class DirtySupport */
|
||||||
|
|
||||||
|
DirtySupport::DirtySupport() : h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
DirtySupport::~DirtySupport()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirtySupport::dirty() const
|
||||||
|
{
|
||||||
|
return h->dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DirtySupport::isDirty(int mask) const
|
||||||
|
{
|
||||||
|
return h->isDirty(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtySupport::setDirty(int mask)
|
||||||
|
{
|
||||||
|
h->setDirty(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtySupport::clearDirty()
|
||||||
|
{
|
||||||
|
h->clearDirty();
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
63
ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.hpp
Normal file
63
ground/gcs/src/libs/osgearth/osgQtQuick/DirtySupport.hpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file DirtySupport.hpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_OSGQTQUICK_DIRTYSUPPORT_H_
|
||||||
|
#define _H_OSGQTQUICK_DIRTYSUPPORT_H_
|
||||||
|
|
||||||
|
namespace osg {
|
||||||
|
class Node;
|
||||||
|
} // namespace osg
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
/**
|
||||||
|
* Provides support to:
|
||||||
|
* - manage dirty state flags
|
||||||
|
* - add/remove node callback to trigger refresh (compatible with viewer on demand mode)
|
||||||
|
*/
|
||||||
|
class DirtySupport {
|
||||||
|
public:
|
||||||
|
explicit DirtySupport();
|
||||||
|
virtual ~DirtySupport();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int dirty() const;
|
||||||
|
bool isDirty(int mask = 0xFFFF) const;
|
||||||
|
void setDirty(int mask = 0xFFFF);
|
||||||
|
void clearDirty();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Hidden;
|
||||||
|
struct NodeUpdateCallback;
|
||||||
|
Hidden *const h;
|
||||||
|
|
||||||
|
virtual osg::Node *nodeToUpdate() const = 0;
|
||||||
|
|
||||||
|
virtual void update() = 0;
|
||||||
|
};
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#endif // _H_OSGQTQUICK_DIRTYSUPPORT_H_
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file Export.hpp
|
* @file Export.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
*
|
|
||||||
* @file OSGBackgroundNode.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 "OSGBackgroundNode.hpp"
|
|
||||||
|
|
||||||
#include <osg/Depth>
|
|
||||||
#include <osg/Texture2D>
|
|
||||||
#include <osgDB/ReadFile>
|
|
||||||
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
namespace osgQtQuick {
|
|
||||||
struct OSGBackgroundNode::Hidden : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
OSGBackgroundNode * const self;
|
|
||||||
|
|
||||||
public:
|
|
||||||
QUrl url;
|
|
||||||
|
|
||||||
Hidden(OSGBackgroundNode *parent) : QObject(parent), self(parent), url() {}
|
|
||||||
|
|
||||||
void updateNode()
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGBackgroundNode::realize - reading image file" << url.path();
|
|
||||||
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
|
|
||||||
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(url.path().toStdString());
|
|
||||||
|
|
||||||
texture->setImage(image.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Drawable> quad = osg::createTexturedQuadGeometry(
|
|
||||||
osg::Vec3(), osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
|
||||||
geode->addDrawable(quad.get());
|
|
||||||
|
|
||||||
osg::Camera *camera = new osg::Camera;
|
|
||||||
camera->setClearMask(0);
|
|
||||||
camera->setCullingActive(false);
|
|
||||||
camera->setAllowEventFocus(false);
|
|
||||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
|
||||||
camera->setRenderOrder(osg::Camera::POST_RENDER);
|
|
||||||
camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0));
|
|
||||||
camera->addChild(geode.get());
|
|
||||||
|
|
||||||
osg::StateSet *ss = camera->getOrCreateStateSet();
|
|
||||||
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
|
||||||
ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0));
|
|
||||||
|
|
||||||
self->setNode(camera);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* class OSGBackgroundNode */
|
|
||||||
|
|
||||||
enum DirtyFlag { URL = 1 << 0 };
|
|
||||||
|
|
||||||
OSGBackgroundNode::OSGBackgroundNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
|
||||||
{
|
|
||||||
qDebug() << "OSGBackgroundNode::OSGBackgroundNode";
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGBackgroundNode::~OSGBackgroundNode()
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGBackgroundNode::~OSGBackgroundNode";
|
|
||||||
delete h;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QUrl OSGBackgroundNode::imageFile() const
|
|
||||||
{
|
|
||||||
return h->url;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGBackgroundNode::setImageFile(const QUrl &url)
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGBackgroundNode::setImageFile" << url;
|
|
||||||
if (h->url != url) {
|
|
||||||
h->url = url;
|
|
||||||
setDirty(URL);
|
|
||||||
emit imageFileChanged(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGBackgroundNode::update()
|
|
||||||
{
|
|
||||||
if (isDirty(URL)) {
|
|
||||||
h->updateNode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGBackgroundNode::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGBackgroundNode::detach(osgViewer::View *view)
|
|
||||||
{}
|
|
||||||
} // namespace osgQtQuick
|
|
||||||
|
|
||||||
#include "OSGBackgroundNode.moc"
|
|
94
ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.cpp
Normal file
94
ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGBillboardNode.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "OSGBillboardNode.hpp"
|
||||||
|
|
||||||
|
#include <osg/Depth>
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
#include <osg/ImageSequence>
|
||||||
|
|
||||||
|
#include <osgDB/ReadFile>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
// NOTE : these flags should not overlap with OSGGroup flags!!!
|
||||||
|
// TODO : find a better way...
|
||||||
|
enum DirtyFlag {};
|
||||||
|
|
||||||
|
struct OSGBillboardNode::Hidden : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGBillboardNode * const self;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Camera> camera;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Hidden(OSGBillboardNode *self) : QObject(self), self(self)
|
||||||
|
{}
|
||||||
|
|
||||||
|
osg::Node *createNode()
|
||||||
|
{
|
||||||
|
camera = new osg::Camera;
|
||||||
|
camera->setClearMask(0);
|
||||||
|
camera->setCullingActive(false);
|
||||||
|
camera->setAllowEventFocus(false);
|
||||||
|
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||||
|
camera->setRenderOrder(osg::Camera::POST_RENDER);
|
||||||
|
camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
osg::StateSet *ss = camera->getOrCreateStateSet();
|
||||||
|
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0));
|
||||||
|
|
||||||
|
return camera;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class OSGBillboardNode */
|
||||||
|
|
||||||
|
OSGBillboardNode::OSGBillboardNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
OSGBillboardNode::~OSGBillboardNode()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Node *OSGBillboardNode::createNode()
|
||||||
|
{
|
||||||
|
return h->createNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGBillboardNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#include "OSGBillboardNode.moc"
|
54
ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.hpp
Normal file
54
ground/gcs/src/libs/osgearth/osgQtQuick/OSGBillboardNode.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGBillboardNode.hpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_OSGQTQUICK_BILLBOARDNODE_H_
|
||||||
|
#define _H_OSGQTQUICK_BILLBOARDNODE_H_
|
||||||
|
|
||||||
|
#include "Export.hpp"
|
||||||
|
#include "OSGGroup.hpp"
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
class OSGQTQUICK_EXPORT OSGBillboardNode : public OSGGroup {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
typedef OSGGroup Inherited;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OSGBillboardNode(QObject *parent = 0);
|
||||||
|
virtual ~OSGBillboardNode();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Hidden;
|
||||||
|
Hidden *const h;
|
||||||
|
};
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#endif // _H_OSGQTQUICK_BILLBOARDNODE_H_
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGCamera.cpp
|
* @file OSGCamera.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,41 +27,45 @@
|
|||||||
|
|
||||||
#include "OSGCamera.hpp"
|
#include "OSGCamera.hpp"
|
||||||
|
|
||||||
#include "OSGNode.hpp"
|
|
||||||
|
|
||||||
#include "../utility.h"
|
|
||||||
|
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
#include <osg/Matrix>
|
|
||||||
#include <osg/Node>
|
#include <osg/Node>
|
||||||
#include <osg/Vec3d>
|
|
||||||
|
|
||||||
#include <osgGA/NodeTrackerManipulator>
|
|
||||||
#include <osgGA/TrackballManipulator>
|
|
||||||
|
|
||||||
#include <osgViewer/View>
|
|
||||||
|
|
||||||
#ifdef USE_OSGEARTH
|
#ifdef USE_OSGEARTH
|
||||||
#include <osgEarthUtil/EarthManipulator>
|
|
||||||
#include <osgEarthUtil/LogarithmicDepthBuffer>
|
#include <osgEarthUtil/LogarithmicDepthBuffer>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QThread>
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { FieldOfView = 1 << 0, ClearColor = 1 << 1, LogDepthBuffer = 1 << 4 };
|
||||||
|
|
||||||
struct OSGCamera::Hidden : public QObject {
|
struct OSGCamera::Hidden : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
private:
|
||||||
Hidden(OSGCamera *camera) :
|
OSGCamera * const self;
|
||||||
QObject(camera), self(camera), sceneNode(NULL),
|
|
||||||
manipulatorMode(ManipulatorMode::Default), trackerMode(TrackerMode::NodeCenterAndAzim), trackNode(NULL),
|
|
||||||
logDepthBufferEnabled(false), clampToTerrain(false), intoTerrain(false)
|
|
||||||
{
|
|
||||||
fieldOfView = 90.0;
|
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Camera> camera;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Camera vertical field of view in degrees
|
||||||
|
// fov depends on the scenery space (probably distance)
|
||||||
|
// here are some value: 75°, 60°, 45° many gamers use
|
||||||
|
// x-plane uses 45° for 4:3 and 60° for 16:9/16:10
|
||||||
|
// flightgear uses 55° / 70°
|
||||||
|
qreal fieldOfView;
|
||||||
|
|
||||||
|
QColor clearColor;
|
||||||
|
|
||||||
|
bool logDepthBufferEnabled;
|
||||||
|
|
||||||
|
#ifdef USE_OSGEARTH
|
||||||
|
osgEarth::Util::LogarithmicDepthBuffer *logDepthBuffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
Hidden(OSGCamera *self) : QObject(self), self(self), fieldOfView(90), clearColor(0, 0, 0, 255), logDepthBufferEnabled(false)
|
||||||
|
{
|
||||||
#ifdef USE_OSGEARTH
|
#ifdef USE_OSGEARTH
|
||||||
logDepthBuffer = NULL;
|
logDepthBuffer = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -69,97 +73,6 @@ public:
|
|||||||
|
|
||||||
~Hidden()
|
~Hidden()
|
||||||
{
|
{
|
||||||
#ifdef USE_OSGEARTH
|
|
||||||
if (logDepthBuffer) {
|
|
||||||
delete logDepthBuffer;
|
|
||||||
logDepthBuffer = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool acceptSceneNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::acceptSceneNode" << node;
|
|
||||||
if (sceneNode == node) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sceneNode) {
|
|
||||||
disconnect(sceneNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
sceneNode = node;
|
|
||||||
|
|
||||||
if (sceneNode) {
|
|
||||||
connect(sceneNode, &OSGNode::nodeChanged, this, &Hidden::onSceneNodeChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool acceptManipulatorMode(ManipulatorMode::Enum mode)
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGCamera::acceptManipulatorMode" << mode;
|
|
||||||
if (manipulatorMode == mode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
manipulatorMode = mode;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool acceptTrackNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::acceptTrackNode" << node;
|
|
||||||
if (trackNode == node) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackNode) {
|
|
||||||
disconnect(trackNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
trackNode = node;
|
|
||||||
|
|
||||||
if (trackNode) {
|
|
||||||
connect(trackNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onTrackNodeChanged(osg::Node *)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachCamera(osg::Camera *camera)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::attach" << camera;
|
|
||||||
|
|
||||||
this->camera = camera;
|
|
||||||
self->setNode(this->camera.get());
|
|
||||||
|
|
||||||
#ifdef USE_OSGEARTH
|
|
||||||
// install log depth buffer if requested
|
|
||||||
if (logDepthBufferEnabled) {
|
|
||||||
qDebug() << "OSGCamera::attach - install logarithmic depth buffer";
|
|
||||||
logDepthBuffer = new osgEarth::Util::LogarithmicDepthBuffer();
|
|
||||||
logDepthBuffer->setUseFragDepth(true);
|
|
||||||
logDepthBuffer->install(camera);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
updateFieldOfView();
|
|
||||||
updateAspectRatio();
|
|
||||||
}
|
|
||||||
|
|
||||||
void detachCamera(osg::Camera *camera)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::detach" << camera;
|
|
||||||
|
|
||||||
if (camera != this->camera) {
|
|
||||||
qWarning() << "OSGCamera::detach - camera not attached" << camera;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->camera = NULL;
|
|
||||||
|
|
||||||
#ifdef USE_OSGEARTH
|
#ifdef USE_OSGEARTH
|
||||||
if (logDepthBuffer) {
|
if (logDepthBuffer) {
|
||||||
logDepthBuffer->uninstall(camera);
|
logDepthBuffer->uninstall(camera);
|
||||||
@ -169,93 +82,36 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void attachManipulator(osgViewer::View *view)
|
osg::Node *createNode()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGCamera::attachManipulator" << view;
|
camera = new osg::Camera();
|
||||||
|
|
||||||
osgGA::CameraManipulator *cm = NULL;
|
camera->setClearColor(osg::Vec4(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF()));
|
||||||
|
|
||||||
switch (manipulatorMode) {
|
osg::StateSet *stateset = camera->getOrCreateStateSet();
|
||||||
case ManipulatorMode::Default:
|
stateset->setGlobalDefaults();
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::attachManipulator - use TrackballManipulator";
|
|
||||||
osgGA::TrackballManipulator *tm = new osgGA::TrackballManipulator();
|
|
||||||
// Set the minimum distance of the eye point from the center before the center is pushed forward.
|
|
||||||
// tm->setMinimumDistance(1, true);
|
|
||||||
cm = tm;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ManipulatorMode::User:
|
|
||||||
qDebug() << "OSGCamera::attachManipulator - no camera manipulator";
|
|
||||||
// disable any installed camera manipulator
|
|
||||||
// TODO create and use own camera manipulator to avoid disabling ON_DEMAND frame update scheme
|
|
||||||
// see https://github.com/gwaldron/osgearth/commit/796daf4792ccaf18ae7eb6a5cb268eef0d42888d
|
|
||||||
// TODO see StandardManipulator for an example on how to react to events (to have FOV changes without the need for an update callback?)
|
|
||||||
cm = NULL;
|
|
||||||
break;
|
|
||||||
case ManipulatorMode::Earth:
|
|
||||||
{
|
|
||||||
#ifdef USE_OSGEARTH
|
|
||||||
qDebug() << "OSGCamera::attachManipulator - use EarthManipulator";
|
|
||||||
osgEarth::Util::EarthManipulator *em = new osgEarth::Util::EarthManipulator();
|
|
||||||
em->getSettings()->setThrowingEnabled(true);
|
|
||||||
cm = em;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ManipulatorMode::Track:
|
|
||||||
qDebug() << "OSGCamera::attachManipulator - use NodeTrackerManipulator";
|
|
||||||
if (trackNode && trackNode->node()) {
|
|
||||||
// setup tracking camera
|
|
||||||
// TODO when camera is thrown, then changing attitude has jitter
|
|
||||||
osgGA::NodeTrackerManipulator *ntm = new osgGA::NodeTrackerManipulator(
|
|
||||||
/*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/);
|
|
||||||
switch (trackerMode) {
|
|
||||||
case TrackerMode::NodeCenter:
|
|
||||||
ntm->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER);
|
|
||||||
break;
|
|
||||||
case TrackerMode::NodeCenterAndAzim:
|
|
||||||
ntm->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM);
|
|
||||||
break;
|
|
||||||
case TrackerMode::NodeCenterAndRotation:
|
|
||||||
ntm->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ntm->setTrackNode(trackNode->node());
|
|
||||||
ntm->setVerticalAxisFixed(false);
|
|
||||||
cm = ntm;
|
|
||||||
} else {
|
|
||||||
qWarning() << "OSGCamera::attachManipulator - no track node provided.";
|
|
||||||
cm = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
qWarning() << "OSGCamera::attachManipulator - should not reach here!";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
view->setCameraManipulator(cm, false);
|
return camera;
|
||||||
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(sceneNode->node());
|
|
||||||
}
|
|
||||||
if (cm) {
|
|
||||||
view->home();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void detachManipulator(osgViewer::View *view)
|
void updateClearColor()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGCamera::detachManipulator" << view;
|
if (!camera.valid()) {
|
||||||
|
qDebug() << "OSGCamera::updateClearColor - invalid camera";
|
||||||
view->setCameraManipulator(NULL, false);
|
return;
|
||||||
|
}
|
||||||
|
// qDebug() << "OSGCamera::updateClearColor" << clearColor;
|
||||||
|
camera->setClearColor(osg::Vec4(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateFieldOfView()
|
void updateFieldOfView()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGCamera::updateCameraFOV" << fieldOfView;
|
if (!camera.valid()) {
|
||||||
|
qDebug() << "OSGCamera::updateFieldOfView - invalid camera";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "OSGCamera::updateFieldOfView" << fieldOfView;
|
||||||
|
|
||||||
double fovy, ar, zn, zf;
|
double fovy, ar, zn, zf;
|
||||||
camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf);
|
camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf);
|
||||||
@ -265,7 +121,16 @@ public:
|
|||||||
|
|
||||||
void updateAspectRatio()
|
void updateAspectRatio()
|
||||||
{
|
{
|
||||||
|
if (!camera.valid()) {
|
||||||
|
qDebug() << "OSGCamera::updateAspectRatio - invalid camera";
|
||||||
|
return;
|
||||||
|
}
|
||||||
osg::Viewport *viewport = camera->getViewport();
|
osg::Viewport *viewport = camera->getViewport();
|
||||||
|
if (!viewport) {
|
||||||
|
qDebug() << "OSGCamera::updateAspectRatio - no viewport" << viewport;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
double aspectRatio = static_cast<double>(viewport->width()) / static_cast<double>(viewport->height());
|
double aspectRatio = static_cast<double>(viewport->width()) / static_cast<double>(viewport->height());
|
||||||
|
|
||||||
qDebug() << "OSGCamera::updateAspectRatio" << aspectRatio;
|
qDebug() << "OSGCamera::updateAspectRatio" << aspectRatio;
|
||||||
@ -276,113 +141,77 @@ public:
|
|||||||
camera->setProjectionMatrixAsPerspective(fovy, ar, zn, zf);
|
camera->setProjectionMatrixAsPerspective(fovy, ar, zn, zf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePosition()
|
void updateLogDepthBuffer()
|
||||||
{
|
{
|
||||||
if (manipulatorMode != ManipulatorMode::User) {
|
if (!camera.valid()) {
|
||||||
|
qWarning() << "OSGCamera::updateLogDepthBuffer - invalid camera";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Altitude mode is absolute (absolute height above MSL/HAE)
|
// qDebug() << "OSGCamera::updateLogDepthBuffer" << logDepthBufferEnabled;
|
||||||
// HAE : Height above ellipsoid. This is the default.
|
|
||||||
// MSL : Height above Mean Sea Level (MSL) if a geoid separation value is specified.
|
|
||||||
// TODO handle the case where the terrain SRS is not "wgs84"
|
|
||||||
// TODO check if position is not below terrain?
|
|
||||||
// TODO compensate antenna height when source of position is GPS (i.e. subtract antenna height from altitude) ;)
|
|
||||||
|
|
||||||
// Camera position
|
|
||||||
osg::Matrix cameraPosition;
|
|
||||||
|
|
||||||
#ifdef USE_OSGEARTH
|
#ifdef USE_OSGEARTH
|
||||||
osgEarth::GeoPoint geoPoint = osgQtQuick::toGeoPoint(position);
|
// install log depth buffer if requested
|
||||||
if (clampToTerrain) {
|
if (logDepthBufferEnabled && !logDepthBuffer) {
|
||||||
if (sceneNode) {
|
qDebug() << "OSGCamera::updateLogDepthBuffer - installing logarithmic depth buffer";
|
||||||
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
logDepthBuffer = new osgEarth::Util::LogarithmicDepthBuffer();
|
||||||
if (mapNode) {
|
logDepthBuffer->setUseFragDepth(true);
|
||||||
intoTerrain = clampGeoPoint(geoPoint, 0.5f, mapNode);
|
logDepthBuffer->install(camera);
|
||||||
} else {
|
} else if (!logDepthBufferEnabled && logDepthBuffer) {
|
||||||
qWarning() << "OSGCamera::updateNode - scene data does not contain a map node";
|
qDebug() << "OSGCamera::updateLogDepthBuffer - uninstalling logarithmic depth buffer";
|
||||||
}
|
logDepthBuffer->uninstall(camera);
|
||||||
}
|
delete logDepthBuffer;
|
||||||
|
logDepthBuffer = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void setGraphicsContext(osg::GraphicsContext *gc)
|
||||||
|
{
|
||||||
|
if (!camera.valid()) {
|
||||||
|
qDebug() << "OSGCamera::setGraphicsContext - invalid camera";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
geoPoint.createLocalToWorld(cameraPosition);
|
qDebug() << "OSGCamera::setGraphicsContext" << gc;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Camera orientation
|
camera->setGraphicsContext(gc);
|
||||||
// By default the camera looks toward -Z, we must rotate it so it looks toward Y
|
camera->setViewport(0, 0, gc->getTraits()->width, gc->getTraits()->height);
|
||||||
osg::Matrix cameraRotation;
|
|
||||||
cameraRotation.makeRotate(osg::DegreesToRadians(90.0), osg::Vec3(1.0, 0.0, 0.0),
|
|
||||||
osg::DegreesToRadians(0.0), osg::Vec3(0.0, 1.0, 0.0),
|
|
||||||
osg::DegreesToRadians(0.0), osg::Vec3(0.0, 0.0, 1.0));
|
|
||||||
|
|
||||||
// Final camera matrix
|
double aspectRatio = static_cast<double>(gc->getTraits()->width) / static_cast<double>(gc->getTraits()->height);
|
||||||
double roll = osg::DegreesToRadians(attitude.x());
|
|
||||||
double pitch = osg::DegreesToRadians(attitude.y());
|
|
||||||
double yaw = osg::DegreesToRadians(attitude.z());
|
|
||||||
osg::Matrix cameraMatrix = cameraRotation
|
|
||||||
* osg::Matrix::rotate(roll, osg::Vec3(0, 1, 0))
|
|
||||||
* osg::Matrix::rotate(pitch, osg::Vec3(1, 0, 0))
|
|
||||||
* osg::Matrix::rotate(yaw, osg::Vec3(0, 0, -1)) * cameraPosition;
|
|
||||||
|
|
||||||
// Inverse the camera's position and orientation matrix to obtain the view matrix
|
camera->setProjectionMatrixAsPerspective(fieldOfView, aspectRatio, 1.0f, 10000.0f);
|
||||||
cameraMatrix = osg::Matrix::inverse(cameraMatrix);
|
|
||||||
camera->setViewMatrix(cameraMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGCamera *const self;
|
double fovy, ar, zn, zf;
|
||||||
|
camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Camera> camera;
|
// FIXME this is needed for PFD + Terrain (because of "user" mode)
|
||||||
|
// updatePosition();
|
||||||
// Camera vertical field of view in degrees
|
|
||||||
qreal fieldOfView;
|
|
||||||
|
|
||||||
OSGNode *sceneNode;
|
|
||||||
|
|
||||||
ManipulatorMode::Enum manipulatorMode;
|
|
||||||
|
|
||||||
// for NodeTrackerManipulator
|
|
||||||
TrackerMode::Enum trackerMode;
|
|
||||||
OSGNode *trackNode;
|
|
||||||
|
|
||||||
bool logDepthBufferEnabled;
|
|
||||||
#ifdef USE_OSGEARTH
|
|
||||||
osgEarth::Util::LogarithmicDepthBuffer *logDepthBuffer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool clampToTerrain;
|
|
||||||
bool intoTerrain;
|
|
||||||
|
|
||||||
QVector3D attitude;
|
|
||||||
QVector3D position;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onSceneNodeChanged(osg::Node *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::onSceneNodeChanged" << node;
|
|
||||||
qWarning() << "OSGCamera::onSceneNodeChanged - needs to be implemented";
|
|
||||||
}
|
|
||||||
|
|
||||||
void onTrackNodeChanged(osg::Node *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::onTrackNodeChanged" << node;
|
|
||||||
qWarning() << "OSGCamera::onTrackNodeChanged - needs to be implemented";
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* class OSGCamera */
|
/* class OSGCamera */
|
||||||
|
|
||||||
enum DirtyFlag { FieldOfView = 1 << 0, Position = 1 << 1, Attitude = 1 << 2 };
|
OSGCamera::OSGCamera(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
OSGCamera::OSGCamera(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
|
||||||
{
|
|
||||||
qDebug() << "OSGCamera::OSGCamera";
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGCamera::~OSGCamera()
|
OSGCamera::~OSGCamera()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGCamera::~OSGCamera";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QColor OSGCamera::clearColor() const
|
||||||
|
{
|
||||||
|
return h->clearColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCamera::setClearColor(const QColor &color)
|
||||||
|
{
|
||||||
|
if (h->clearColor != color) {
|
||||||
|
h->clearColor = color;
|
||||||
|
emit clearColorChanged(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qreal OSGCamera::fieldOfView() const
|
qreal OSGCamera::fieldOfView() const
|
||||||
{
|
{
|
||||||
return h->fieldOfView;
|
return h->fieldOfView;
|
||||||
@ -397,102 +226,7 @@ void OSGCamera::setFieldOfView(qreal arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGNode *OSGCamera::sceneNode()
|
bool OSGCamera::logarithmicDepthBuffer() const
|
||||||
{
|
|
||||||
return h->sceneNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGCamera::setSceneNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
if (h->acceptSceneNode(node)) {
|
|
||||||
emit sceneNodeChanged(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ManipulatorMode::Enum OSGCamera::manipulatorMode() const
|
|
||||||
{
|
|
||||||
return h->manipulatorMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGCamera::setManipulatorMode(ManipulatorMode::Enum mode)
|
|
||||||
{
|
|
||||||
if (h->acceptManipulatorMode(mode)) {
|
|
||||||
emit manipulatorModeChanged(manipulatorMode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGNode *OSGCamera::trackNode() const
|
|
||||||
{
|
|
||||||
return h->trackNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGCamera::setTrackNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
if (h->acceptTrackNode(node)) {
|
|
||||||
emit trackNodeChanged(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackerMode::Enum OSGCamera::trackerMode() const
|
|
||||||
{
|
|
||||||
return h->trackerMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGCamera::setTrackerMode(TrackerMode::Enum mode)
|
|
||||||
{
|
|
||||||
if (h->trackerMode != mode) {
|
|
||||||
h->trackerMode = mode;
|
|
||||||
emit trackerModeChanged(trackerMode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OSGCamera::clampToTerrain() const
|
|
||||||
{
|
|
||||||
return h->clampToTerrain;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGCamera::setClampToTerrain(bool arg)
|
|
||||||
{
|
|
||||||
if (h->clampToTerrain != arg) {
|
|
||||||
h->clampToTerrain = arg;
|
|
||||||
emit clampToTerrainChanged(clampToTerrain());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OSGCamera::intoTerrain() const
|
|
||||||
{
|
|
||||||
return h->intoTerrain;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector3D OSGCamera::attitude() const
|
|
||||||
{
|
|
||||||
return h->attitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGCamera::setAttitude(QVector3D arg)
|
|
||||||
{
|
|
||||||
if (h->attitude != arg) {
|
|
||||||
h->attitude = arg;
|
|
||||||
setDirty(Attitude);
|
|
||||||
emit attitudeChanged(attitude());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector3D OSGCamera::position() const
|
|
||||||
{
|
|
||||||
return h->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGCamera::setPosition(QVector3D arg)
|
|
||||||
{
|
|
||||||
if (h->position != arg) {
|
|
||||||
h->position = arg;
|
|
||||||
setDirty(Position);
|
|
||||||
emit positionChanged(position());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OSGCamera::logarithmicDepthBuffer()
|
|
||||||
{
|
{
|
||||||
return h->logDepthBufferEnabled;
|
return h->logDepthBufferEnabled;
|
||||||
}
|
}
|
||||||
@ -501,32 +235,40 @@ void OSGCamera::setLogarithmicDepthBuffer(bool enabled)
|
|||||||
{
|
{
|
||||||
if (h->logDepthBufferEnabled != enabled) {
|
if (h->logDepthBufferEnabled != enabled) {
|
||||||
h->logDepthBufferEnabled = enabled;
|
h->logDepthBufferEnabled = enabled;
|
||||||
|
setDirty(LogDepthBuffer);
|
||||||
emit logarithmicDepthBufferChanged(logarithmicDepthBuffer());
|
emit logarithmicDepthBufferChanged(logarithmicDepthBuffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGCamera::update()
|
osg::Node *OSGCamera::createNode()
|
||||||
{
|
{
|
||||||
|
return h->createNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCamera::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
|
if (isDirty(ClearColor)) {
|
||||||
|
h->updateClearColor();
|
||||||
|
}
|
||||||
if (isDirty(FieldOfView)) {
|
if (isDirty(FieldOfView)) {
|
||||||
h->updateFieldOfView();
|
h->updateFieldOfView();
|
||||||
}
|
}
|
||||||
if (isDirty(Position | Attitude)) {
|
if (isDirty(LogDepthBuffer)) {
|
||||||
h->updatePosition();
|
h->updateLogDepthBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGCamera::attach(osgViewer::View *view)
|
osg::Camera *OSGCamera::asCamera() const
|
||||||
{
|
{
|
||||||
h->attachCamera(view->getCamera());
|
// BAD introduce templating
|
||||||
h->attachManipulator(view);
|
return (osg::Camera *)node();
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGCamera::detach(osgViewer::View *view)
|
void OSGCamera::setGraphicsContext(osg::GraphicsContext *gc)
|
||||||
{
|
{
|
||||||
h->detachManipulator(view);
|
h->setGraphicsContext(gc);
|
||||||
h->detachCamera(view->getCamera());
|
|
||||||
}
|
}
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGCamera.hpp
|
* @file OSGCamera.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -32,114 +32,51 @@
|
|||||||
#include "OSGNode.hpp"
|
#include "OSGNode.hpp"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVector3D>
|
#include <QColor>
|
||||||
|
|
||||||
namespace osgViewer {
|
namespace osg {
|
||||||
class View;
|
class Camera;
|
||||||
|
class GraphicsContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class ManipulatorMode : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum Enum { Default, Earth, Track, User };
|
|
||||||
Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5
|
|
||||||
};
|
|
||||||
|
|
||||||
class TrackerMode : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum Enum { NodeCenter, NodeCenterAndAzim, NodeCenterAndRotation };
|
|
||||||
Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5
|
|
||||||
};
|
|
||||||
|
|
||||||
// This class does too much:
|
|
||||||
// - tracking a geo point and attitude
|
|
||||||
// - tracking another node
|
|
||||||
// camera should be simpler and provide only tracking
|
|
||||||
// - tracking of a modelnode (for ModelView)
|
|
||||||
// - tracking of a virtual node (for PFD with Terrain)
|
|
||||||
//
|
|
||||||
// TODO
|
|
||||||
// - expose track mode
|
|
||||||
// - provide good default distance and attitude for tracker camera
|
|
||||||
class OSGQTQUICK_EXPORT OSGCamera : public OSGNode {
|
class OSGQTQUICK_EXPORT OSGCamera : public OSGNode {
|
||||||
Q_OBJECT Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged)
|
Q_OBJECT Q_PROPERTY(QColor clearColor READ clearColor WRITE setClearColor NOTIFY clearColorChanged)
|
||||||
Q_PROPERTY(osgQtQuick::OSGNode * sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged)
|
||||||
Q_PROPERTY(osgQtQuick::ManipulatorMode::Enum manipulatorMode READ manipulatorMode WRITE setManipulatorMode NOTIFY manipulatorModeChanged)
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
Q_PROPERTY(bool logarithmicDepthBuffer READ logarithmicDepthBuffer WRITE setLogarithmicDepthBuffer NOTIFY logarithmicDepthBufferChanged)
|
Q_PROPERTY(bool logarithmicDepthBuffer READ logarithmicDepthBuffer WRITE setLogarithmicDepthBuffer NOTIFY logarithmicDepthBufferChanged)
|
||||||
|
|
||||||
|
typedef OSGNode Inherited;
|
||||||
|
|
||||||
friend class OSGViewport;
|
friend class OSGViewport;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OSGCamera(QObject *parent = 0);
|
explicit OSGCamera(QObject *parent = 0);
|
||||||
virtual ~OSGCamera();
|
virtual ~OSGCamera();
|
||||||
|
|
||||||
// fov depends on the scenery space (probaby distance)
|
QColor clearColor() const;
|
||||||
// here are some value: 75°, 60°, 45° many gamers use
|
void setClearColor(const QColor &color);
|
||||||
// x-plane uses 45° for 4:3 and 60° for 16:9/16:10
|
|
||||||
// flightgear uses 55° / 70°
|
|
||||||
qreal fieldOfView() const;
|
qreal fieldOfView() const;
|
||||||
void setFieldOfView(qreal arg);
|
void setFieldOfView(qreal arg);
|
||||||
|
|
||||||
OSGNode *sceneNode();
|
bool logarithmicDepthBuffer() const;
|
||||||
void setSceneNode(OSGNode *node);
|
|
||||||
|
|
||||||
ManipulatorMode::Enum manipulatorMode() const;
|
|
||||||
void setManipulatorMode(ManipulatorMode::Enum);
|
|
||||||
|
|
||||||
OSGNode *trackNode() const;
|
|
||||||
void setTrackNode(OSGNode *node);
|
|
||||||
|
|
||||||
TrackerMode::Enum trackerMode() const;
|
|
||||||
void setTrackerMode(TrackerMode::Enum);
|
|
||||||
|
|
||||||
bool clampToTerrain() const;
|
|
||||||
void setClampToTerrain(bool arg);
|
|
||||||
|
|
||||||
bool intoTerrain() const;
|
|
||||||
|
|
||||||
QVector3D attitude() const;
|
|
||||||
void setAttitude(QVector3D arg);
|
|
||||||
|
|
||||||
QVector3D position() const;
|
|
||||||
void setPosition(QVector3D arg);
|
|
||||||
|
|
||||||
bool logarithmicDepthBuffer();
|
|
||||||
void setLogarithmicDepthBuffer(bool enabled);
|
void setLogarithmicDepthBuffer(bool enabled);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void clearColorChanged(const QColor &color);
|
||||||
void fieldOfViewChanged(qreal arg);
|
void fieldOfViewChanged(qreal arg);
|
||||||
|
|
||||||
void sceneNodeChanged(OSGNode *node);
|
|
||||||
|
|
||||||
void manipulatorModeChanged(ManipulatorMode::Enum);
|
|
||||||
|
|
||||||
void trackNodeChanged(OSGNode *node);
|
|
||||||
void trackerModeChanged(TrackerMode::Enum);
|
|
||||||
|
|
||||||
void clampToTerrainChanged(bool arg);
|
|
||||||
void intoTerrainChanged(bool arg);
|
|
||||||
|
|
||||||
void attitudeChanged(QVector3D arg);
|
|
||||||
void positionChanged(QVector3D arg);
|
|
||||||
|
|
||||||
void logarithmicDepthBufferChanged(bool enabled);
|
void logarithmicDepthBufferChanged(bool enabled);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
osg::Camera *asCamera() const;
|
||||||
|
void setGraphicsContext(osg::GraphicsContext *gc);
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGFileNode.cpp
|
* @file OSGFileNode.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -37,11 +37,14 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { Source = 1 << 0, Async = 1 << 1, OptimizeMode = 1 << 2 };
|
||||||
|
|
||||||
class OSGFileLoader : public QThread {
|
class OSGFileLoader : public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGFileLoader(const QUrl &url) : url(url) {}
|
OSGFileLoader(const QUrl &url) : url(url)
|
||||||
|
{}
|
||||||
|
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
@ -54,9 +57,12 @@ public:
|
|||||||
QElapsedTimer t;
|
QElapsedTimer t;
|
||||||
|
|
||||||
t.start();
|
t.start();
|
||||||
qDebug() << "OSGFileLoader::load - reading node file" << url.path();
|
// qDebug() << "OSGFileLoader::load - reading node file" << url.path();
|
||||||
// qDebug() << "OSGFileLoader - load - currentContext" << QOpenGLContext::currentContext();
|
// qDebug() << "OSGFileLoader - load - currentContext" << QOpenGLContext::currentContext();
|
||||||
osg::Node *node = osgDB::readNodeFile(url.path().toStdString());
|
osg::Node *node = osgDB::readNodeFile(url.path().toStdString());
|
||||||
|
if (!node) {
|
||||||
|
qWarning() << "OSGFileLoader::load - failed to load" << url.path();
|
||||||
|
}
|
||||||
// qDebug() << "OSGFileLoader::load - reading node" << node << "took" << t.elapsed() << "ms";
|
// qDebug() << "OSGFileLoader::load - reading node" << node << "took" << t.elapsed() << "ms";
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@ -79,11 +85,12 @@ public:
|
|||||||
bool async;
|
bool async;
|
||||||
OptimizeMode::Enum optimizeMode;
|
OptimizeMode::Enum optimizeMode;
|
||||||
|
|
||||||
Hidden(OSGFileNode *node) : QObject(node), self(node), source(), async(false), optimizeMode(OptimizeMode::None) {}
|
Hidden(OSGFileNode *self) : QObject(self), self(self), source(), async(false), optimizeMode(OptimizeMode::None)
|
||||||
|
{}
|
||||||
|
|
||||||
void updateNode()
|
void updateSource()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGFileNode::updateNode" << source;
|
qDebug() << "OSGFileNode::updateNode" << source;
|
||||||
if (!source.isValid()) {
|
if (!source.isValid()) {
|
||||||
self->setNode(NULL);
|
self->setNode(NULL);
|
||||||
if (!source.isEmpty()) {
|
if (!source.isEmpty()) {
|
||||||
@ -118,7 +125,7 @@ private:
|
|||||||
|
|
||||||
void setNode(osg::Node *node)
|
void setNode(osg::Node *node)
|
||||||
{
|
{
|
||||||
qDebug() << "OSGFileNode::setNode" << node;
|
// qDebug() << "OSGFileNode::setNode" << node;
|
||||||
if (node && optimizeMode != OptimizeMode::None) {
|
if (node && optimizeMode != OptimizeMode::None) {
|
||||||
// qDebug() << "OSGFileNode::acceptNode - optimize" << node << optimizeMode;
|
// qDebug() << "OSGFileNode::acceptNode - optimize" << node << optimizeMode;
|
||||||
osgUtil::Optimizer optimizer;
|
osgUtil::Optimizer optimizer;
|
||||||
@ -139,18 +146,11 @@ private slots:
|
|||||||
|
|
||||||
/* class OSGFileNode */
|
/* class OSGFileNode */
|
||||||
|
|
||||||
enum DirtyFlag { Source = 1 << 0, Async = 1 << 1, OptimizeMode = 1 << 2 };
|
OSGFileNode::OSGFileNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
OSGFileNode::OSGFileNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
|
||||||
{
|
|
||||||
qDebug() << "OSGFileNode::OSGFileNode";
|
|
||||||
setAsync(false);
|
|
||||||
setOptimizeMode(OptimizeMode::None);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGFileNode::~OSGFileNode()
|
OSGFileNode::~OSGFileNode()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGFileNode::~OSGFileNode";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,6 @@ const QUrl OSGFileNode::source() const
|
|||||||
|
|
||||||
void OSGFileNode::setSource(const QUrl &source)
|
void OSGFileNode::setSource(const QUrl &source)
|
||||||
{
|
{
|
||||||
qDebug() << "OSGFileNode::setSource" << source;
|
|
||||||
if (h->source != source) {
|
if (h->source != source) {
|
||||||
h->source = source;
|
h->source = source;
|
||||||
setDirty(Source);
|
setDirty(Source);
|
||||||
@ -176,7 +175,6 @@ bool OSGFileNode::async() const
|
|||||||
|
|
||||||
void OSGFileNode::setAsync(const bool async)
|
void OSGFileNode::setAsync(const bool async)
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGFileNode::setAsync" << async;
|
|
||||||
if (h->async != async) {
|
if (h->async != async) {
|
||||||
h->async = async;
|
h->async = async;
|
||||||
setDirty(Async);
|
setDirty(Async);
|
||||||
@ -191,7 +189,6 @@ OptimizeMode::Enum OSGFileNode::optimizeMode() const
|
|||||||
|
|
||||||
void OSGFileNode::setOptimizeMode(OptimizeMode::Enum optimizeMode)
|
void OSGFileNode::setOptimizeMode(OptimizeMode::Enum optimizeMode)
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGFileNode::setOptimizeMode" << optimizeMode;
|
|
||||||
if (h->optimizeMode != optimizeMode) {
|
if (h->optimizeMode != optimizeMode) {
|
||||||
h->optimizeMode = optimizeMode;
|
h->optimizeMode = optimizeMode;
|
||||||
setDirty(OptimizeMode);
|
setDirty(OptimizeMode);
|
||||||
@ -199,8 +196,16 @@ void OSGFileNode::setOptimizeMode(OptimizeMode::Enum optimizeMode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGFileNode::update()
|
osg::Node *OSGFileNode::createNode()
|
||||||
{
|
{
|
||||||
|
// node is created later
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGFileNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
if (isDirty(Async)) {
|
if (isDirty(Async)) {
|
||||||
// do nothing...
|
// do nothing...
|
||||||
}
|
}
|
||||||
@ -208,18 +213,9 @@ void OSGFileNode::update()
|
|||||||
// TODO: trigger a node update ?
|
// TODO: trigger a node update ?
|
||||||
}
|
}
|
||||||
if (isDirty(Source)) {
|
if (isDirty(Source)) {
|
||||||
h->updateNode();
|
h->updateSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGFileNode::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGFileNode::detach(osgViewer::View *view)
|
|
||||||
{}
|
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#include "OSGFileNode.moc"
|
#include "OSGFileNode.moc"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGFileNode.hpp
|
* @file OSGFileNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -39,6 +39,7 @@ QT_END_NAMESPACE
|
|||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class OSGQTQUICK_EXPORT OptimizeMode : public QObject {
|
class OSGQTQUICK_EXPORT OptimizeMode : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Enum { None, Optimize, OptimizeAndCheck };
|
enum Enum { None, Optimize, OptimizeAndCheck };
|
||||||
Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5
|
Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5
|
||||||
@ -49,6 +50,8 @@ class OSGQTQUICK_EXPORT OSGFileNode : public OSGNode {
|
|||||||
Q_PROPERTY(bool async READ async WRITE setAsync NOTIFY asyncChanged)
|
Q_PROPERTY(bool async READ async WRITE setAsync NOTIFY asyncChanged)
|
||||||
Q_PROPERTY(osgQtQuick::OptimizeMode::Enum optimizeMode READ optimizeMode WRITE setOptimizeMode NOTIFY optimizeModeChanged)
|
Q_PROPERTY(osgQtQuick::OptimizeMode::Enum optimizeMode READ optimizeMode WRITE setOptimizeMode NOTIFY optimizeModeChanged)
|
||||||
|
|
||||||
|
typedef OSGNode Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGFileNode(QObject *parent = 0);
|
OSGFileNode(QObject *parent = 0);
|
||||||
virtual ~OSGFileNode();
|
virtual ~OSGFileNode();
|
||||||
@ -67,14 +70,13 @@ signals:
|
|||||||
void asyncChanged(const bool async);
|
void asyncChanged(const bool async);
|
||||||
void optimizeModeChanged(OptimizeMode::Enum);
|
void optimizeModeChanged(OptimizeMode::Enum);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGGeoTransformNode.cpp
|
* @file OSGGeoTransformNode.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "OSGGeoTransformNode.hpp"
|
#include "OSGGeoTransformNode.hpp"
|
||||||
|
|
||||||
#include "../utility.h"
|
#include "utils/utility.h"
|
||||||
|
|
||||||
#include <osg/ComputeBoundsVisitor>
|
#include <osg/ComputeBoundsVisitor>
|
||||||
|
|
||||||
@ -38,6 +38,10 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
|
// NOTE : these flags should not overlap with OSGGroup flags!!!
|
||||||
|
// TODO : find a better way...
|
||||||
|
enum DirtyFlag { Scene = 1 << 10, Position = 1 << 11, Clamp = 1 << 12 };
|
||||||
|
|
||||||
struct OSGGeoTransformNode::Hidden : public QObject {
|
struct OSGGeoTransformNode::Hidden : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -47,7 +51,6 @@ private:
|
|||||||
osg::ref_ptr<osgEarth::GeoTransform> transform;
|
osg::ref_ptr<osgEarth::GeoTransform> transform;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGNode *childNode;
|
|
||||||
OSGNode *sceneNode;
|
OSGNode *sceneNode;
|
||||||
|
|
||||||
float offset;
|
float offset;
|
||||||
@ -57,31 +60,14 @@ public:
|
|||||||
|
|
||||||
QVector3D position;
|
QVector3D position;
|
||||||
|
|
||||||
Hidden(OSGGeoTransformNode *node) : QObject(node), self(node), childNode(NULL), sceneNode(NULL), offset(-1.0), clampToTerrain(false), intoTerrain(false)
|
Hidden(OSGGeoTransformNode *self) : QObject(self), self(self), sceneNode(NULL), offset(-1.0), clampToTerrain(false), intoTerrain(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
osg::Node *createNode()
|
||||||
{
|
{
|
||||||
transform = new osgEarth::GeoTransform();
|
transform = new osgEarth::GeoTransform();
|
||||||
transform->setAutoRecomputeHeights(true);
|
transform->setAutoRecomputeHeights(true);
|
||||||
self->setNode(transform);
|
return transform;
|
||||||
}
|
|
||||||
|
|
||||||
bool acceptChildNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGGeoTransformNode::acceptChildNode" << node;
|
|
||||||
if (childNode == node) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childNode) {
|
|
||||||
disconnect(childNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
childNode = node;
|
|
||||||
|
|
||||||
if (childNode) {
|
|
||||||
connect(childNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onChildNodeChanged(osg::Node *)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acceptSceneNode(OSGNode *node)
|
bool acceptSceneNode(OSGNode *node)
|
||||||
@ -98,37 +84,15 @@ public:
|
|||||||
sceneNode = node;
|
sceneNode = node;
|
||||||
|
|
||||||
if (sceneNode) {
|
if (sceneNode) {
|
||||||
connect(sceneNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onSceneNodeChanged(osg::Node *)));
|
connect(sceneNode, &OSGNode::nodeChanged, this, &OSGGeoTransformNode::Hidden::onSceneNodeChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTransformNode()
|
|
||||||
{
|
|
||||||
bool updated = false;
|
|
||||||
|
|
||||||
if (transform->getNumChildren() == 0) {
|
|
||||||
if (childNode && childNode->node()) {
|
|
||||||
updated |= transform->addChild(childNode->node());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (childNode && childNode->node()) {
|
|
||||||
if (transform->getChild(0) != childNode->node()) {
|
|
||||||
updated |= transform->removeChild(0, 1);
|
|
||||||
updated |= transform->addChild(childNode->node());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updated |= transform->removeChild(0, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if (updated) {
|
|
||||||
self->emitNodeChanged();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateSceneNode()
|
void updateSceneNode()
|
||||||
{
|
{
|
||||||
|
qDebug() << "OSGGeoTransformNode::updateSceneNode" << sceneNode;
|
||||||
if (sceneNode && sceneNode->node()) {
|
if (sceneNode && sceneNode->node()) {
|
||||||
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
||||||
if (mapNode) {
|
if (mapNode) {
|
||||||
@ -141,15 +105,20 @@ public:
|
|||||||
|
|
||||||
void updatePosition()
|
void updatePosition()
|
||||||
{
|
{
|
||||||
|
// qDebug() << "OSGGeoTransformNode::updatePosition" << position;
|
||||||
|
|
||||||
osgEarth::MapNode *mapNode = NULL;
|
osgEarth::MapNode *mapNode = NULL;
|
||||||
|
|
||||||
if (sceneNode && sceneNode->node()) {
|
if (sceneNode && sceneNode->node()) {
|
||||||
mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
||||||
}
|
if (!mapNode) {
|
||||||
if (!mapNode) {
|
qWarning() << "OSGGeoTransformNode::updatePosition - scene node does not contain a map node";
|
||||||
qWarning() << "OSGGeoTransformNode::updatePosition - scene node does not contain a map node";
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "OSGGeoTransformNode::updatePosition - scene node is not valid";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO factorize this logic to utility (same logic is found elsewhere)
|
||||||
osgEarth::GeoPoint geoPoint;
|
osgEarth::GeoPoint geoPoint;
|
||||||
if (mapNode) {
|
if (mapNode) {
|
||||||
geoPoint = osgQtQuick::toGeoPoint(mapNode->getTerrain()->getSRS(), position);
|
geoPoint = osgQtQuick::toGeoPoint(mapNode->getTerrain()->getSRS(), position);
|
||||||
@ -160,7 +129,7 @@ public:
|
|||||||
// get "size" of model
|
// get "size" of model
|
||||||
// TODO this should be done once only...
|
// TODO this should be done once only...
|
||||||
osg::ComputeBoundsVisitor cbv;
|
osg::ComputeBoundsVisitor cbv;
|
||||||
childNode->node()->accept(cbv);
|
transform->accept(cbv);
|
||||||
const osg::BoundingBox & bbox = cbv.getBoundingBox();
|
const osg::BoundingBox & bbox = cbv.getBoundingBox();
|
||||||
offset = bbox.radius();
|
offset = bbox.radius();
|
||||||
|
|
||||||
@ -168,53 +137,33 @@ public:
|
|||||||
|
|
||||||
// clamp model to terrain if needed
|
// clamp model to terrain if needed
|
||||||
intoTerrain = clampGeoPoint(geoPoint, offset, mapNode);
|
intoTerrain = clampGeoPoint(geoPoint, offset, mapNode);
|
||||||
|
} else if (clampToTerrain) {
|
||||||
|
qWarning() << "OSGGeoTransformNode::onChildNodeChanged - cannot clamp without map node";
|
||||||
}
|
}
|
||||||
|
|
||||||
transform->setPosition(geoPoint);
|
transform->setPosition(geoPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onChildNodeChanged(osg::Node *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGGeoTransformNode::onChildNodeChanged" << node;
|
|
||||||
updateTransformNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSceneNodeChanged(osg::Node *node)
|
void onSceneNodeChanged(osg::Node *node)
|
||||||
{
|
{
|
||||||
qDebug() << "OSGGeoTransformNode::onSceneNodeChanged" << node;
|
qDebug() << "OSGGeoTransformNode::onSceneNodeChanged" << node;
|
||||||
// TODO
|
updateSceneNode();
|
||||||
|
updatePosition();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* class OSGGeoTransformNode */
|
/* class OSGGeoTransformNode */
|
||||||
|
|
||||||
enum DirtyFlag { Child = 1 << 0, Scene = 1 << 1, Position = 1 << 2, Clamp = 1 << 3 };
|
OSGGeoTransformNode::OSGGeoTransformNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
OSGGeoTransformNode::OSGGeoTransformNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
|
||||||
{
|
|
||||||
qDebug() << "OSGGeoTransformNode::OSGGeoTransformNode";
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGGeoTransformNode::~OSGGeoTransformNode()
|
OSGGeoTransformNode::~OSGGeoTransformNode()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGGeoTransformNode::~OSGGeoTransformNode";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGNode *OSGGeoTransformNode::childNode()
|
OSGNode *OSGGeoTransformNode::sceneNode() const
|
||||||
{
|
|
||||||
return h->childNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGGeoTransformNode::setChildNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
if (h->acceptChildNode(node)) {
|
|
||||||
setDirty(Child);
|
|
||||||
emit childNodeChanged(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGNode *OSGGeoTransformNode::sceneNode()
|
|
||||||
{
|
{
|
||||||
return h->sceneNode;
|
return h->sceneNode;
|
||||||
}
|
}
|
||||||
@ -260,32 +209,25 @@ void OSGGeoTransformNode::setPosition(QVector3D arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGGeoTransformNode::update()
|
osg::Node *OSGGeoTransformNode::createNode()
|
||||||
{
|
{
|
||||||
if (isDirty(Child)) {
|
return h->createNode();
|
||||||
h->updateTransformNode();
|
}
|
||||||
}
|
|
||||||
|
void OSGGeoTransformNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
if (isDirty(Scene)) {
|
if (isDirty(Scene)) {
|
||||||
h->updateSceneNode();
|
h->updateSceneNode();
|
||||||
}
|
}
|
||||||
if (isDirty(Clamp)) {}
|
if (isDirty(Clamp)) {
|
||||||
if (isDirty(Position)) {
|
// do nothing...
|
||||||
|
}
|
||||||
|
if (isDirty(Scene | Clamp | Position)) {
|
||||||
h->updatePosition();
|
h->updatePosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGGeoTransformNode::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
OSGNode::attach(h->childNode, view);
|
|
||||||
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGGeoTransformNode::detach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
OSGNode::detach(h->childNode, view);
|
|
||||||
}
|
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#include "OSGGeoTransformNode.moc"
|
#include "OSGGeoTransformNode.moc"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGGeoTransformNode.hpp
|
* @file OSGGeoTransformNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -29,32 +29,24 @@
|
|||||||
#define _H_OSGQTQUICK_GEOTRANSFORMNODE_H_
|
#define _H_OSGQTQUICK_GEOTRANSFORMNODE_H_
|
||||||
|
|
||||||
#include "Export.hpp"
|
#include "Export.hpp"
|
||||||
#include "OSGNode.hpp"
|
#include "OSGGroup.hpp"
|
||||||
|
|
||||||
#include <QVector3D>
|
#include <QVector3D>
|
||||||
|
|
||||||
// TODO derive from OSGGroup...
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class OSGQTQUICK_EXPORT OSGGeoTransformNode : public OSGNode {
|
class OSGQTQUICK_EXPORT OSGGeoTransformNode : public OSGGroup {
|
||||||
Q_OBJECT
|
Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
||||||
// TODO rename to childNode
|
|
||||||
Q_PROPERTY(osgQtQuick::OSGNode *modelData READ childNode WRITE setChildNode NOTIFY childNodeChanged)
|
|
||||||
// TODO rename to sceneNode
|
|
||||||
Q_PROPERTY(osgQtQuick::OSGNode * sceneData READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged)
|
Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged)
|
||||||
Q_PROPERTY(bool intoTerrain READ intoTerrain NOTIFY intoTerrainChanged)
|
Q_PROPERTY(bool intoTerrain READ intoTerrain NOTIFY intoTerrainChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
||||||
|
|
||||||
|
typedef OSGGroup Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGGeoTransformNode(QObject *parent = 0);
|
OSGGeoTransformNode(QObject *parent = 0);
|
||||||
virtual ~OSGGeoTransformNode();
|
virtual ~OSGGeoTransformNode();
|
||||||
|
|
||||||
OSGNode *childNode();
|
OSGNode *sceneNode() const;
|
||||||
void setChildNode(OSGNode *node);
|
|
||||||
|
|
||||||
OSGNode *sceneNode();
|
|
||||||
void setSceneNode(OSGNode *node);
|
void setSceneNode(OSGNode *node);
|
||||||
|
|
||||||
bool clampToTerrain() const;
|
bool clampToTerrain() const;
|
||||||
@ -66,23 +58,18 @@ public:
|
|||||||
void setPosition(QVector3D arg);
|
void setPosition(QVector3D arg);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void childNodeChanged(OSGNode *node);
|
|
||||||
|
|
||||||
void sceneNodeChanged(OSGNode *node);
|
void sceneNodeChanged(OSGNode *node);
|
||||||
|
|
||||||
void clampToTerrainChanged(bool arg);
|
void clampToTerrainChanged(bool arg);
|
||||||
void intoTerrainChanged(bool arg);
|
void intoTerrainChanged(bool arg);
|
||||||
|
|
||||||
void positionChanged(QVector3D arg);
|
void positionChanged(QVector3D arg);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGGroup.cpp
|
* @file OSGGroup.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -39,26 +39,26 @@ struct OSGGroup::Hidden : public QObject {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OSGGroup * self;
|
OSGGroup * const self;
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> group;
|
|
||||||
|
|
||||||
QMap<OSGNode *, osg::Node *> cache;
|
QMap<OSGNode *, osg::Node *> cache;
|
||||||
|
|
||||||
public:
|
|
||||||
Hidden(OSGGroup *node) : QObject(node), self(node), group(new osg::Group)
|
|
||||||
{
|
|
||||||
group = new osg::Group();
|
|
||||||
self->setNode(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<OSGNode *> children;
|
QList<OSGNode *> children;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Hidden(OSGGroup *self) : QObject(self), self(self)
|
||||||
|
{}
|
||||||
|
|
||||||
|
osg::Node *createNode()
|
||||||
|
{
|
||||||
|
return new osg::Group();
|
||||||
|
}
|
||||||
|
|
||||||
void appendChild(OSGNode *childNode)
|
void appendChild(OSGNode *childNode)
|
||||||
{
|
{
|
||||||
cache[childNode] = childNode->node();
|
// qDebug() << "OSGGroup::appendChild" << childNode;
|
||||||
children.append(childNode);
|
children.append(childNode);
|
||||||
connect(childNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onChildNodeChanged(osg::Node *)), Qt::UniqueConnection);
|
connect(childNode, &OSGNode::nodeChanged, this, &osgQtQuick::OSGGroup::Hidden::onChildNodeChanged, Qt::UniqueConnection);
|
||||||
self->setDirty(Children);
|
self->setDirty(Children);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,27 +86,39 @@ public:
|
|||||||
self->setDirty(Children);
|
self->setDirty(Children);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateGroupNode()
|
void updateChildren()
|
||||||
{
|
{
|
||||||
|
qDebug() << "OSGGroup::updateChildren";
|
||||||
|
|
||||||
|
osg::Group *group = static_cast<osg::Group *>(self->node());
|
||||||
|
if (!group) {
|
||||||
|
qWarning() << "OSGGroup::updateChildren - null group";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
unsigned int index = 0;
|
unsigned int index = 0;
|
||||||
|
|
||||||
QListIterator<OSGNode *> i(children);
|
QListIterator<OSGNode *> i(children);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
OSGNode *childNode = i.next();
|
OSGNode *childNode = i.next();
|
||||||
if (index < group->getNumChildren()) {
|
// qDebug() << "OSGGroup::updateChildren - child" << childNode;
|
||||||
updated |= group->replaceChild(group->getChild(index), childNode->node());
|
if (childNode->node()) {
|
||||||
} else {
|
if (index < group->getNumChildren()) {
|
||||||
updated |= group->addChild(childNode->node());
|
updated |= group->replaceChild(group->getChild(index), childNode->node());
|
||||||
|
} else {
|
||||||
|
updated |= group->addChild(childNode->node());
|
||||||
|
}
|
||||||
|
cache.insert(childNode, childNode->node());
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
// removing eventual left overs
|
// removing eventual left overs
|
||||||
if (index < group->getNumChildren()) {
|
if (index < group->getNumChildren()) {
|
||||||
updated |= group->removeChild(index, group->getNumChildren() - index);
|
updated |= group->removeChild(index, group->getNumChildren() - index);
|
||||||
}
|
}
|
||||||
// if (updated) {
|
// if (updated) {
|
||||||
self->emitNodeChanged();
|
// self->emitNodeChanged();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,37 +153,53 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onChildNodeChanged(osg::Node *node)
|
void onChildNodeChanged(osg::Node *child)
|
||||||
{
|
{
|
||||||
qDebug() << "OSGGroup::onChildNodeChanged" << node;
|
// qDebug() << "OSGGroup::onChildNodeChanged" << node;
|
||||||
OSGNode *obj = qobject_cast<OSGNode *>(sender());
|
|
||||||
if (obj) {
|
osg::Group *group = static_cast<osg::Group *>(self->node());
|
||||||
osg::Node *cacheNode = cache.value(obj, NULL);
|
|
||||||
if (cacheNode) {
|
if (!group) {
|
||||||
group->replaceChild(cacheNode, node);
|
qWarning() << "OSGGroup::onChildNodeChanged - null group";
|
||||||
} else {
|
return;
|
||||||
// should not happen...
|
|
||||||
}
|
|
||||||
cache[obj] = node;
|
|
||||||
// emit self->nodeChanged(group.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OSGNode *childNode = qobject_cast<OSGNode *>(sender());
|
||||||
|
// qDebug() << "OSGGroup::onChildNodeChanged - child node" << obj;
|
||||||
|
if (!childNode) {
|
||||||
|
qWarning() << "OSGGroup::onChildNodeChanged - sender is not an OSGNode" << sender();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (childNode->node() != child) {
|
||||||
|
qWarning() << "OSGGroup::onChildNodeChanged - child node is not valid" << childNode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool updated = false;
|
||||||
|
osg::Node *current = cache.value(childNode, NULL);
|
||||||
|
if (current) {
|
||||||
|
updated |= group->replaceChild(current, child);
|
||||||
|
} else {
|
||||||
|
// should not happen...
|
||||||
|
qWarning() << "OSGGroup::onChildNodeChanged - child node is not a child" << childNode;
|
||||||
|
}
|
||||||
|
cache[childNode] = childNode->node();
|
||||||
|
// if (updated) {
|
||||||
|
// emit self->nodeChanged(group.get());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* class OSGGGroupNode */
|
/* class OSGGGroupNode */
|
||||||
|
|
||||||
OSGGroup::OSGGroup(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
OSGGroup::OSGGroup(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
{
|
{}
|
||||||
qDebug() << "OSGGroup::OSGGroup";
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGGroup::~OSGGroup()
|
OSGGroup::~OSGGroup()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGGroup::~OSGGroup";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlListProperty<OSGNode> OSGGroup::children()
|
QQmlListProperty<OSGNode> OSGGroup::children() const
|
||||||
{
|
{
|
||||||
return QQmlListProperty<OSGNode>(h, 0,
|
return QQmlListProperty<OSGNode>(h, 0,
|
||||||
&Hidden::append_child,
|
&Hidden::append_child,
|
||||||
@ -180,34 +208,17 @@ QQmlListProperty<OSGNode> OSGGroup::children()
|
|||||||
&Hidden::clear_child);
|
&Hidden::clear_child);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGGroup::update()
|
osg::Node *OSGGroup::createNode()
|
||||||
{
|
{
|
||||||
|
return h->createNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGGroup::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
if (isDirty(Children)) {
|
if (isDirty(Children)) {
|
||||||
h->updateGroupNode();
|
h->updateChildren();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGGroup::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGGroup::attach " << view;
|
|
||||||
QListIterator<OSGNode *> i(h->children);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
OSGNode *node = i.next();
|
|
||||||
// qDebug() << "OSGGroup::attach - child" << node;
|
|
||||||
OSGNode::attach(node, view);
|
|
||||||
}
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGGroup::detach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGGroup::detach " << view;
|
|
||||||
QListIterator<OSGNode *> i(h->children);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
OSGNode *node = i.next();
|
|
||||||
// qDebug() << "OSGGroup::detach - child" << node;
|
|
||||||
OSGNode::detach(node, view);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGGroup.hpp
|
* @file OSGGroup.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -39,20 +39,21 @@ class OSGQTQUICK_EXPORT OSGGroup : public OSGNode {
|
|||||||
|
|
||||||
Q_CLASSINFO("DefaultProperty", "children")
|
Q_CLASSINFO("DefaultProperty", "children")
|
||||||
|
|
||||||
|
typedef OSGNode Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OSGGroup(QObject *parent = 0);
|
explicit OSGGroup(QObject *parent = 0);
|
||||||
virtual ~OSGGroup();
|
virtual ~OSGGroup();
|
||||||
|
|
||||||
QQmlListProperty<OSGNode> children();
|
QQmlListProperty<OSGNode> children() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
128
ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.cpp
Normal file
128
ground/gcs/src/libs/osgearth/osgQtQuick/OSGImageNode.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGImageNode.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "OSGImageNode.hpp"
|
||||||
|
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
|
||||||
|
#include <osgDB/ReadFile>
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { ImageFile = 1 << 0 };
|
||||||
|
|
||||||
|
struct OSGImageNode::Hidden : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGImageNode * const self;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Texture2D> texture;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QUrl url;
|
||||||
|
|
||||||
|
Hidden(OSGImageNode *self) : QObject(self), self(self), url()
|
||||||
|
{}
|
||||||
|
|
||||||
|
osg::Node *createNode()
|
||||||
|
{
|
||||||
|
osg::Drawable *quad = osg::createTexturedQuadGeometry(osg::Vec3(0, 0, 0), osg::Vec3(1, 0, 0), osg::Vec3(0, 1, 0));
|
||||||
|
|
||||||
|
osg::Geode *geode = new osg::Geode;
|
||||||
|
|
||||||
|
geode->addDrawable(quad);
|
||||||
|
|
||||||
|
geode->setStateSet(createState());
|
||||||
|
|
||||||
|
return geode;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::StateSet *createState()
|
||||||
|
{
|
||||||
|
texture = new osg::Texture2D;
|
||||||
|
|
||||||
|
// create the StateSet to store the texture data
|
||||||
|
osg::StateSet *stateset = new osg::StateSet;
|
||||||
|
|
||||||
|
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
return stateset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateImageFile()
|
||||||
|
{
|
||||||
|
qDebug() << "OSGImageNode::updateImageFile - reading image file" << url.path();
|
||||||
|
osg::Image *image = osgDB::readImageFile(url.path().toStdString());
|
||||||
|
if (texture.valid()) {
|
||||||
|
texture->setImage(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class OSGImageNode */
|
||||||
|
|
||||||
|
OSGImageNode::OSGImageNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
OSGImageNode::~OSGImageNode()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QUrl OSGImageNode::imageFile() const
|
||||||
|
{
|
||||||
|
return h->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGImageNode::setImageFile(const QUrl &url)
|
||||||
|
{
|
||||||
|
if (h->url != url) {
|
||||||
|
h->url = url;
|
||||||
|
setDirty(ImageFile);
|
||||||
|
emit imageFileChanged(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Node *OSGImageNode::createNode()
|
||||||
|
{
|
||||||
|
return h->createNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGImageNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
|
if (isDirty(ImageFile)) {
|
||||||
|
h->updateImageFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#include "OSGImageNode.moc"
|
@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGBackgroundNode.hpp
|
* @file OSGImageNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -25,24 +25,23 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _H_OSGQTQUICK_BACKGROUNDNODE_H_
|
#ifndef _H_OSGQTQUICK_IMAGENODE_H_
|
||||||
#define _H_OSGQTQUICK_BACKGROUNDNODE_H_
|
#define _H_OSGQTQUICK_IMAGENODE_H_
|
||||||
|
|
||||||
#include "Export.hpp"
|
#include "Export.hpp"
|
||||||
#include "OSGNode.hpp"
|
#include "OSGNode.hpp"
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QUrl;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class OSGQTQUICK_EXPORT OSGBackgroundNode : public OSGNode {
|
class OSGQTQUICK_EXPORT OSGImageNode : public OSGNode {
|
||||||
Q_OBJECT Q_PROPERTY(QUrl imageFile READ imageFile WRITE setImageFile NOTIFY imageFileChanged)
|
Q_OBJECT Q_PROPERTY(QUrl imageFile READ imageFile WRITE setImageFile NOTIFY imageFileChanged)
|
||||||
|
|
||||||
|
typedef OSGNode Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGBackgroundNode(QObject *parent = 0);
|
OSGImageNode(QObject *parent = 0);
|
||||||
virtual ~OSGBackgroundNode();
|
virtual ~OSGImageNode();
|
||||||
|
|
||||||
const QUrl imageFile() const;
|
const QUrl imageFile() const;
|
||||||
void setImageFile(const QUrl &url);
|
void setImageFile(const QUrl &url);
|
||||||
@ -50,15 +49,14 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void imageFileChanged(const QUrl &url);
|
void imageFileChanged(const QUrl &url);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#endif // _H_OSGQTQUICK_BACKGROUNDNODE_H_
|
#endif // _H_OSGQTQUICK_IMAGENODE_H_
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGNode.cpp
|
* @file OSGNode.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,75 +27,39 @@
|
|||||||
|
|
||||||
#include "OSGNode.hpp"
|
#include "OSGNode.hpp"
|
||||||
|
|
||||||
|
#include "DirtySupport.hpp"
|
||||||
|
|
||||||
#include <osg/Node>
|
#include <osg/Node>
|
||||||
#include <osg/NodeVisitor>
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class OSGNode;
|
class OSGNode;
|
||||||
class Hidden;
|
|
||||||
|
|
||||||
struct NodeUpdateCallback : public osg::NodeCallback {
|
struct OSGNode::Hidden : public QObject, public DirtySupport {
|
||||||
public:
|
|
||||||
NodeUpdateCallback(OSGNode::Hidden *h) : h(h) {}
|
|
||||||
|
|
||||||
void operator()(osg::Node *node, osg::NodeVisitor *nv);
|
|
||||||
|
|
||||||
private:
|
|
||||||
OSGNode::Hidden *const h;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OSGNode::Hidden : public QObject {
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
friend class OSGNode;
|
friend class OSGNode;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGNode *const self;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Node> node;
|
||||||
|
|
||||||
|
bool complete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Hidden(OSGNode *node) : QObject(node), self(node), dirty(0)
|
Hidden(OSGNode *self) : QObject(self), self(self), complete(false) /*, dirty(0)*/
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool isDirty(int mask)
|
osg::Node *nodeToUpdate() const
|
||||||
{
|
{
|
||||||
return (dirty && mask) != 0;
|
return self->node();
|
||||||
}
|
|
||||||
|
|
||||||
void setDirty(int mask)
|
|
||||||
{
|
|
||||||
// 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 |= mask;
|
|
||||||
// qDebug() << "OSGNode::setDirty DONE";
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearDirty()
|
|
||||||
{
|
|
||||||
dirty = 0;
|
|
||||||
if (node && nodeUpdateCallback.valid()) {
|
|
||||||
// qDebug() << "OSGNode::clearDirty REMOVE CALLBACK";
|
|
||||||
node->setUpdateCallback(NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update()
|
void update()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGNode::update BEGIN";
|
return self->updateNode();
|
||||||
if (dirty) {
|
|
||||||
// qDebug() << "OSGNode::update UPDATE";
|
|
||||||
self->update();
|
|
||||||
}
|
|
||||||
clearDirty();
|
|
||||||
// qDebug() << "OSGNode::update DONE";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acceptNode(osg::Node *aNode)
|
bool acceptNode(osg::Node *aNode)
|
||||||
@ -103,43 +67,24 @@ public:
|
|||||||
if (node == aNode) {
|
if (node == aNode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (node && dirty) {
|
|
||||||
// qDebug() << "OSGNode::acceptNode REMOVE CALLBACK" << node;
|
int flags = dirty();
|
||||||
node->setUpdateCallback(NULL);
|
if (flags) {
|
||||||
|
clearDirty();
|
||||||
}
|
}
|
||||||
node = aNode;
|
node = aNode;
|
||||||
if (node) {
|
if (node) {
|
||||||
if (dirty) {
|
if (flags) {
|
||||||
if (!nodeUpdateCallback.valid()) {
|
setDirty(flags);
|
||||||
// lazy creation
|
|
||||||
// qDebug() << "OSGNode::acceptNode CREATE CALLBACK";
|
|
||||||
nodeUpdateCallback = new NodeUpdateCallback(this);
|
|
||||||
}
|
|
||||||
// qDebug() << "OSGNode::acceptNode ADD CALLBACK";
|
|
||||||
node->setUpdateCallback(nodeUpdateCallback);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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)
|
/* class OSGNode */
|
||||||
{
|
|
||||||
// qDebug() << "NodeUpdateCallback::";
|
|
||||||
nv->traverse(*node);
|
|
||||||
h->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGNode::OSGNode(QObject *parent) : QObject(parent), h(new Hidden(this))
|
OSGNode::OSGNode(QObject *parent) : QObject(parent), QQmlParserStatus(), h(new Hidden(this))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
OSGNode::~OSGNode()
|
OSGNode::~OSGNode()
|
||||||
@ -155,16 +100,11 @@ osg::Node *OSGNode::node() const
|
|||||||
void OSGNode::setNode(osg::Node *node)
|
void OSGNode::setNode(osg::Node *node)
|
||||||
{
|
{
|
||||||
if (h->acceptNode(node)) {
|
if (h->acceptNode(node)) {
|
||||||
emit nodeChanged(node);
|
emitNodeChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSGNode::isDirty()
|
bool OSGNode::isDirty(int mask) const
|
||||||
{
|
|
||||||
return h->isDirty(0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OSGNode::isDirty(int mask)
|
|
||||||
{
|
{
|
||||||
return h->isDirty(mask);
|
return h->isDirty(mask);
|
||||||
}
|
}
|
||||||
@ -179,30 +119,39 @@ void OSGNode::clearDirty()
|
|||||||
h->clearDirty();
|
h->clearDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGNode::attach(OSGNode *node, osgViewer::View *view)
|
osg::Node *OSGNode::createNode()
|
||||||
{
|
{
|
||||||
if (!node) {
|
return NULL;
|
||||||
return;
|
|
||||||
}
|
|
||||||
node->attach(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGNode::detach(OSGNode *node, osgViewer::View *view)
|
void OSGNode::updateNode()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void OSGNode::emitNodeChanged()
|
||||||
{
|
{
|
||||||
if (!node) {
|
if (h->complete) {
|
||||||
return;
|
emit nodeChanged(node());
|
||||||
}
|
}
|
||||||
node->detach(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGNode::update()
|
void OSGNode::classBegin()
|
||||||
{}
|
{
|
||||||
|
// qDebug() << "OSGNode::classBegin" << this;
|
||||||
|
|
||||||
void OSGNode::attach(osgViewer::View *view)
|
setNode(createNode());
|
||||||
{}
|
}
|
||||||
|
|
||||||
void OSGNode::detach(osgViewer::View *view)
|
void OSGNode::componentComplete()
|
||||||
{}
|
{
|
||||||
|
// qDebug() << "OSGNode::componentComplete" << this;
|
||||||
|
|
||||||
|
updateNode();
|
||||||
|
clearDirty();
|
||||||
|
h->complete = true;
|
||||||
|
if (!h->node.valid()) {
|
||||||
|
qWarning() << "OSGNode::componentComplete - node is not valid!" << this;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#include "OSGNode.moc"
|
#include "OSGNode.moc"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGNode.hpp
|
* @file OSGNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include "Export.hpp"
|
#include "Export.hpp"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QQmlParserStatus>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only update() methods are allowed to update the OSG scenegraph.
|
* Only update() methods are allowed to update the OSG scenegraph.
|
||||||
@ -39,25 +40,19 @@
|
|||||||
* - node change events should be handled right away.
|
* - node change events should be handled right away.
|
||||||
*
|
*
|
||||||
* Setting an OSGNode dirty will trigger the addition of a one time update callback.
|
* Setting an OSGNode dirty will trigger the addition of a one time update callback.
|
||||||
* *
|
|
||||||
* This approach leads to some potential issues:
|
* 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).
|
* - 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 {
|
namespace osg {
|
||||||
class Node;
|
class Node;
|
||||||
} // namespace osg
|
} // namespace osg
|
||||||
|
|
||||||
namespace osgViewer {
|
|
||||||
class View;
|
|
||||||
} // namespace osgViewer
|
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class OSGQTQUICK_EXPORT OSGNode : public QObject {
|
class OSGQTQUICK_EXPORT OSGNode : public QObject, public QQmlParserStatus {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QQmlParserStatus)
|
||||||
friend class OSGViewport;
|
|
||||||
friend class NodeUpdateCallback;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OSGNode(QObject *parent = 0);
|
explicit OSGNode(QObject *parent = 0);
|
||||||
@ -66,31 +61,25 @@ public:
|
|||||||
osg::Node *node() const;
|
osg::Node *node() const;
|
||||||
void setNode(osg::Node *node);
|
void setNode(osg::Node *node);
|
||||||
|
|
||||||
protected:
|
|
||||||
bool isDirty();
|
|
||||||
bool isDirty(int mask);
|
|
||||||
void setDirty(int mask);
|
|
||||||
void clearDirty();
|
|
||||||
|
|
||||||
void emitNodeChanged()
|
|
||||||
{
|
|
||||||
emit nodeChanged(node());
|
|
||||||
}
|
|
||||||
|
|
||||||
void attach(OSGNode *node, osgViewer::View *view);
|
|
||||||
void detach(OSGNode *node, osgViewer::View *view);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nodeChanged(osg::Node *node) const;
|
void nodeChanged(osg::Node *node) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isDirty(int mask = 0xFFFF) const;
|
||||||
|
void setDirty(int mask = 0xFFFF);
|
||||||
|
void clearDirty();
|
||||||
|
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
|
void emitNodeChanged();
|
||||||
|
|
||||||
|
void classBegin();
|
||||||
|
void componentComplete();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGShapeNode.cpp
|
* @file OSGShapeNode.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "OSGShapeNode.hpp"
|
#include "OSGShapeNode.hpp"
|
||||||
|
|
||||||
#include "../shapeutils.h"
|
#include "utils/shapeutils.h"
|
||||||
|
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
#include <osg/Group>
|
#include <osg/Group>
|
||||||
@ -37,19 +37,21 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { ShapeType = 1 << 0 };
|
||||||
|
|
||||||
struct OSGShapeNode::Hidden : public QObject {
|
struct OSGShapeNode::Hidden : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OSGShapeNode * self;
|
OSGShapeNode * const self;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShapeType::Enum shapeType;
|
ShapeType::Enum shapeType;
|
||||||
|
|
||||||
Hidden(OSGShapeNode *node) : QObject(node), self(node), shapeType(ShapeType::Sphere)
|
Hidden(OSGShapeNode *self) : QObject(self), self(self), shapeType(ShapeType::Sphere)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void updateNode()
|
void updateShapeType()
|
||||||
{
|
{
|
||||||
osg::Node *node = NULL;
|
osg::Node *node = NULL;
|
||||||
|
|
||||||
@ -67,26 +69,19 @@ public:
|
|||||||
node = ShapeUtils::create3DAxis();
|
node = ShapeUtils::create3DAxis();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Add the node to the scene
|
|
||||||
self->setNode(node);
|
self->setNode(node);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* class OSGShapeNode */
|
/* class OSGShapeNode */
|
||||||
|
|
||||||
enum DirtyFlag { Type = 1 << 0 };
|
OSGShapeNode::OSGShapeNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
|
||||||
// TODO turn into generic shape node...
|
|
||||||
// see http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/TransformsAndStates
|
|
||||||
OSGShapeNode::OSGShapeNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
|
||||||
{
|
{
|
||||||
qDebug() << "OSGShapeNode::OSGShapeNode";
|
setDirty(ShapeType);
|
||||||
setShapeType(ShapeType::Sphere);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGShapeNode::~OSGShapeNode()
|
OSGShapeNode::~OSGShapeNode()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGShapeNode::~OSGShapeNode";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,26 +94,24 @@ void OSGShapeNode::setShapeType(ShapeType::Enum type)
|
|||||||
{
|
{
|
||||||
if (h->shapeType != type) {
|
if (h->shapeType != type) {
|
||||||
h->shapeType = type;
|
h->shapeType = type;
|
||||||
setDirty(Type);
|
setDirty(ShapeType);
|
||||||
emit shapeTypeChanged(type);
|
emit shapeTypeChanged(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGShapeNode::update()
|
osg::Node *OSGShapeNode::createNode()
|
||||||
{
|
{
|
||||||
if (isDirty(Type)) {
|
return NULL;
|
||||||
h->updateNode();
|
}
|
||||||
|
|
||||||
|
void OSGShapeNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
|
if (isDirty(ShapeType)) {
|
||||||
|
h->updateShapeType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGShapeNode::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGShapeNode::detach(osgViewer::View *view)
|
|
||||||
{}
|
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#include "OSGShapeNode.moc"
|
#include "OSGShapeNode.moc"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGShapeNode.hpp
|
* @file OSGShapeNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -42,6 +42,8 @@ public:
|
|||||||
class OSGQTQUICK_EXPORT OSGShapeNode : public OSGNode {
|
class OSGQTQUICK_EXPORT OSGShapeNode : public OSGNode {
|
||||||
Q_OBJECT Q_PROPERTY(osgQtQuick::ShapeType::Enum shapeType READ shapeType WRITE setShapeType NOTIFY shapeTypeChanged)
|
Q_OBJECT Q_PROPERTY(osgQtQuick::ShapeType::Enum shapeType READ shapeType WRITE setShapeType NOTIFY shapeTypeChanged)
|
||||||
|
|
||||||
|
typedef OSGNode Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGShapeNode(QObject *parent = 0);
|
OSGShapeNode(QObject *parent = 0);
|
||||||
virtual ~OSGShapeNode();
|
virtual ~OSGShapeNode();
|
||||||
@ -52,14 +54,13 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void shapeTypeChanged(ShapeType::Enum);
|
void shapeTypeChanged(ShapeType::Enum);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGSkyNode.cpp
|
* @file OSGSkyNode.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "OSGSkyNode.hpp"
|
#include "OSGSkyNode.hpp"
|
||||||
|
|
||||||
|
#include "OSGViewport.hpp"
|
||||||
|
|
||||||
#include <osgViewer/View>
|
#include <osgViewer/View>
|
||||||
|
|
||||||
#include <osgEarth/Config>
|
#include <osgEarth/Config>
|
||||||
@ -39,6 +41,8 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { Scene = 1 << 0, Viewport = 1 << 1, DateTime = 1 << 2, Light = 1 << 3 };
|
||||||
|
|
||||||
struct OSGSkyNode::Hidden : public QObject {
|
struct OSGSkyNode::Hidden : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -48,13 +52,15 @@ private:
|
|||||||
osg::ref_ptr<osgEarth::Util::SkyNode> skyNode;
|
osg::ref_ptr<osgEarth::Util::SkyNode> skyNode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGNode *sceneNode;
|
OSGNode *sceneNode;
|
||||||
|
OSGViewport *viewport;
|
||||||
|
|
||||||
bool sunLightEnabled;
|
bool sunLightEnabled;
|
||||||
QDateTime dateTime;
|
QDateTime dateTime;
|
||||||
double minimumAmbientLight;
|
double minimumAmbientLight;
|
||||||
|
|
||||||
Hidden(OSGSkyNode *node) : QObject(node), self(node), sceneNode(NULL), sunLightEnabled(true), minimumAmbientLight(0.03)
|
Hidden(OSGSkyNode *self) : QObject(self), self(self), sceneNode(NULL), viewport(NULL),
|
||||||
|
sunLightEnabled(true), minimumAmbientLight(0.03)
|
||||||
{
|
{
|
||||||
dateTime = QDateTime::currentDateTime();
|
dateTime = QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
@ -76,27 +82,28 @@ public:
|
|||||||
sceneNode = node;
|
sceneNode = node;
|
||||||
|
|
||||||
if (sceneNode) {
|
if (sceneNode) {
|
||||||
connect(sceneNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onSceneNodeChanged(osg::Node *)));
|
connect(sceneNode, &OSGNode::nodeChanged, this, &OSGSkyNode::Hidden::onSceneNodeChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSkyNode()
|
void updateScene()
|
||||||
{
|
{
|
||||||
if (!sceneNode || !sceneNode->node()) {
|
if (!sceneNode || !sceneNode->node()) {
|
||||||
qWarning() << "OSGSkyNode::acceptNode - scene node not valid";
|
qWarning() << "OSGSkyNode::updateScene - scene node not valid";
|
||||||
self->setNode(NULL);
|
self->setNode(NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
qDebug() << "OSGSkyNode::updateScene - scene node" << sceneNode->node();
|
||||||
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
||||||
if (!mapNode) {
|
if (!mapNode) {
|
||||||
qWarning() << "OSGSkyNode::acceptNode - scene node does not contain a map node";
|
qWarning() << "OSGSkyNode::updateScene - scene node does not contain a map node";
|
||||||
self->setNode(NULL);
|
self->setNode(NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mapNode->getMap()->isGeocentric()) {
|
if (!mapNode->getMap()->isGeocentric()) {
|
||||||
qWarning() << "OSGSkyNode::acceptNode - map node is not geocentric";
|
qWarning() << "OSGSkyNode::updateScene - map node is not geocentric";
|
||||||
self->setNode(NULL);
|
self->setNode(NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -117,7 +124,7 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
skyNode->removeChild(0, 1);
|
skyNode->removeChild(0, 1);
|
||||||
skyNode->addChild(sceneNode->node());
|
skyNode->addChild(sceneNode->node());
|
||||||
self->emitNodeChanged();
|
// self->emitNodeChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +149,23 @@ public:
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void updateViewport()
|
||||||
|
{
|
||||||
|
qDebug() << "OSGSkyNode::updateViewport" << skyNode;
|
||||||
|
if (!skyNode.valid()) {
|
||||||
|
qWarning() << "OSGSkyNode::updateViewport - invalid sky node" << skyNode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "OSGSkyNode::updateViewport - attaching to" << viewport->asView();
|
||||||
|
skyNode->attach(viewport->asView());
|
||||||
|
}
|
||||||
|
|
||||||
void updateSunLightEnabled()
|
void updateSunLightEnabled()
|
||||||
{
|
{
|
||||||
|
if (!skyNode.valid()) {
|
||||||
|
qWarning() << "OSGSkyNode::updateSunLightEnabled - invalid sky node";
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!skyNode.valid()) {
|
if (!skyNode.valid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -153,10 +175,11 @@ public:
|
|||||||
void updateDateTime()
|
void updateDateTime()
|
||||||
{
|
{
|
||||||
if (!skyNode.valid()) {
|
if (!skyNode.valid()) {
|
||||||
|
qWarning() << "OSGSkyNode::updateDateTime - invalid sky node";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!dateTime.isValid()) {
|
if (!dateTime.isValid()) {
|
||||||
qWarning() << "OSGSkyNode::acceptDateTime - invalid date/time" << dateTime;
|
qWarning() << "OSGSkyNode::updateDateTime - invalid date/time" << dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDate date = dateTime.date();
|
QDate date = dateTime.date();
|
||||||
@ -168,6 +191,7 @@ public:
|
|||||||
void updateMinimumAmbientLight()
|
void updateMinimumAmbientLight()
|
||||||
{
|
{
|
||||||
if (!skyNode.valid()) {
|
if (!skyNode.valid()) {
|
||||||
|
qWarning() << "OSGSkyNode::updateMinimumAmbientLight - invalid sky node";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
double d = minimumAmbientLight;
|
double d = minimumAmbientLight;
|
||||||
@ -193,28 +217,23 @@ private slots:
|
|||||||
void onSceneNodeChanged(osg::Node *node)
|
void onSceneNodeChanged(osg::Node *node)
|
||||||
{
|
{
|
||||||
qDebug() << "OSGSkyNode::onSceneNodeChanged" << node;
|
qDebug() << "OSGSkyNode::onSceneNodeChanged" << node;
|
||||||
updateSkyNode();
|
updateScene();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* class OSGSkyNode */
|
/* class OSGSkyNode */
|
||||||
|
|
||||||
enum DirtyFlag { Child = 1 << 0, DateTime = 1 << 1, Light = 1 << 2 };
|
OSGSkyNode::OSGSkyNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
|
||||||
OSGSkyNode::OSGSkyNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
|
||||||
{
|
{
|
||||||
qDebug() << "OSGSkyNode::OSGSkyNode";
|
setDirty(DateTime | Light);
|
||||||
setSunLightEnabled(true);
|
|
||||||
setMinimumAmbientLight(0.03);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGSkyNode::~OSGSkyNode()
|
OSGSkyNode::~OSGSkyNode()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGSkyNode::~OSGSkyNode";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGNode *OSGSkyNode::sceneNode()
|
OSGNode *OSGSkyNode::sceneNode() const
|
||||||
{
|
{
|
||||||
return h->sceneNode;
|
return h->sceneNode;
|
||||||
}
|
}
|
||||||
@ -222,12 +241,26 @@ OSGNode *OSGSkyNode::sceneNode()
|
|||||||
void OSGSkyNode::setSceneNode(OSGNode *node)
|
void OSGSkyNode::setSceneNode(OSGNode *node)
|
||||||
{
|
{
|
||||||
if (h->acceptSceneNode(node)) {
|
if (h->acceptSceneNode(node)) {
|
||||||
setDirty(Child);
|
setDirty(Scene);
|
||||||
emit sceneNodeChanged(node);
|
emit sceneNodeChanged(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSGSkyNode::sunLightEnabled()
|
OSGViewport *OSGSkyNode::viewport() const
|
||||||
|
{
|
||||||
|
return h->viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGSkyNode::setViewport(OSGViewport *viewport)
|
||||||
|
{
|
||||||
|
if (h->viewport != viewport) {
|
||||||
|
h->viewport = viewport;
|
||||||
|
setDirty(Viewport);
|
||||||
|
emit viewportChanged(viewport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSGSkyNode::sunLightEnabled() const
|
||||||
{
|
{
|
||||||
return h->sunLightEnabled;
|
return h->sunLightEnabled;
|
||||||
}
|
}
|
||||||
@ -241,7 +274,7 @@ void OSGSkyNode::setSunLightEnabled(bool enabled)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime OSGSkyNode::dateTime()
|
QDateTime OSGSkyNode::dateTime() const
|
||||||
{
|
{
|
||||||
return h->dateTime;
|
return h->dateTime;
|
||||||
}
|
}
|
||||||
@ -255,7 +288,7 @@ void OSGSkyNode::setDateTime(QDateTime dateTime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double OSGSkyNode::minimumAmbientLight()
|
double OSGSkyNode::minimumAmbientLight() const
|
||||||
{
|
{
|
||||||
return h->minimumAmbientLight;
|
return h->minimumAmbientLight;
|
||||||
}
|
}
|
||||||
@ -269,10 +302,20 @@ void OSGSkyNode::setMinimumAmbientLight(double ambient)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGSkyNode::update()
|
osg::Node *OSGSkyNode::createNode()
|
||||||
{
|
{
|
||||||
if (isDirty(Child)) {
|
return NULL;
|
||||||
h->updateSkyNode();
|
}
|
||||||
|
|
||||||
|
void OSGSkyNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
|
if (isDirty(Scene)) {
|
||||||
|
h->updateScene();
|
||||||
|
}
|
||||||
|
if (isDirty(Viewport)) {
|
||||||
|
h->updateViewport();
|
||||||
}
|
}
|
||||||
if (isDirty(Light)) {
|
if (isDirty(Light)) {
|
||||||
h->updateSunLightEnabled();
|
h->updateSunLightEnabled();
|
||||||
@ -282,23 +325,6 @@ void OSGSkyNode::update()
|
|||||||
h->updateDateTime();
|
h->updateDateTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGSkyNode::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGSkyNode::attach " << view;
|
|
||||||
OSGNode::attach(h->sceneNode, view);
|
|
||||||
|
|
||||||
h->attachSkyNode(view);
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGSkyNode::detach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGSkyNode::detach " << view;
|
|
||||||
h->detachSkyNode(view);
|
|
||||||
OSGNode::detach(h->sceneNode, view);
|
|
||||||
}
|
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#include "OSGSkyNode.moc"
|
#include "OSGSkyNode.moc"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGSkyNode.hpp
|
* @file OSGSkyNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -43,45 +43,52 @@ class QUrl;
|
|||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class OSGQTQUICK_EXPORT OSGSkyNode : public OSGNode {
|
class OSGViewport;
|
||||||
// TODO rename to sceneNode
|
|
||||||
Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneData READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
|
||||||
|
|
||||||
|
// TODO should derive from OSGGroup
|
||||||
|
class OSGQTQUICK_EXPORT OSGSkyNode : public OSGNode {
|
||||||
|
Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
||||||
|
Q_PROPERTY(osgQtQuick::OSGViewport * viewport READ viewport WRITE setViewport NOTIFY viewportChanged)
|
||||||
Q_PROPERTY(bool sunLightEnabled READ sunLightEnabled WRITE setSunLightEnabled NOTIFY sunLightEnabledChanged)
|
Q_PROPERTY(bool sunLightEnabled READ sunLightEnabled WRITE setSunLightEnabled NOTIFY sunLightEnabledChanged)
|
||||||
Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged)
|
Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged)
|
||||||
Q_PROPERTY(double minimumAmbientLight READ minimumAmbientLight WRITE setMinimumAmbientLight NOTIFY minimumAmbientLightChanged)
|
Q_PROPERTY(double minimumAmbientLight READ minimumAmbientLight WRITE setMinimumAmbientLight NOTIFY minimumAmbientLightChanged)
|
||||||
|
|
||||||
|
typedef OSGNode Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGSkyNode(QObject *parent = 0);
|
OSGSkyNode(QObject *parent = 0);
|
||||||
virtual ~OSGSkyNode();
|
virtual ~OSGSkyNode();
|
||||||
|
|
||||||
OSGNode *sceneNode();
|
OSGNode *sceneNode() const;
|
||||||
void setSceneNode(OSGNode *node);
|
void setSceneNode(OSGNode *node);
|
||||||
|
|
||||||
bool sunLightEnabled();
|
OSGViewport *viewport() const;
|
||||||
|
void setViewport(OSGViewport *viewport);
|
||||||
|
|
||||||
|
bool sunLightEnabled() const;
|
||||||
void setSunLightEnabled(bool arg);
|
void setSunLightEnabled(bool arg);
|
||||||
|
|
||||||
QDateTime dateTime();
|
QDateTime dateTime() const;
|
||||||
void setDateTime(QDateTime arg);
|
void setDateTime(QDateTime arg);
|
||||||
|
|
||||||
double minimumAmbientLight();
|
double minimumAmbientLight() const;
|
||||||
void setMinimumAmbientLight(double arg);
|
void setMinimumAmbientLight(double arg);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sceneNodeChanged(OSGNode *node);
|
void sceneNodeChanged(OSGNode *node);
|
||||||
|
void viewportChanged(OSGViewport *viewport);
|
||||||
|
|
||||||
void sunLightEnabledChanged(bool arg);
|
void sunLightEnabledChanged(bool arg);
|
||||||
void dateTimeChanged(QDateTime arg);
|
void dateTimeChanged(QDateTime arg);
|
||||||
void minimumAmbientLightChanged(double arg);
|
void minimumAmbientLightChanged(double arg);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGTextNode.cpp
|
* @file OSGTextNode.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "OSGTextNode.hpp"
|
#include "OSGTextNode.hpp"
|
||||||
|
|
||||||
#include "../utility.h"
|
#include "utils/utility.h"
|
||||||
|
|
||||||
#include <osgText/Text>
|
#include <osgText/Text>
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
@ -37,6 +37,8 @@
|
|||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { Text = 1 << 0, Color = 1 << 1 };
|
||||||
|
|
||||||
struct OSGTextNode::Hidden : public QObject {
|
struct OSGTextNode::Hidden : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -49,24 +51,24 @@ public:
|
|||||||
QString textString;
|
QString textString;
|
||||||
QColor color;
|
QColor color;
|
||||||
|
|
||||||
Hidden(OSGTextNode *node) : QObject(node), self(node)
|
Hidden(OSGTextNode *self) : QObject(self), self(self)
|
||||||
|
{}
|
||||||
|
|
||||||
|
osg::Node *createNode()
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osgText::Font> textFont = createFont(QFont("Times"));
|
osg::ref_ptr<osgText::Font> textFont = createFont(QFont("Times"));
|
||||||
|
|
||||||
text = createText(osg::Vec3(-100, 20, 0), "Hello World", 20.0f,
|
text = createText(osg::Vec3(-100, 20, 0), "Hello World", 20.0f, textFont.get());
|
||||||
textFont.get());
|
osg::ref_ptr<osg::Geode> textGeode = new osg::Geode();
|
||||||
osg::ref_ptr<osg::Geode> textGeode = new osg::Geode();
|
|
||||||
textGeode->addDrawable(text.get());
|
textGeode->addDrawable(text.get());
|
||||||
#if 0
|
#if 0
|
||||||
text->setAutoRotateToScreen(true);
|
text->setAutoRotateToScreen(true);
|
||||||
self->setNode(textGeode.get());
|
|
||||||
#else
|
#else
|
||||||
osg::Camera *camera = createHUDCamera(-100, 100, -100, 100);
|
osg::Camera *camera = createHUDCamera(-100, 100, -100, 100);
|
||||||
camera->addChild(textGeode.get());
|
camera->addChild(textGeode.get());
|
||||||
camera->getOrCreateStateSet()->setMode(
|
camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
GL_LIGHTING, osg::StateAttribute::OFF);
|
|
||||||
self->setNode(camera);
|
|
||||||
#endif
|
#endif
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateText()
|
void updateText()
|
||||||
@ -88,10 +90,10 @@ public:
|
|||||||
|
|
||||||
/* class OSGTextNode */
|
/* class OSGTextNode */
|
||||||
|
|
||||||
enum DirtyFlag { Text = 1 << 0, Color = 1 << 1 };
|
OSGTextNode::OSGTextNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{
|
||||||
OSGTextNode::OSGTextNode(QObject *node) : OSGNode(node), h(new Hidden(this))
|
setDirty(Text | Color);
|
||||||
{}
|
}
|
||||||
|
|
||||||
OSGTextNode::~OSGTextNode()
|
OSGTextNode::~OSGTextNode()
|
||||||
{
|
{
|
||||||
@ -126,8 +128,15 @@ void OSGTextNode::setColor(const QColor &color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGTextNode::update()
|
osg::Node *OSGTextNode::createNode()
|
||||||
{
|
{
|
||||||
|
return h->createNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGTextNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
if (isDirty(Text)) {
|
if (isDirty(Text)) {
|
||||||
h->updateText();
|
h->updateText();
|
||||||
}
|
}
|
||||||
@ -135,15 +144,6 @@ void OSGTextNode::update()
|
|||||||
h->updateColor();
|
h->updateColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGTextNode::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGTextNode::detach(osgViewer::View *view)
|
|
||||||
{}
|
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#include "OSGTextNode.moc"
|
#include "OSGTextNode.moc"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGTextNode.hpp
|
* @file OSGTextNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -38,6 +38,8 @@ class OSGQTQUICK_EXPORT OSGTextNode : public OSGNode {
|
|||||||
Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
||||||
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
||||||
|
|
||||||
|
typedef OSGNode Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OSGTextNode(QObject *parent = 0);
|
explicit OSGTextNode(QObject *parent = 0);
|
||||||
virtual ~OSGTextNode();
|
virtual ~OSGTextNode();
|
||||||
@ -52,14 +54,13 @@ signals:
|
|||||||
void textChanged(const QString &text);
|
void textChanged(const QString &text);
|
||||||
void colorChanged(const QColor &color);
|
void colorChanged(const QColor &color);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGTransformNode.cpp
|
* @file OSGTransformNode.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -34,6 +34,10 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
|
// NOTE : these flags should not overlap with OSGGroup flags!!!
|
||||||
|
// TODO : find a better way...
|
||||||
|
enum DirtyFlag { Scale = 1 << 10, Position = 1 << 11, Attitude = 1 << 12 };
|
||||||
|
|
||||||
struct OSGTransformNode::Hidden : public QObject {
|
struct OSGTransformNode::Hidden : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -43,63 +47,22 @@ private:
|
|||||||
osg::ref_ptr<osg::PositionAttitudeTransform> transform;
|
osg::ref_ptr<osg::PositionAttitudeTransform> transform;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGNode *childNode;
|
|
||||||
|
|
||||||
QVector3D scale;
|
QVector3D scale;
|
||||||
QVector3D attitude;
|
QVector3D attitude;
|
||||||
QVector3D position;
|
QVector3D position;
|
||||||
|
|
||||||
Hidden(OSGTransformNode *node) : QObject(node), self(node), childNode(NULL)
|
Hidden(OSGTransformNode *self) : QObject(self), self(self)
|
||||||
|
{}
|
||||||
|
|
||||||
|
osg::Node *createNode()
|
||||||
{
|
{
|
||||||
transform = new osg::PositionAttitudeTransform();
|
transform = new osg::PositionAttitudeTransform();
|
||||||
self->setNode(transform);
|
return transform;
|
||||||
}
|
|
||||||
|
|
||||||
bool acceptChildNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGTransformNode::acceptChildNode" << node;
|
|
||||||
if (childNode == node) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childNode) {
|
|
||||||
disconnect(childNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
childNode = node;
|
|
||||||
|
|
||||||
if (childNode) {
|
|
||||||
connect(childNode, SIGNAL(nodeChanged(osg::Node *)), this, SLOT(onChildNodeChanged(osg::Node *)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateTransformNode()
|
|
||||||
{
|
|
||||||
bool updated = false;
|
|
||||||
|
|
||||||
if (transform->getNumChildren() == 0) {
|
|
||||||
if (childNode && childNode->node()) {
|
|
||||||
updated |= transform->addChild(childNode->node());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (childNode && childNode->node()) {
|
|
||||||
if (transform->getChild(0) != childNode->node()) {
|
|
||||||
updated |= transform->removeChild(0, 1);
|
|
||||||
updated |= transform->addChild(childNode->node());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updated |= transform->removeChild(0, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if (updated) {
|
|
||||||
self->emitNodeChanged();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateScale()
|
void updateScale()
|
||||||
{
|
{
|
||||||
|
// qDebug() << "OSGTransformNode::updateScale" << scale;
|
||||||
if ((scale.x() != 0.0) || (scale.y() != 0.0) || (scale.z() != 0.0)) {
|
if ((scale.x() != 0.0) || (scale.y() != 0.0) || (scale.z() != 0.0)) {
|
||||||
transform->setScale(osg::Vec3d(scale.x(), scale.y(), scale.z()));
|
transform->setScale(osg::Vec3d(scale.x(), scale.y(), scale.z()));
|
||||||
// transform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
|
// transform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
|
||||||
@ -118,52 +81,24 @@ public:
|
|||||||
yaw, osg::Vec3d(0, 0, -1));
|
yaw, osg::Vec3d(0, 0, -1));
|
||||||
|
|
||||||
transform->setAttitude(q);
|
transform->setAttitude(q);
|
||||||
|
|
||||||
// position
|
|
||||||
transform->setPosition(osg::Vec3d(position.x(), position.y(), position.z()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePosition()
|
void updatePosition()
|
||||||
{
|
{
|
||||||
transform->setPosition(osg::Vec3d(position.x(), position.y(), position.z()));
|
transform->setPosition(osg::Vec3d(position.x(), position.y(), position.z()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onChildNodeChanged(osg::Node *node)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGTransformNode::onChildNodeChanged" << node;
|
|
||||||
updateTransformNode();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* class OSGTransformNode */
|
/* class OSGTransformNode */
|
||||||
|
|
||||||
enum DirtyFlag { Child = 1 << 0, Scale = 1 << 1, Position = 1 << 2, Attitude = 1 << 3 };
|
OSGTransformNode::OSGTransformNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
OSGTransformNode::OSGTransformNode(QObject *parent) : OSGNode(parent), h(new Hidden(this))
|
|
||||||
{
|
|
||||||
qDebug() << "OSGTransformNode::OSGTransformNode";
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGTransformNode::~OSGTransformNode()
|
OSGTransformNode::~OSGTransformNode()
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGTransformNode::~OSGTransformNode";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGNode *OSGTransformNode::childNode()
|
|
||||||
{
|
|
||||||
return h->childNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGTransformNode::setChildNode(OSGNode *node)
|
|
||||||
{
|
|
||||||
if (h->acceptChildNode(node)) {
|
|
||||||
setDirty(Child);
|
|
||||||
emit childNodeChanged(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector3D OSGTransformNode::scale() const
|
QVector3D OSGTransformNode::scale() const
|
||||||
{
|
{
|
||||||
return h->scale;
|
return h->scale;
|
||||||
@ -206,11 +141,15 @@ void OSGTransformNode::setPosition(QVector3D arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGTransformNode::update()
|
osg::Node *OSGTransformNode::createNode()
|
||||||
{
|
{
|
||||||
if (isDirty(Child)) {
|
return h->createNode();
|
||||||
h->updateTransformNode();
|
}
|
||||||
}
|
|
||||||
|
void OSGTransformNode::updateNode()
|
||||||
|
{
|
||||||
|
Inherited::updateNode();
|
||||||
|
|
||||||
if (isDirty(Scale)) {
|
if (isDirty(Scale)) {
|
||||||
h->updateScale();
|
h->updateScale();
|
||||||
}
|
}
|
||||||
@ -221,19 +160,6 @@ void OSGTransformNode::update()
|
|||||||
h->updatePosition();
|
h->updatePosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGTransformNode::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
OSGNode::attach(h->childNode, view);
|
|
||||||
|
|
||||||
update();
|
|
||||||
clearDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGTransformNode::detach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
OSGNode::detach(h->childNode, view);
|
|
||||||
}
|
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
#include "OSGTransformNode.moc"
|
#include "OSGTransformNode.moc"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGTransformNode.hpp
|
* @file OSGTransformNode.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -29,28 +29,22 @@
|
|||||||
#define _H_OSGQTQUICK_TRANSFORMNODE_H_
|
#define _H_OSGQTQUICK_TRANSFORMNODE_H_
|
||||||
|
|
||||||
#include "Export.hpp"
|
#include "Export.hpp"
|
||||||
#include "OSGNode.hpp"
|
#include "OSGGroup.hpp"
|
||||||
|
|
||||||
#include <QVector3D>
|
#include <QVector3D>
|
||||||
|
|
||||||
// TODO derive from OSGGroup...
|
|
||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class OSGQTQUICK_EXPORT OSGTransformNode : public OSGNode {
|
class OSGQTQUICK_EXPORT OSGTransformNode : public OSGGroup {
|
||||||
Q_OBJECT
|
Q_OBJECT Q_PROPERTY(QVector3D scale READ scale WRITE setScale NOTIFY scaleChanged)
|
||||||
// TODO rename to childNode
|
|
||||||
Q_PROPERTY(osgQtQuick::OSGNode *modelData READ childNode WRITE setChildNode NOTIFY childNodeChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(QVector3D scale READ scale WRITE setScale NOTIFY scaleChanged)
|
|
||||||
Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged)
|
Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged)
|
||||||
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
||||||
|
|
||||||
|
typedef OSGGroup Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OSGTransformNode(QObject *parent = 0);
|
OSGTransformNode(QObject *parent = 0);
|
||||||
virtual ~OSGTransformNode();
|
virtual ~OSGTransformNode();
|
||||||
|
|
||||||
OSGNode *childNode();
|
|
||||||
void setChildNode(OSGNode *node);
|
|
||||||
|
|
||||||
QVector3D scale() const;
|
QVector3D scale() const;
|
||||||
void setScale(QVector3D arg);
|
void setScale(QVector3D arg);
|
||||||
|
|
||||||
@ -61,20 +55,17 @@ public:
|
|||||||
void setPosition(QVector3D arg);
|
void setPosition(QVector3D arg);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void childNodeChanged(OSGNode *node);
|
|
||||||
|
|
||||||
void scaleChanged(QVector3D arg);
|
void scaleChanged(QVector3D arg);
|
||||||
void attitudeChanged(QVector3D arg);
|
void attitudeChanged(QVector3D arg);
|
||||||
void positionChanged(QVector3D arg);
|
void positionChanged(QVector3D arg);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual osg::Node *createNode();
|
||||||
|
virtual void updateNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
|
|
||||||
virtual void update();
|
|
||||||
|
|
||||||
virtual void attach(osgViewer::View *view);
|
|
||||||
virtual void detach(osgViewer::View *view);
|
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGViewport.cpp
|
* @file OSGViewport.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,13 +27,14 @@
|
|||||||
|
|
||||||
#include "OSGViewport.hpp"
|
#include "OSGViewport.hpp"
|
||||||
|
|
||||||
#include "../osgearth.h"
|
#include "osgearth.h"
|
||||||
#include "../utility.h"
|
#include "utils/utility.h"
|
||||||
|
|
||||||
#include "OSGNode.hpp"
|
#include "OSGNode.hpp"
|
||||||
#include "OSGCamera.hpp"
|
#include "OSGCamera.hpp"
|
||||||
|
|
||||||
#include <osg/Node>
|
#include <osg/Node>
|
||||||
|
#include <osg/Vec4>
|
||||||
#include <osg/DeleteHandler>
|
#include <osg/DeleteHandler>
|
||||||
#include <osg/GLObjects>
|
#include <osg/GLObjects>
|
||||||
#include <osg/ApplicationUsage>
|
#include <osg/ApplicationUsage>
|
||||||
@ -41,10 +42,7 @@
|
|||||||
#include <osgViewer/CompositeViewer>
|
#include <osgViewer/CompositeViewer>
|
||||||
#include <osgViewer/ViewerEventHandlers>
|
#include <osgViewer/ViewerEventHandlers>
|
||||||
#include <osgGA/StateSetManipulator>
|
#include <osgGA/StateSetManipulator>
|
||||||
|
#include <osgGA/CameraManipulator>
|
||||||
#ifdef USE_OSGEARTH
|
|
||||||
#include <osgEarth/MapNode>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
@ -55,10 +53,6 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
namespace osgQtQuick {
|
|
||||||
/*
|
/*
|
||||||
Debugging tips
|
Debugging tips
|
||||||
- export OSG_NOTIFY_LEVEL=DEBUG
|
- export OSG_NOTIFY_LEVEL=DEBUG
|
||||||
@ -79,18 +73,66 @@ namespace osgQtQuick {
|
|||||||
|
|
||||||
TODO : add OSGView to handle multiple views for a given OSGViewport
|
TODO : add OSGView to handle multiple views for a given OSGViewport
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
that's a typical error when working with high-resolution (retina)
|
||||||
|
displays. The issue here is that on the high-resolution devices, the UI
|
||||||
|
operates with a virtual pixel size that is smaller than the real number
|
||||||
|
of pixels on the device. For example, you get coordinates from 0 to 2048
|
||||||
|
while the real device resolution if 4096 pixels. This factor has to be
|
||||||
|
taken into account when mapping from window coordinates to OpenGL, e.g.,
|
||||||
|
when calling glViewport.
|
||||||
|
|
||||||
|
How you can get this factor depends on the GUI library you are using. In
|
||||||
|
Qt, you can query it with QWindow::devicePixelRatio():
|
||||||
|
http://doc.qt.io/qt-5/qwindow.html#devicePixelRatio
|
||||||
|
|
||||||
|
So, there should be something like
|
||||||
|
glViewport(0, 0, window->width() * window->devicePixelRatio(),
|
||||||
|
window->height() * window->devicePixelRatio()).
|
||||||
|
|
||||||
|
Also keep in mind that you have to do the same e.g. for mouse coordinates.
|
||||||
|
|
||||||
|
I think osgQt already handles this correctly, so you shouldn't have to
|
||||||
|
worry about this if you use the classes provided by osgQt ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
// enum DirtyFlag { Scene = 1 << 0, Camera = 1 << 1 };
|
||||||
|
|
||||||
|
class ViewportRenderer;
|
||||||
|
|
||||||
struct OSGViewport::Hidden : public QObject {
|
struct OSGViewport::Hidden : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
friend ViewportRenderer;
|
||||||
|
|
||||||
Hidden(OSGViewport *viewport) : QObject(viewport),
|
private:
|
||||||
self(viewport),
|
OSGViewport *const self;
|
||||||
window(NULL),
|
|
||||||
sceneData(NULL),
|
QQuickWindow *window;
|
||||||
camera(NULL),
|
|
||||||
updateMode(UpdateMode::Discrete),
|
int frameTimer;
|
||||||
frameTimer(-1)
|
|
||||||
|
osg::ref_ptr<osg::GraphicsContext> gc;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OSGNode *sceneNode;
|
||||||
|
OSGCamera *cameraNode;
|
||||||
|
|
||||||
|
osg::ref_ptr<osgViewer::CompositeViewer> viewer;
|
||||||
|
osg::ref_ptr<osgViewer::View> view;
|
||||||
|
|
||||||
|
OSGCameraManipulator *manipulator;
|
||||||
|
|
||||||
|
UpdateMode::Enum updateMode;
|
||||||
|
|
||||||
|
bool busy;
|
||||||
|
|
||||||
|
static QtKeyboardMap keyMap;
|
||||||
|
|
||||||
|
Hidden(OSGViewport *self) : QObject(self), self(self), window(NULL), frameTimer(-1),
|
||||||
|
sceneNode(NULL), cameraNode(NULL), manipulator(NULL), updateMode(UpdateMode::OnDemand), busy(false)
|
||||||
{
|
{
|
||||||
OsgEarth::initialize();
|
OsgEarth::initialize();
|
||||||
|
|
||||||
@ -101,7 +143,9 @@ public:
|
|||||||
|
|
||||||
~Hidden()
|
~Hidden()
|
||||||
{
|
{
|
||||||
stop();
|
disconnect(self);
|
||||||
|
|
||||||
|
stopTimer();
|
||||||
|
|
||||||
destroyViewer();
|
destroyViewer();
|
||||||
}
|
}
|
||||||
@ -109,195 +153,140 @@ public:
|
|||||||
public slots:
|
public slots:
|
||||||
void onWindowChanged(QQuickWindow *window)
|
void onWindowChanged(QQuickWindow *window)
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::onWindowChanged" << window;
|
// qDebug() << "OSGViewport::onWindowChanged" << window;
|
||||||
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onWindowChanged");
|
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onWindowChanged");
|
||||||
if (window) {
|
if (window) {
|
||||||
// window->setClearBeforeRendering(false);
|
// window->setClearBeforeRendering(false);
|
||||||
connect(window, &QQuickWindow::sceneGraphInitialized, this, &Hidden::onSceneGraphInitialized, Qt::DirectConnection);
|
// connect(window, &QQuickWindow::sceneGraphInitialized, this, &Hidden::onSceneGraphInitialized, Qt::DirectConnection);
|
||||||
connect(window, &QQuickWindow::sceneGraphAboutToStop, this, &Hidden::onSceneGraphAboutToStop, Qt::DirectConnection);
|
// connect(window, &QQuickWindow::sceneGraphAboutToStop, this, &Hidden::onSceneGraphAboutToStop, Qt::DirectConnection);
|
||||||
connect(window, &QQuickWindow::sceneGraphInvalidated, this, &Hidden::onSceneGraphInvalidated, Qt::DirectConnection);
|
// connect(window, &QQuickWindow::sceneGraphInvalidated, this, &Hidden::onSceneGraphInvalidated, Qt::DirectConnection);
|
||||||
|
// connect(window, &QQuickWindow::visibleChanged, this, &Hidden::visibleChanged, Qt::DirectConnection);
|
||||||
|
// connect(window, &QQuickWindow::widthChanged, this, &Hidden::widthChanged, Qt::DirectConnection);
|
||||||
|
// connect(window, &QQuickWindow::heightChanged, this, &Hidden::heightChanged, Qt::DirectConnection);
|
||||||
} else {
|
} else {
|
||||||
if (this->window) {
|
// if (this->window) {
|
||||||
disconnect(this->window);
|
// disconnect(this->window);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
this->window = window;
|
this->window = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool acceptSceneNode(OSGNode *node)
|
||||||
bool acceptSceneData(OSGNode *node)
|
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::acceptSceneData" << node;
|
qDebug() << "OSGViewport::acceptSceneNode" << node;
|
||||||
if (sceneData == node) {
|
if (sceneNode == node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneData) {
|
if (sceneNode) {
|
||||||
disconnect(sceneData);
|
disconnect(sceneNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
sceneData = node;
|
sceneNode = node;
|
||||||
|
|
||||||
if (sceneData) {
|
if (sceneNode) {
|
||||||
acceptNode(sceneData->node());
|
connect(sceneNode, &OSGNode::nodeChanged, this, &Hidden::onSceneNodeChanged);
|
||||||
connect(sceneData, &OSGNode::nodeChanged, this, &Hidden::onNodeChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acceptNode(osg::Node *node)
|
bool acceptCameraNode(OSGCamera *node)
|
||||||
{
|
{
|
||||||
|
qDebug() << "OSGViewport::acceptCameraNode" << node;
|
||||||
|
if (cameraNode == node) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraNode) {
|
||||||
|
disconnect(cameraNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
cameraNode = node;
|
||||||
|
|
||||||
|
if (cameraNode) {
|
||||||
|
connect(cameraNode, &OSGNode::nodeChanged, this, &Hidden::onCameraNodeChanged);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach(osgViewer::View *view)
|
bool acceptManipulator(OSGCameraManipulator *m)
|
||||||
{
|
{
|
||||||
if (!sceneData) {
|
qDebug() << "OSGViewport::acceptManipulator" << manipulator;
|
||||||
qWarning() << "OSGViewport::attach - invalid scene!";
|
if (manipulator == m) {
|
||||||
return;
|
return true;
|
||||||
}
|
|
||||||
// attach scene
|
|
||||||
attach(view, sceneData->node());
|
|
||||||
// attach camera
|
|
||||||
if (camera) {
|
|
||||||
camera->attach(view);
|
|
||||||
} else {
|
|
||||||
qWarning() << "OSGViewport::attach - no camera!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void attach(osgViewer::View *view, osg::Node *node)
|
|
||||||
{
|
|
||||||
if (!view) {
|
|
||||||
qWarning() << "OSGViewport::attach - view is null";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!node) {
|
|
||||||
qWarning() << "OSGViewport::attach - node is null";
|
|
||||||
view->setSceneData(NULL);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_OSGEARTH
|
manipulator = m;
|
||||||
// TODO map handling should not be done here
|
|
||||||
osgEarth::MapNode *mapNode = osgEarth::MapNode::findMapNode(node);
|
|
||||||
if (mapNode) {
|
|
||||||
qDebug() << "OSGViewport::attach - found map node" << mapNode;
|
|
||||||
|
|
||||||
// remove light to prevent unnecessary state changes in SceneView
|
return true;
|
||||||
// scene will get light from sky (works only with latest > 2.7)
|
|
||||||
// view->setLightingMode(osg::View::NO_LIGHT);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
qDebug() << "OSGViewport::attach - set scene" << node;
|
|
||||||
view->setSceneData(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void detach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
// detach camera
|
|
||||||
if (camera) {
|
|
||||||
camera->detach(view);
|
|
||||||
}
|
|
||||||
// detach scene
|
|
||||||
view->setSceneData(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSceneGraphInitialized()
|
|
||||||
{
|
|
||||||
qDebug() << "OSGViewport::onSceneGraphInitialized";
|
|
||||||
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onSceneGraphInitialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSceneGraphAboutToStop()
|
|
||||||
{
|
|
||||||
qDebug() << "OSGViewport::onSceneGraphAboutToStop";
|
|
||||||
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onSceneGraphAboutToStop");
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSceneGraphInvalidated()
|
|
||||||
{
|
|
||||||
qDebug() << "OSGViewport::onSceneGraphInvalidated";
|
|
||||||
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "onSceneGraphInvalidated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeResources()
|
void initializeResources()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::initializeResources";
|
if (gc.valid()) {
|
||||||
if (view.valid()) {
|
// qWarning() << "OSGViewport::initializeResources - gc already created!";
|
||||||
qWarning() << "OSGViewport::initializeResources - view already created!";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view = createView();
|
// qDebug() << "OSGViewport::initializeResources";
|
||||||
viewer->addView(view);
|
|
||||||
self->attach(view.get());
|
// setup graphics context and camera
|
||||||
start();
|
gc = createGraphicsContext();
|
||||||
|
|
||||||
|
cameraNode->setGraphicsContext(gc);
|
||||||
|
|
||||||
|
// qDebug() << "OSGViewport::initializeResources - camera" << cameraNode->asCamera();
|
||||||
|
view->setCamera(cameraNode->asCamera());
|
||||||
|
|
||||||
|
// qDebug() << "OSGViewport::initializeResources - scene data" << sceneNode->node();
|
||||||
|
view->setSceneData(sceneNode->node());
|
||||||
|
|
||||||
|
if (manipulator) {
|
||||||
|
osgGA::CameraManipulator *m = manipulator->asCameraManipulator();
|
||||||
|
// qDebug() << "OSGViewport::initializeResources - manipulator" << m;
|
||||||
|
|
||||||
|
// Setting the manipulator on the camera will change the manipulator node (used to compute the camera home position)
|
||||||
|
// to the view scene node. So we need to save and restore the manipulator node.
|
||||||
|
osg::Node *node = m->getNode();
|
||||||
|
view->setCameraManipulator(m, false);
|
||||||
|
if (node) {
|
||||||
|
m->setNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
view->home();
|
||||||
|
} else {
|
||||||
|
view->setCameraManipulator(NULL, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
installHanders();
|
||||||
|
|
||||||
|
startTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void releaseResources()
|
void releaseResources()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::releaseResources";
|
// qDebug() << "OSGViewport::releaseResources";
|
||||||
if (!view.valid()) {
|
if (!gc.valid()) {
|
||||||
qWarning() << "OSGViewport::releaseResources - view is not valid!";
|
qWarning() << "OSGViewport::releaseResources - gc is not valid!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
osg::deleteAllGLObjects(view->getCamera()->getGraphicsContext()->getState()->getContextID());
|
osg::deleteAllGLObjects(gc->getState()->getContextID());
|
||||||
// view->getSceneData()->releaseGLObjects(view->getCamera()->getGraphicsContext()->getState());
|
// view->getSceneData()->releaseGLObjects(view->getCamera()->getGraphicsContext()->getState());
|
||||||
// view->getCamera()->releaseGLObjects(view->getCamera()->getGraphicsContext()->getState());
|
// view->getCamera()->releaseGLObjects(view->getCamera()->getGraphicsContext()->getState());
|
||||||
// view->getCamera()->getGraphicsContext()->close();
|
// view->getCamera()->getGraphicsContext()->close();
|
||||||
// view->getCamera()->setGraphicsContext(NULL);
|
// view->getCamera()->setGraphicsContext(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acceptUpdateMode(UpdateMode::Enum mode)
|
private:
|
||||||
{
|
|
||||||
if (updateMode == mode) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateMode = mode;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool acceptCamera(OSGCamera *camera)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGViewport::acceptCamera" << camera;
|
|
||||||
if (this->camera == camera) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->camera = camera;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGViewport *self;
|
|
||||||
|
|
||||||
QQuickWindow *window;
|
|
||||||
|
|
||||||
OSGNode *sceneData;
|
|
||||||
OSGCamera *camera;
|
|
||||||
|
|
||||||
UpdateMode::Enum updateMode;
|
|
||||||
|
|
||||||
int frameTimer;
|
|
||||||
|
|
||||||
osg::ref_ptr<osgViewer::CompositeViewer> viewer;
|
|
||||||
osg::ref_ptr<osgViewer::View> view;
|
|
||||||
|
|
||||||
static QtKeyboardMap keyMap;
|
|
||||||
|
|
||||||
void createViewer()
|
void createViewer()
|
||||||
{
|
{
|
||||||
if (viewer.valid()) {
|
if (viewer.valid()) {
|
||||||
qWarning() << "OSGViewport::createViewer - viewer is valid";
|
qWarning() << "OSGViewport::createViewer - viewer is valid";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// qDebug() << "OSGViewport::createViewer";
|
||||||
qDebug() << "OSGViewport::createViewer";
|
|
||||||
|
|
||||||
viewer = new osgViewer::CompositeViewer();
|
viewer = new osgViewer::CompositeViewer();
|
||||||
viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
|
viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
|
||||||
@ -306,6 +295,9 @@ public:
|
|||||||
// disable the default setting of viewer.done() by pressing Escape.
|
// disable the default setting of viewer.done() by pressing Escape.
|
||||||
viewer->setKeyEventSetsDone(0);
|
viewer->setKeyEventSetsDone(0);
|
||||||
// viewer->setQuitEventSetsDone(false);
|
// viewer->setQuitEventSetsDone(false);
|
||||||
|
|
||||||
|
view = createView();
|
||||||
|
viewer->addView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyViewer()
|
void destroyViewer()
|
||||||
@ -314,17 +306,25 @@ public:
|
|||||||
qWarning() << "OSGViewport::destroyViewer - viewer is not valid";
|
qWarning() << "OSGViewport::destroyViewer - viewer is not valid";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// qDebug() << "OSGViewport::destroyViewer";
|
||||||
qDebug() << "OSGViewport::destroyViewer";
|
|
||||||
|
|
||||||
viewer = NULL;
|
viewer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
osgViewer::View *createView()
|
osgViewer::View *createView()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::createView";
|
// qDebug() << "OSGViewport::createView";
|
||||||
osgViewer::View *view = new osgViewer::View();
|
osgViewer::View *view = new osgViewer::View();
|
||||||
|
|
||||||
|
// TODO expose as Qml properties
|
||||||
|
view->setLightingMode(osgViewer::View::SKY_LIGHT);
|
||||||
|
view->getLight()->setAmbient(osg::Vec4(0.6f, 0.6f, 0.6f, 1.0f));
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void installHanders()
|
||||||
|
{
|
||||||
// TODO will the handlers be destroyed???
|
// TODO will the handlers be destroyed???
|
||||||
// add the state manipulator
|
// add the state manipulator
|
||||||
view->addEventHandler(new osgGA::StateSetManipulator(view->getCamera()->getOrCreateStateSet()));
|
view->addEventHandler(new osgGA::StateSetManipulator(view->getCamera()->getOrCreateStateSet()));
|
||||||
@ -350,26 +350,14 @@ public:
|
|||||||
|
|
||||||
// add the screen capture handler
|
// add the screen capture handler
|
||||||
// view->addEventHandler(new osgViewer::ScreenCaptureHandler);
|
// view->addEventHandler(new osgViewer::ScreenCaptureHandler);
|
||||||
|
|
||||||
// setup graphics context and camera
|
|
||||||
osg::GraphicsContext *gc = createGraphicsContext();
|
|
||||||
|
|
||||||
// TODO expose as Qml properties
|
|
||||||
view->setLightingMode(osgViewer::View::SKY_LIGHT);
|
|
||||||
view->getLight()->setAmbient(osg::Vec4(0.6f, 0.6f, 0.6f, 1.0f));
|
|
||||||
|
|
||||||
osg::Camera *camera = view->getCamera();
|
|
||||||
camera->setGraphicsContext(gc);
|
|
||||||
camera->setViewport(0, 0, gc->getTraits()->width, gc->getTraits()->height);
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::GraphicsContext *createGraphicsContext()
|
osg::GraphicsContext *createGraphicsContext()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::createGraphicsContext";
|
// qDebug() << "OSGViewport::createGraphicsContext";
|
||||||
|
|
||||||
osg::GraphicsContext::Traits *traits = getTraits();
|
osg::GraphicsContext::Traits *traits = getTraits();
|
||||||
|
|
||||||
// traitsInfo(*traits);
|
// traitsInfo(*traits);
|
||||||
|
|
||||||
traits->pbuffer = true;
|
traits->pbuffer = true;
|
||||||
@ -416,19 +404,19 @@ public:
|
|||||||
return traits;
|
return traits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start()
|
void startTimer()
|
||||||
{
|
{
|
||||||
if (updateMode == UpdateMode::Discrete && (frameTimer < 0)) {
|
if ((updateMode != UpdateMode::Continuous) && (frameTimer < 0)) {
|
||||||
qDebug() << "OSGViewport::start - starting timer";
|
// qDebug() << "OSGViewport::startTimer - starting timer";
|
||||||
frameTimer = startTimer(33, Qt::PreciseTimer);
|
frameTimer = QObject::startTimer(33, Qt::PreciseTimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop()
|
void stopTimer()
|
||||||
{
|
{
|
||||||
if (frameTimer >= 0) {
|
if (frameTimer >= 0) {
|
||||||
qDebug() << "OSGViewport::stop - killing timer";
|
// qDebug() << "OSGViewport::stopTimer - killing timer";
|
||||||
killTimer(frameTimer);
|
QObject::killTimer(frameTimer);
|
||||||
frameTimer = -1;
|
frameTimer = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -448,34 +436,38 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void onNodeChanged(osg::Node *node)
|
void onSceneNodeChanged(osg::Node *node)
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::onNodeChanged" << node;
|
qWarning() << "OSGViewport::onSceneNodeChanged - not implemented";
|
||||||
qWarning() << "OSGViewport::onNodeChanged - not implemented";
|
}
|
||||||
// if (view.valid()) {
|
|
||||||
// acceptNode(node);
|
void onCameraNodeChanged(osg::Node *node)
|
||||||
// }
|
{
|
||||||
|
qWarning() << "OSGViewport::onCameraNodeChanged - not implemented";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* class ViewportRenderer */
|
/* class ViewportRenderer */
|
||||||
|
|
||||||
class ViewportRenderer : public QQuickFramebufferObject::Renderer {
|
class ViewportRenderer : public QQuickFramebufferObject::Renderer {
|
||||||
|
private:
|
||||||
|
OSGViewport::Hidden *const h;
|
||||||
|
|
||||||
|
int frameCount;
|
||||||
|
bool needToDoFrame;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ViewportRenderer(OSGViewport::Hidden *h) : h(h)
|
ViewportRenderer(OSGViewport::Hidden *h) : h(h), frameCount(0), needToDoFrame(false)
|
||||||
{
|
{
|
||||||
qDebug() << "ViewportRenderer::ViewportRenderer";
|
// qDebug() << "ViewportRenderer::ViewportRenderer";
|
||||||
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::ViewportRenderer");
|
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::ViewportRenderer");
|
||||||
|
|
||||||
h->initializeResources();
|
h->initializeResources();
|
||||||
|
|
||||||
firstFrame = true;
|
|
||||||
needToDoFrame = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~ViewportRenderer()
|
~ViewportRenderer()
|
||||||
{
|
{
|
||||||
qDebug() << "ViewportRenderer::~ViewportRenderer";
|
// qDebug() << "ViewportRenderer::~ViewportRenderer";
|
||||||
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::~ViewportRenderer");
|
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "ViewportRenderer::~ViewportRenderer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,29 +487,71 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstFrame) {
|
// TODO this is not correct : switching workspaces in GCS will destroy and recreate the renderer (and frameCount is thus reset to 0).
|
||||||
|
if (frameCount == 0) {
|
||||||
h->view->init();
|
h->view->init();
|
||||||
if (!h->viewer->isRealized()) {
|
if (!h->viewer->isRealized()) {
|
||||||
h->viewer->realize();
|
h->viewer->realize();
|
||||||
}
|
}
|
||||||
firstFrame = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
needToDoFrame = false;
|
// we always want to draw the first frame
|
||||||
osg::Viewport *viewport = h->view->getCamera()->getViewport();
|
needToDoFrame = (frameCount == 0);
|
||||||
if ((viewport->width() != item->width()) || (viewport->height() != item->height())) {
|
|
||||||
|
// if not on-demand then do frame
|
||||||
|
if (h->updateMode != UpdateMode::OnDemand) {
|
||||||
needToDoFrame = true;
|
needToDoFrame = true;
|
||||||
int dpr = h->self->window()->devicePixelRatio();
|
}
|
||||||
h->view->getCamera()->getGraphicsContext()->resized(0, 0, item->width() * dpr, item->height() * dpr);
|
|
||||||
|
// check if viewport needs to be resized
|
||||||
|
// a redraw will be requested if necessary
|
||||||
|
osg::Viewport *viewport = h->view->getCamera()->getViewport();
|
||||||
|
int dpr = h->self->window()->devicePixelRatio();
|
||||||
|
int width = item->width() * dpr;
|
||||||
|
int height = item->height() * dpr;
|
||||||
|
if ((viewport->width() != width) || (viewport->height() != height)) {
|
||||||
|
// qDebug() << "*** RESIZE" << frameCount << viewport->width() << "x" << viewport->height() << "->" << width << "x" << height;
|
||||||
|
needToDoFrame = true;
|
||||||
|
|
||||||
|
// h->view->getCamera()->resize(width, height);
|
||||||
|
h->view->getCamera()->getGraphicsContext()->resized(0, 0, width, height);
|
||||||
|
|
||||||
|
// trick to force a "home" on first few frames to absorb initial spurious resizes
|
||||||
|
if (frameCount <= 2) {
|
||||||
|
h->view->home();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh busy state
|
||||||
|
// TODO state becomes busy when scene is loading or downloading tiles (should do it only for download)
|
||||||
|
h->self->setBusy(h->view->getDatabasePager()->getRequestsInProgress());
|
||||||
|
// TODO also expose request list size to Qml
|
||||||
|
if (h->view->getDatabasePager()->getFileRequestListSize() > 0) {
|
||||||
|
// qDebug() << h->view->getDatabasePager()->getFileRequestListSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needToDoFrame) {
|
if (!needToDoFrame) {
|
||||||
needToDoFrame = h->viewer->checkNeedToDoFrame();
|
needToDoFrame = h->viewer->checkNeedToDoFrame();
|
||||||
}
|
}
|
||||||
|
// workarounds to osg issues
|
||||||
if (!needToDoFrame) {
|
if (!needToDoFrame) {
|
||||||
|
// issue 1 : if only root node has an update callback checkNeedToDoFrame should return true but does not
|
||||||
|
// a fix will be submitted to osg (current version is 3.5.1)
|
||||||
|
if (h->view->getSceneData()) {
|
||||||
|
needToDoFrame |= !(h->view->getSceneData()->getUpdateCallback() == NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!needToDoFrame) {
|
||||||
|
// issue 2 : UI events don't trigger a redraw
|
||||||
|
// this issue should be fixed here...
|
||||||
|
// event handling needs a lot of attention :
|
||||||
|
// - sometimes the scene is redrawing continuously (after a drag for example, and single click will stop continuous redraw)
|
||||||
|
// - some events (simple click for instance) trigger a redraw when not needed
|
||||||
|
// - in Earth View : continuous zoom (triggered by holding right button and moving mouse up/down) sometimes stops working when holding mouse still after initiating
|
||||||
needToDoFrame = !h->view->getEventQueue()->empty();
|
needToDoFrame = !h->view->getEventQueue()->empty();
|
||||||
}
|
}
|
||||||
if (needToDoFrame) {
|
if (needToDoFrame) {
|
||||||
|
// qDebug() << "ViewportRenderer::synchronize - update scene" << frameCount;
|
||||||
h->viewer->advance();
|
h->viewer->advance();
|
||||||
h->viewer->eventTraversal();
|
h->viewer->eventTraversal();
|
||||||
h->viewer->updateTraversal();
|
h->viewer->updateTraversal();
|
||||||
@ -537,6 +571,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needToDoFrame) {
|
if (needToDoFrame) {
|
||||||
|
// qDebug() << "ViewportRenderer::render - render scene" << frameCount;
|
||||||
|
|
||||||
// needed to properly render models without terrain (Qt bug?)
|
// needed to properly render models without terrain (Qt bug?)
|
||||||
QOpenGLContext::currentContext()->functions()->glUseProgram(0);
|
QOpenGLContext::currentContext()->functions()->glUseProgram(0);
|
||||||
h->viewer->renderingTraversals();
|
h->viewer->renderingTraversals();
|
||||||
@ -547,6 +583,8 @@ public:
|
|||||||
// trigger next update
|
// trigger next update
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++frameCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size)
|
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size)
|
||||||
@ -556,30 +594,18 @@ public:
|
|||||||
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
|
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
|
||||||
// format.setSamples(4);
|
// format.setSamples(4);
|
||||||
|
|
||||||
// Keeping this for reference :
|
QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(size.width(), size.height(), format);
|
||||||
// Mac need(ed) to have devicePixelRatio (dpr) taken into account (i.e. dpr = 2).
|
|
||||||
// Further tests on Mac have shown that although dpr is still 2 it should not be used to scale the fbo.
|
|
||||||
// Note that getting the window to get the devicePixelRatio is not great (messing with windows is often a bad idea...)
|
|
||||||
int dpr = 1; // h->self->window()->devicePixelRatio();
|
|
||||||
QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(size.width() / dpr, size.height() / dpr, format);
|
|
||||||
|
|
||||||
return fbo;
|
return fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
OSGViewport::Hidden *h;
|
|
||||||
|
|
||||||
bool firstFrame;
|
|
||||||
bool needToDoFrame;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QtKeyboardMap OSGViewport::Hidden::keyMap = QtKeyboardMap();
|
QtKeyboardMap OSGViewport::Hidden::keyMap = QtKeyboardMap();
|
||||||
|
|
||||||
/* class OSGViewport */
|
/* class OSGViewport */
|
||||||
|
|
||||||
OSGViewport::OSGViewport(QQuickItem *parent) : QQuickFramebufferObject(parent), h(new Hidden(this))
|
OSGViewport::OSGViewport(QQuickItem *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::OSGViewport";
|
|
||||||
// setClearBeforeRendering(false);
|
// setClearBeforeRendering(false);
|
||||||
setMirrorVertically(true);
|
setMirrorVertically(true);
|
||||||
setAcceptHoverEvents(true);
|
setAcceptHoverEvents(true);
|
||||||
@ -588,10 +614,48 @@ OSGViewport::OSGViewport(QQuickItem *parent) : QQuickFramebufferObject(parent),
|
|||||||
|
|
||||||
OSGViewport::~OSGViewport()
|
OSGViewport::~OSGViewport()
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::~OSGViewport";
|
|
||||||
delete h;
|
delete h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OSGNode *OSGViewport::sceneNode() const
|
||||||
|
{
|
||||||
|
return h->sceneNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGViewport::setSceneNode(OSGNode *node)
|
||||||
|
{
|
||||||
|
if (h->acceptSceneNode(node)) {
|
||||||
|
// setDirty(Scene);
|
||||||
|
emit sceneNodeChanged(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGCamera *OSGViewport::cameraNode() const
|
||||||
|
{
|
||||||
|
return h->cameraNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGViewport::setCameraNode(OSGCamera *node)
|
||||||
|
{
|
||||||
|
if (h->acceptCameraNode(node)) {
|
||||||
|
// setDirty(Camera);
|
||||||
|
emit cameraNodeChanged(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGCameraManipulator *OSGViewport::manipulator() const
|
||||||
|
{
|
||||||
|
return h->manipulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGViewport::setManipulator(OSGCameraManipulator *manipulator)
|
||||||
|
{
|
||||||
|
if (h->acceptManipulator(manipulator)) {
|
||||||
|
// setDirty(Manipulator);
|
||||||
|
emit manipulatorChanged(manipulator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UpdateMode::Enum OSGViewport::updateMode() const
|
UpdateMode::Enum OSGViewport::updateMode() const
|
||||||
{
|
{
|
||||||
return h->updateMode;
|
return h->updateMode;
|
||||||
@ -599,95 +663,54 @@ UpdateMode::Enum OSGViewport::updateMode() const
|
|||||||
|
|
||||||
void OSGViewport::setUpdateMode(UpdateMode::Enum mode)
|
void OSGViewport::setUpdateMode(UpdateMode::Enum mode)
|
||||||
{
|
{
|
||||||
if (h->acceptUpdateMode(mode)) {
|
if (h->updateMode != mode) {
|
||||||
emit updateModeChanged(updateMode());
|
h->updateMode = mode;
|
||||||
|
emit updateModeChanged(mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor OSGViewport::color() const
|
bool OSGViewport::busy() const
|
||||||
{
|
{
|
||||||
const osg::Vec4 osgColor = h->view->getCamera()->getClearColor();
|
return h->busy;
|
||||||
|
|
||||||
return QColor::fromRgbF(osgColor.r(), osgColor.g(), osgColor.b(), osgColor.a());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGViewport::setColor(const QColor &color)
|
void OSGViewport::setBusy(const bool busy)
|
||||||
{
|
{
|
||||||
osg::Vec4 osgColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
if (h->busy != busy) {
|
||||||
|
h->busy = busy;
|
||||||
if (h->view->getCamera()->getClearColor() != osgColor) {
|
emit busyChanged(busy);
|
||||||
h->view->getCamera()->setClearColor(osgColor);
|
|
||||||
emit colorChanged(color);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGNode *OSGViewport::sceneData()
|
osgViewer::View *OSGViewport::asView() const
|
||||||
{
|
{
|
||||||
return h->sceneData;
|
return h->view;
|
||||||
}
|
|
||||||
|
|
||||||
void OSGViewport::setSceneData(OSGNode *node)
|
|
||||||
{
|
|
||||||
if (h->acceptSceneData(node)) {
|
|
||||||
emit sceneDataChanged(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGCamera *OSGViewport::camera()
|
|
||||||
{
|
|
||||||
return h->camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGViewport::setCamera(OSGCamera *camera)
|
|
||||||
{
|
|
||||||
if (h->acceptCamera(camera)) {
|
|
||||||
emit cameraChanged(camera);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickFramebufferObject::Renderer *OSGViewport::createRenderer() const
|
QQuickFramebufferObject::Renderer *OSGViewport::createRenderer() const
|
||||||
{
|
{
|
||||||
qDebug() << "OSGViewport::createRenderer";
|
// qDebug() << "OSGViewport::createRenderer";
|
||||||
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "createRenderer");
|
// osgQtQuick::openGLContextInfo(QOpenGLContext::currentContext(), "createRenderer");
|
||||||
return new ViewportRenderer(h);
|
return new ViewportRenderer(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGViewport::attach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
// qDebug() << "OSGViewport::attach" << view;
|
|
||||||
if (h->sceneData) {
|
|
||||||
h->sceneData->attach(view);
|
|
||||||
}
|
|
||||||
h->attach(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGViewport::detach(osgViewer::View *view)
|
|
||||||
{
|
|
||||||
qDebug() << "OSGViewport::detach" << view;
|
|
||||||
h->detach(view);
|
|
||||||
if (h->sceneData) {
|
|
||||||
h->sceneData->detach(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSGViewport::releaseResources()
|
void OSGViewport::releaseResources()
|
||||||
{
|
{
|
||||||
QQuickFramebufferObject::releaseResources();
|
// qDebug() << "OSGViewport::releaseResources" << this;
|
||||||
|
Inherited::releaseResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
// see https://bugreports.qt-project.org/browse/QTBUG-41073
|
void OSGViewport::classBegin()
|
||||||
QSGNode *OSGViewport::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData)
|
|
||||||
{
|
{
|
||||||
// qDebug() << "OSGViewport::updatePaintNode";
|
// qDebug() << "OSGViewport::classBegin" << this;
|
||||||
if (!node) {
|
Inherited::classBegin();
|
||||||
qDebug() << "OSGViewport::updatePaintNode - set transform";
|
|
||||||
node = QQuickFramebufferObject::updatePaintNode(node, nodeData);
|
|
||||||
QSGSimpleTextureNode *n = static_cast<QSGSimpleTextureNode *>(node);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
return QQuickFramebufferObject::updatePaintNode(node, nodeData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OSGViewport::componentComplete()
|
||||||
|
{
|
||||||
|
// qDebug() << "OSGViewport::componentComplete" << this;
|
||||||
|
Inherited::componentComplete();
|
||||||
|
}
|
||||||
|
|
||||||
QPointF OSGViewport::mousePoint(QMouseEvent *event)
|
QPointF OSGViewport::mousePoint(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
@ -785,7 +808,7 @@ void OSGViewport::keyPressEvent(QKeyEvent *event)
|
|||||||
// among others, it closes popup windows on ESC and forwards the event to the parent widgets
|
// among others, it closes popup windows on ESC and forwards the event to the parent widgets
|
||||||
// TODO implement
|
// TODO implement
|
||||||
// if( _forwardKeyEvents )
|
// if( _forwardKeyEvents )
|
||||||
// inherited::keyPressEvent( event );
|
// Inherited::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSGViewport::keyReleaseEvent(QKeyEvent *event)
|
void OSGViewport::keyReleaseEvent(QKeyEvent *event)
|
||||||
@ -804,7 +827,7 @@ void OSGViewport::keyReleaseEvent(QKeyEvent *event)
|
|||||||
// among others, it closes popup windows on ESC and forwards the event to the parent widgets
|
// among others, it closes popup windows on ESC and forwards the event to the parent widgets
|
||||||
// TODO implement
|
// TODO implement
|
||||||
// if( _forwardKeyEvents )
|
// if( _forwardKeyEvents )
|
||||||
// inherited::keyReleaseEvent( event );
|
// Inherited::keyReleaseEvent(event);
|
||||||
}
|
}
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file OSGViewport.hpp
|
* @file OSGViewport.hpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "Export.hpp"
|
#include "Export.hpp"
|
||||||
|
|
||||||
|
#include "ga/OSGCameraManipulator.hpp"
|
||||||
|
|
||||||
#include <QQuickFramebufferObject>
|
#include <QQuickFramebufferObject>
|
||||||
|
|
||||||
namespace osgViewer {
|
namespace osgViewer {
|
||||||
@ -49,39 +51,49 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class OSGQTQUICK_EXPORT OSGViewport : public QQuickFramebufferObject {
|
class OSGQTQUICK_EXPORT OSGViewport : public QQuickFramebufferObject {
|
||||||
Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
||||||
|
Q_PROPERTY(osgQtQuick::OSGCamera * camera READ cameraNode WRITE setCameraNode NOTIFY cameraNodeChanged)
|
||||||
|
Q_PROPERTY(osgQtQuick::OSGCameraManipulator * manipulator READ manipulator WRITE setManipulator NOTIFY manipulatorChanged)
|
||||||
Q_PROPERTY(osgQtQuick::UpdateMode::Enum updateMode READ updateMode WRITE setUpdateMode NOTIFY updateModeChanged)
|
Q_PROPERTY(osgQtQuick::UpdateMode::Enum updateMode READ updateMode WRITE setUpdateMode NOTIFY updateModeChanged)
|
||||||
Q_PROPERTY(osgQtQuick::OSGNode * sceneData READ sceneData WRITE setSceneData NOTIFY sceneDataChanged)
|
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
|
||||||
Q_PROPERTY(osgQtQuick::OSGCamera * camera READ camera WRITE setCamera NOTIFY cameraChanged)
|
|
||||||
|
typedef QQuickFramebufferObject Inherited;
|
||||||
|
|
||||||
public:
|
|
||||||
friend class ViewportRenderer;
|
friend class ViewportRenderer;
|
||||||
|
|
||||||
|
public:
|
||||||
explicit OSGViewport(QQuickItem *parent = 0);
|
explicit OSGViewport(QQuickItem *parent = 0);
|
||||||
virtual ~OSGViewport();
|
virtual ~OSGViewport();
|
||||||
|
|
||||||
|
OSGNode *sceneNode() const;
|
||||||
|
void setSceneNode(OSGNode *node);
|
||||||
|
|
||||||
|
OSGCamera *cameraNode() const;
|
||||||
|
void setCameraNode(OSGCamera *node);
|
||||||
|
|
||||||
|
OSGCameraManipulator *manipulator() const;
|
||||||
|
void setManipulator(OSGCameraManipulator *manipulator);
|
||||||
|
|
||||||
UpdateMode::Enum updateMode() const;
|
UpdateMode::Enum updateMode() const;
|
||||||
void setUpdateMode(UpdateMode::Enum mode);
|
void setUpdateMode(UpdateMode::Enum mode);
|
||||||
|
|
||||||
QColor color() const;
|
bool busy() const;
|
||||||
void setColor(const QColor &color);
|
void setBusy(const bool busy);
|
||||||
|
|
||||||
OSGNode *sceneData();
|
|
||||||
void setSceneData(OSGNode *node);
|
|
||||||
|
|
||||||
OSGCamera *camera();
|
|
||||||
void setCamera(OSGCamera *camera);
|
|
||||||
|
|
||||||
Renderer *createRenderer() const;
|
Renderer *createRenderer() const;
|
||||||
void releaseResources();
|
void releaseResources();
|
||||||
|
|
||||||
|
osgViewer::View *asView() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void sceneNodeChanged(OSGNode *node);
|
||||||
|
void cameraNodeChanged(OSGCamera *node);
|
||||||
|
void manipulatorChanged(OSGCameraManipulator *manipulator);
|
||||||
void updateModeChanged(UpdateMode::Enum mode);
|
void updateModeChanged(UpdateMode::Enum mode);
|
||||||
void colorChanged(const QColor &color);
|
void busyChanged(bool busy);
|
||||||
void sceneDataChanged(OSGNode *node);
|
|
||||||
void cameraChanged(OSGCamera *camera);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// QQuickItem
|
||||||
void mousePressEvent(QMouseEvent *event);
|
void mousePressEvent(QMouseEvent *event);
|
||||||
void mouseMoveEvent(QMouseEvent *event);
|
void mouseMoveEvent(QMouseEvent *event);
|
||||||
void mouseReleaseEvent(QMouseEvent *event);
|
void mouseReleaseEvent(QMouseEvent *event);
|
||||||
@ -92,14 +104,13 @@ protected:
|
|||||||
void setKeyboardModifiers(QInputEvent *event);
|
void setKeyboardModifiers(QInputEvent *event);
|
||||||
QPointF mousePoint(QMouseEvent *event);
|
QPointF mousePoint(QMouseEvent *event);
|
||||||
|
|
||||||
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
|
// QQmlParserStatus
|
||||||
|
void classBegin();
|
||||||
void attach(osgViewer::View *view);
|
void componentComplete();
|
||||||
void detach(osgViewer::View *view);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hidden;
|
struct Hidden;
|
||||||
Hidden *h;
|
Hidden *const h;
|
||||||
};
|
};
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
@ -0,0 +1,181 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGCameraManipulator.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "OSGCameraManipulator.hpp"
|
||||||
|
|
||||||
|
#include "../DirtySupport.hpp"
|
||||||
|
#include "../OSGNode.hpp"
|
||||||
|
|
||||||
|
#include <osgGA/CameraManipulator>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { Scene = 1 << 0 };
|
||||||
|
|
||||||
|
struct OSGCameraManipulator::Hidden : public QObject, public DirtySupport {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
friend class OSGCameraManipulator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGCameraManipulator *const self;
|
||||||
|
|
||||||
|
public:
|
||||||
|
osg::ref_ptr<osgGA::CameraManipulator> manipulator;
|
||||||
|
|
||||||
|
OSGNode *sceneNode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Hidden(OSGCameraManipulator *self) : QObject(self), self(self), sceneNode(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~Hidden()
|
||||||
|
{}
|
||||||
|
|
||||||
|
osg::Node *nodeToUpdate() const
|
||||||
|
{
|
||||||
|
return manipulator->getNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
return self->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool acceptSceneNode(OSGNode *node)
|
||||||
|
{
|
||||||
|
qDebug() << "OSGCameraManipulator::acceptSceneNode" << node;
|
||||||
|
if (sceneNode == node) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sceneNode) {
|
||||||
|
disconnect(sceneNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
sceneNode = node;
|
||||||
|
|
||||||
|
if (sceneNode) {
|
||||||
|
connect(sceneNode, &OSGNode::nodeChanged, this, &OSGCameraManipulator::Hidden::onSceneNodeChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSceneNode()
|
||||||
|
{
|
||||||
|
if (!sceneNode) {
|
||||||
|
qWarning() << "OSGCameraManipulator::updateSceneNode - no scene node";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "OSGCameraManipulator::updateSceneNode" << sceneNode;
|
||||||
|
manipulator->setNode(sceneNode->node());
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onSceneNodeChanged(osg::Node *node)
|
||||||
|
{
|
||||||
|
qDebug() << "OSGCameraManipulator::onSceneNodeChanged" << node;
|
||||||
|
updateSceneNode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class OSGCameraManipulator */
|
||||||
|
|
||||||
|
OSGCameraManipulator::OSGCameraManipulator(QObject *parent) : QObject(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
OSGCameraManipulator::~OSGCameraManipulator()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGNode *OSGCameraManipulator::sceneNode() const
|
||||||
|
{
|
||||||
|
return h->sceneNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCameraManipulator::setSceneNode(OSGNode *node)
|
||||||
|
{
|
||||||
|
if (h->acceptSceneNode(node)) {
|
||||||
|
setDirty(Scene);
|
||||||
|
emit sceneNodeChanged(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSGCameraManipulator::isDirty(int mask) const
|
||||||
|
{
|
||||||
|
return h->isDirty(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCameraManipulator::setDirty(int mask)
|
||||||
|
{
|
||||||
|
h->setDirty(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCameraManipulator::clearDirty()
|
||||||
|
{
|
||||||
|
h->clearDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCameraManipulator::classBegin()
|
||||||
|
{
|
||||||
|
// qDebug() << "OSGCameraManipulator::classBegin" << this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCameraManipulator::componentComplete()
|
||||||
|
{
|
||||||
|
qDebug() << "OSGCameraManipulator::componentComplete" << this;
|
||||||
|
update();
|
||||||
|
clearDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
osgGA::CameraManipulator *OSGCameraManipulator::manipulator() const
|
||||||
|
{
|
||||||
|
return h->manipulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCameraManipulator::setManipulator(osgGA::CameraManipulator *manipulator)
|
||||||
|
{
|
||||||
|
h->manipulator = manipulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
osgGA::CameraManipulator *OSGCameraManipulator::asCameraManipulator() const
|
||||||
|
{
|
||||||
|
return h->manipulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGCameraManipulator::update()
|
||||||
|
{
|
||||||
|
if (isDirty(Scene)) {
|
||||||
|
h->updateSceneNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#include "OSGCameraManipulator.moc"
|
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGCameraManipulator.hpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_OSGQTQUICK_OSGCAMERAMANIPULATOR_H_
|
||||||
|
#define _H_OSGQTQUICK_OSGCAMERAMANIPULATOR_H_
|
||||||
|
|
||||||
|
#include "../Export.hpp"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQmlParserStatus>
|
||||||
|
|
||||||
|
namespace osgGA {
|
||||||
|
class CameraManipulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
class OSGNode;
|
||||||
|
|
||||||
|
class OSGQTQUICK_EXPORT OSGCameraManipulator : public QObject, public QQmlParserStatus {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QQmlParserStatus)
|
||||||
|
|
||||||
|
Q_PROPERTY(osgQtQuick::OSGNode * sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OSGCameraManipulator(QObject *parent = 0);
|
||||||
|
virtual ~OSGCameraManipulator();
|
||||||
|
|
||||||
|
osgGA::CameraManipulator *asCameraManipulator() const;
|
||||||
|
|
||||||
|
OSGNode *sceneNode() const;
|
||||||
|
void setSceneNode(OSGNode *node);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sceneNodeChanged(OSGNode *node);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isDirty(int mask = 0xFFFF) const;
|
||||||
|
void setDirty(int mask = 0xFFFF);
|
||||||
|
void clearDirty();
|
||||||
|
|
||||||
|
void classBegin();
|
||||||
|
void componentComplete();
|
||||||
|
|
||||||
|
osgGA::CameraManipulator *manipulator() const;
|
||||||
|
void setManipulator(osgGA::CameraManipulator *manipulator);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Hidden;
|
||||||
|
Hidden *const h;
|
||||||
|
};
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#endif // _H_OSGQTQUICK_OSGCAMERAMANIPULATOR_H_
|
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGEarthManipulator.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "OSGEarthManipulator.hpp"
|
||||||
|
|
||||||
|
#include "../OSGNode.hpp"
|
||||||
|
|
||||||
|
#include <osgEarthUtil/EarthManipulator>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
struct OSGEarthManipulator::Hidden : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGEarthManipulator * const self;
|
||||||
|
|
||||||
|
public:
|
||||||
|
osg::ref_ptr<osgEarth::Util::EarthManipulator> manipulator;
|
||||||
|
|
||||||
|
Hidden(OSGEarthManipulator *self) : QObject(self), self(self)
|
||||||
|
{
|
||||||
|
manipulator = new osgEarth::Util::EarthManipulator(
|
||||||
|
/*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/);
|
||||||
|
manipulator->getSettings()->setThrowingEnabled(true);
|
||||||
|
self->setManipulator(manipulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Hidden()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class OSGEarthManipulator */
|
||||||
|
|
||||||
|
OSGEarthManipulator::OSGEarthManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
OSGEarthManipulator::~OSGEarthManipulator()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#include "OSGEarthManipulator.moc"
|
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGEarthManipulator.hpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_OSGQTQUICK_OSGEARTHMANIPULATOR_H_
|
||||||
|
#define _H_OSGQTQUICK_OSGEARTHMANIPULATOR_H_
|
||||||
|
|
||||||
|
#include "../Export.hpp"
|
||||||
|
#include "OSGCameraManipulator.hpp"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
class OSGQTQUICK_EXPORT OSGEarthManipulator : public OSGCameraManipulator {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
typedef OSGCameraManipulator Inherited;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OSGEarthManipulator(QObject *parent = 0);
|
||||||
|
virtual ~OSGEarthManipulator();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Hidden;
|
||||||
|
Hidden *const h;
|
||||||
|
};
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#endif // _H_OSGQTQUICK_OSGEARTHMANIPULATOR_H_
|
@ -0,0 +1,285 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGGeoTransformManipulator.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "OSGGeoTransformManipulator.hpp"
|
||||||
|
|
||||||
|
#include "../OSGNode.hpp"
|
||||||
|
#include "utils/utility.h"
|
||||||
|
|
||||||
|
#include <osg/Matrix>
|
||||||
|
#include <osg/Node>
|
||||||
|
#include <osg/Vec3d>
|
||||||
|
|
||||||
|
#include <osgGA/CameraManipulator>
|
||||||
|
|
||||||
|
#include <osgEarth/GeoData>
|
||||||
|
#include <osgEarth/MapNode>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { Position = 1 << 10, Attitude = 1 << 11, Clamp = 1 << 12 };
|
||||||
|
|
||||||
|
class MyManipulator : public osgGA::CameraManipulator {
|
||||||
|
public:
|
||||||
|
MyManipulator()
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void updateCamera(osg::Camera &camera);
|
||||||
|
|
||||||
|
virtual const char *className() const
|
||||||
|
{
|
||||||
|
return "MyManipulator";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setByMatrix(const osg::Matrixd &matrix)
|
||||||
|
{
|
||||||
|
this->matrix = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setByInverseMatrix(const osg::Matrixd &matrix)
|
||||||
|
{
|
||||||
|
this->invMatrix = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual osg::Matrixd getMatrix() const
|
||||||
|
{
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual osg::Matrixd getInverseMatrix() const
|
||||||
|
{
|
||||||
|
return invMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setNode(osg::Node *node)
|
||||||
|
{
|
||||||
|
this->node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const osg::Node *getNode() const
|
||||||
|
{
|
||||||
|
return node.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual osg::Node *getNode()
|
||||||
|
{
|
||||||
|
return node.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
osg::Matrixd matrix;
|
||||||
|
osg::Matrixd invMatrix;
|
||||||
|
osg::ref_ptr<osg::Node> node;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OSGGeoTransformManipulator::Hidden : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGGeoTransformManipulator * const self;
|
||||||
|
|
||||||
|
osg::Matrix cameraPosition;
|
||||||
|
osg::Matrix cameraRotation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
osg::ref_ptr<MyManipulator> manipulator;
|
||||||
|
|
||||||
|
QVector3D attitude;
|
||||||
|
QVector3D position;
|
||||||
|
|
||||||
|
bool clampToTerrain;
|
||||||
|
bool intoTerrain;
|
||||||
|
|
||||||
|
Hidden(OSGGeoTransformManipulator *self) : QObject(self), self(self), clampToTerrain(false), intoTerrain(false)
|
||||||
|
{
|
||||||
|
manipulator = new MyManipulator();
|
||||||
|
self->setManipulator(manipulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Hidden()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void updateManipulator()
|
||||||
|
{
|
||||||
|
// qDebug() << "OSGGeoTransformManipulator::updateManipulator";
|
||||||
|
|
||||||
|
osg::Matrix cameraMatrix = cameraRotation * cameraPosition;
|
||||||
|
|
||||||
|
manipulator->setByMatrix(cameraMatrix);
|
||||||
|
|
||||||
|
// Inverse the camera's position and orientation matrix to obtain the view matrix
|
||||||
|
cameraMatrix = osg::Matrix::inverse(cameraMatrix);
|
||||||
|
manipulator->setByInverseMatrix(cameraMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePosition()
|
||||||
|
{
|
||||||
|
// qDebug() << "OSGGeoTransformManipulator::updatePosition" << position;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// TODO handle the case where the terrain SRS is not "wgs84"
|
||||||
|
// TODO check if position is not below terrain?
|
||||||
|
// TODO compensate antenna height when source of position is GPS (i.e. subtract antenna height from altitude) ;)
|
||||||
|
|
||||||
|
osgEarth::MapNode *mapNode = NULL;
|
||||||
|
|
||||||
|
OSGNode *sceneNode = self->sceneNode();
|
||||||
|
|
||||||
|
if (sceneNode && sceneNode->node()) {
|
||||||
|
mapNode = osgEarth::MapNode::findMapNode(sceneNode->node());
|
||||||
|
if (!mapNode) {
|
||||||
|
qWarning() << "OSGGeoTransformManipulator::updatePosition - manipulator node does not contain a map node";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "OSGGeoTransformManipulator::updatePosition - scene node is null";
|
||||||
|
}
|
||||||
|
|
||||||
|
osgEarth::GeoPoint geoPoint;
|
||||||
|
if (mapNode) {
|
||||||
|
geoPoint = osgQtQuick::toGeoPoint(mapNode->getTerrain()->getSRS(), position);
|
||||||
|
} else {
|
||||||
|
geoPoint = osgQtQuick::toGeoPoint(position);
|
||||||
|
}
|
||||||
|
if (clampToTerrain && mapNode) {
|
||||||
|
// clamp model to terrain if needed
|
||||||
|
intoTerrain = osgQtQuick::clampGeoPoint(geoPoint, 0, mapNode);
|
||||||
|
} else if (clampToTerrain) {
|
||||||
|
qWarning() << "OSGGeoTransformManipulator::updatePosition - cannot clamp without map node";
|
||||||
|
}
|
||||||
|
|
||||||
|
geoPoint.createLocalToWorld(cameraPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateAttitude()
|
||||||
|
{
|
||||||
|
// qDebug() << "OSGGeoTransformManipulator::updateAttitude" << attitude;
|
||||||
|
|
||||||
|
// By default the camera looks toward -Z, we must rotate it so it looks toward Y
|
||||||
|
cameraRotation.makeRotate(osg::DegreesToRadians(90.0), osg::Vec3(1.0, 0.0, 0.0),
|
||||||
|
osg::DegreesToRadians(0.0), osg::Vec3(0.0, 1.0, 0.0),
|
||||||
|
osg::DegreesToRadians(0.0), osg::Vec3(0.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
// Final camera matrix
|
||||||
|
double roll = osg::DegreesToRadians(attitude.x());
|
||||||
|
double pitch = osg::DegreesToRadians(attitude.y());
|
||||||
|
double yaw = osg::DegreesToRadians(attitude.z());
|
||||||
|
cameraRotation = cameraRotation
|
||||||
|
* osg::Matrix::rotate(roll, osg::Vec3(0, 1, 0))
|
||||||
|
* osg::Matrix::rotate(pitch, osg::Vec3(1, 0, 0))
|
||||||
|
* osg::Matrix::rotate(yaw, osg::Vec3(0, 0, -1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class OSGGeoTransformManipulator::MyManipulator */
|
||||||
|
|
||||||
|
void MyManipulator::updateCamera(osg::Camera & camera)
|
||||||
|
{
|
||||||
|
// qDebug() << "MyManipulator::updateCamera";
|
||||||
|
CameraManipulator::updateCamera(camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* class OSGGeoTransformManipulator */
|
||||||
|
|
||||||
|
OSGGeoTransformManipulator::OSGGeoTransformManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
OSGGeoTransformManipulator::~OSGGeoTransformManipulator()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSGGeoTransformManipulator::clampToTerrain() const
|
||||||
|
{
|
||||||
|
return h->clampToTerrain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGGeoTransformManipulator::setClampToTerrain(bool arg)
|
||||||
|
{
|
||||||
|
if (h->clampToTerrain != arg) {
|
||||||
|
h->clampToTerrain = arg;
|
||||||
|
setDirty(Clamp);
|
||||||
|
emit clampToTerrainChanged(clampToTerrain());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSGGeoTransformManipulator::intoTerrain() const
|
||||||
|
{
|
||||||
|
return h->intoTerrain;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D OSGGeoTransformManipulator::attitude() const
|
||||||
|
{
|
||||||
|
return h->attitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGGeoTransformManipulator::setAttitude(QVector3D arg)
|
||||||
|
{
|
||||||
|
if (h->attitude != arg) {
|
||||||
|
h->attitude = arg;
|
||||||
|
setDirty(Attitude);
|
||||||
|
emit attitudeChanged(attitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D OSGGeoTransformManipulator::position() const
|
||||||
|
{
|
||||||
|
return h->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGGeoTransformManipulator::setPosition(QVector3D arg)
|
||||||
|
{
|
||||||
|
if (h->position != arg) {
|
||||||
|
h->position = arg;
|
||||||
|
setDirty(Position);
|
||||||
|
emit positionChanged(position());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGGeoTransformManipulator::update()
|
||||||
|
{
|
||||||
|
Inherited::update();
|
||||||
|
|
||||||
|
bool b = false;
|
||||||
|
|
||||||
|
if (isDirty(Clamp | Position)) {
|
||||||
|
h->updatePosition();
|
||||||
|
b = true;
|
||||||
|
}
|
||||||
|
if (isDirty(Attitude)) {
|
||||||
|
h->updateAttitude();
|
||||||
|
b = true;
|
||||||
|
}
|
||||||
|
if (b) {
|
||||||
|
h->updateManipulator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#include "OSGGeoTransformManipulator.moc"
|
@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGGeoTransformManipulator.hpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_OSGQTQUICK_OSGGEOTRANSFORMMANIPULATOR_H_
|
||||||
|
#define _H_OSGQTQUICK_OSGGEOTRANSFORMMANIPULATOR_H_
|
||||||
|
|
||||||
|
#include "../Export.hpp"
|
||||||
|
#include "OSGCameraManipulator.hpp"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVector3D>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
class OSGQTQUICK_EXPORT OSGGeoTransformManipulator : public OSGCameraManipulator {
|
||||||
|
Q_OBJECT Q_PROPERTY(QVector3D attitude READ attitude WRITE setAttitude NOTIFY attitudeChanged)
|
||||||
|
Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
|
||||||
|
Q_PROPERTY(bool clampToTerrain READ clampToTerrain WRITE setClampToTerrain NOTIFY clampToTerrainChanged)
|
||||||
|
Q_PROPERTY(bool intoTerrain READ intoTerrain NOTIFY intoTerrainChanged)
|
||||||
|
|
||||||
|
typedef OSGCameraManipulator Inherited;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OSGGeoTransformManipulator(QObject *parent = 0);
|
||||||
|
virtual ~OSGGeoTransformManipulator();
|
||||||
|
|
||||||
|
QVector3D attitude() const;
|
||||||
|
void setAttitude(QVector3D arg);
|
||||||
|
|
||||||
|
QVector3D position() const;
|
||||||
|
void setPosition(QVector3D arg);
|
||||||
|
|
||||||
|
bool clampToTerrain() const;
|
||||||
|
void setClampToTerrain(bool arg);
|
||||||
|
|
||||||
|
bool intoTerrain() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void attitudeChanged(QVector3D arg);
|
||||||
|
void positionChanged(QVector3D arg);
|
||||||
|
void clampToTerrainChanged(bool arg);
|
||||||
|
void intoTerrainChanged(bool arg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Hidden;
|
||||||
|
Hidden *const h;
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
};
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#endif // _H_OSGQTQUICK_OSGGEOTRANSFORMMANIPULATOR_H_
|
@ -0,0 +1,175 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGNodeTrackerManipulator.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "OSGNodeTrackerManipulator.hpp"
|
||||||
|
|
||||||
|
#include "../OSGNode.hpp"
|
||||||
|
|
||||||
|
#include <osgGA/NodeTrackerManipulator>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
enum DirtyFlag { TrackNode = 1 << 10, TrackerMode = 1 << 11 };
|
||||||
|
|
||||||
|
struct OSGNodeTrackerManipulator::Hidden : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGNodeTrackerManipulator * const self;
|
||||||
|
|
||||||
|
public:
|
||||||
|
osg::ref_ptr<osgGA::NodeTrackerManipulator> manipulator;
|
||||||
|
|
||||||
|
OSGNode *trackNode;
|
||||||
|
TrackerMode::Enum trackerMode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Hidden(OSGNodeTrackerManipulator *self) : QObject(self), self(self),
|
||||||
|
trackNode(NULL), trackerMode(TrackerMode::NodeCenterAndAzim)
|
||||||
|
{
|
||||||
|
manipulator = new osgGA::NodeTrackerManipulator(
|
||||||
|
/*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/);
|
||||||
|
manipulator->setTrackerMode(toOsg(trackerMode));
|
||||||
|
manipulator->setVerticalAxisFixed(false);
|
||||||
|
|
||||||
|
self->setManipulator(manipulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Hidden()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool acceptTrackNode(OSGNode *node)
|
||||||
|
{
|
||||||
|
qDebug() << "OSGNodeTrackerManipulator::acceptTrackNode" << node;
|
||||||
|
if (trackNode == node) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackNode) {
|
||||||
|
disconnect(trackNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
trackNode = node;
|
||||||
|
|
||||||
|
if (trackNode) {
|
||||||
|
connect(trackNode, &OSGNode::nodeChanged, this, &OSGNodeTrackerManipulator::Hidden::onTrackNodeChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateTrackNode()
|
||||||
|
{
|
||||||
|
if (!trackNode) {
|
||||||
|
qWarning() << "OSGNodeTrackerManipulator::updateTrackNode - no track node";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "OSGNodeTrackerManipulator::updateTrackNode" << trackNode->node();
|
||||||
|
manipulator->setTrackNode(trackNode->node());
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateTrackerMode()
|
||||||
|
{
|
||||||
|
// qDebug() << "OSGNodeTrackerManipulator::updateTrackerMode" << mode;
|
||||||
|
manipulator->setTrackerMode(toOsg(trackerMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
osgGA::NodeTrackerManipulator::TrackerMode toOsg(TrackerMode::Enum mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case TrackerMode::NodeCenter:
|
||||||
|
return osgGA::NodeTrackerManipulator::NODE_CENTER;
|
||||||
|
|
||||||
|
case TrackerMode::NodeCenterAndAzim:
|
||||||
|
return osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM;
|
||||||
|
|
||||||
|
case TrackerMode::NodeCenterAndRotation:
|
||||||
|
return osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
|
||||||
|
}
|
||||||
|
return osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onTrackNodeChanged(osg::Node *node)
|
||||||
|
{
|
||||||
|
qDebug() << "OSGNodeTrackerManipulator::onTrackNodeChanged" << node;
|
||||||
|
qWarning() << "OSGNodeTrackerManipulator::onTrackNodeChanged - needs to be implemented";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class OSGNodeTrackerManipulator */
|
||||||
|
|
||||||
|
OSGNodeTrackerManipulator::OSGNodeTrackerManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
OSGNodeTrackerManipulator::~OSGNodeTrackerManipulator()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGNode *OSGNodeTrackerManipulator::trackNode() const
|
||||||
|
{
|
||||||
|
return h->trackNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGNodeTrackerManipulator::setTrackNode(OSGNode *node)
|
||||||
|
{
|
||||||
|
if (h->acceptTrackNode(node)) {
|
||||||
|
setDirty(TrackNode);
|
||||||
|
emit trackNodeChanged(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackerMode::Enum OSGNodeTrackerManipulator::trackerMode() const
|
||||||
|
{
|
||||||
|
return h->trackerMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGNodeTrackerManipulator::setTrackerMode(TrackerMode::Enum mode)
|
||||||
|
{
|
||||||
|
if (h->trackerMode != mode) {
|
||||||
|
h->trackerMode = mode;
|
||||||
|
setDirty(TrackerMode);
|
||||||
|
emit trackerModeChanged(trackerMode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSGNodeTrackerManipulator::update()
|
||||||
|
{
|
||||||
|
Inherited::update();
|
||||||
|
|
||||||
|
if (isDirty(TrackNode)) {
|
||||||
|
h->updateTrackNode();
|
||||||
|
}
|
||||||
|
if (isDirty(TrackerMode)) {
|
||||||
|
h->updateTrackerMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#include "OSGNodeTrackerManipulator.moc"
|
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGNodeTrackerManipulator.hpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_OSGQTQUICK_OSGNODETRACKERMANIPULATOR_H_
|
||||||
|
#define _H_OSGQTQUICK_OSGNODETRACKERMANIPULATOR_H_
|
||||||
|
|
||||||
|
#include "../Export.hpp"
|
||||||
|
#include "OSGCameraManipulator.hpp"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
class TrackerMode : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Enum { NodeCenter, NodeCenterAndAzim, NodeCenterAndRotation };
|
||||||
|
Q_ENUMS(Enum) // TODO switch to Q_ENUM once on Qt 5.5
|
||||||
|
};
|
||||||
|
|
||||||
|
class OSGQTQUICK_EXPORT OSGNodeTrackerManipulator : public OSGCameraManipulator {
|
||||||
|
Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *trackNode READ trackNode WRITE setTrackNode NOTIFY trackNodeChanged)
|
||||||
|
Q_PROPERTY(osgQtQuick::TrackerMode::Enum trackerMode READ trackerMode WRITE setTrackerMode NOTIFY trackerModeChanged)
|
||||||
|
|
||||||
|
typedef OSGCameraManipulator Inherited;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OSGNodeTrackerManipulator(QObject *parent = 0);
|
||||||
|
virtual ~OSGNodeTrackerManipulator();
|
||||||
|
|
||||||
|
OSGNode *trackNode() const;
|
||||||
|
void setTrackNode(OSGNode *node);
|
||||||
|
|
||||||
|
TrackerMode::Enum trackerMode() const;
|
||||||
|
void setTrackerMode(TrackerMode::Enum);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void trackNodeChanged(OSGNode *node);
|
||||||
|
void trackerModeChanged(TrackerMode::Enum);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Hidden;
|
||||||
|
Hidden *const h;
|
||||||
|
|
||||||
|
virtual void update();
|
||||||
|
};
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#endif // _H_OSGQTQUICK_OSGNODETRACKERMANIPULATOR_H_
|
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGTrackballManipulator.cpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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 "OSGTrackballManipulator.hpp"
|
||||||
|
|
||||||
|
#include "../OSGNode.hpp"
|
||||||
|
|
||||||
|
#include <osgGA/TrackballManipulator>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
struct OSGTrackballManipulator::Hidden : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSGTrackballManipulator * const self;
|
||||||
|
|
||||||
|
public:
|
||||||
|
osg::ref_ptr<osgGA::TrackballManipulator> manipulator;
|
||||||
|
|
||||||
|
Hidden(OSGTrackballManipulator *self) : QObject(self), self(self)
|
||||||
|
{
|
||||||
|
manipulator = new osgGA::TrackballManipulator(
|
||||||
|
/*osgGA::StandardManipulator::COMPUTE_HOME_USING_BBOX | osgGA::StandardManipulator::DEFAULT_SETTINGS*/);
|
||||||
|
|
||||||
|
self->setManipulator(manipulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Hidden()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* class OSGTrackballManipulator */
|
||||||
|
|
||||||
|
OSGTrackballManipulator::OSGTrackballManipulator(QObject *parent) : Inherited(parent), h(new Hidden(this))
|
||||||
|
{}
|
||||||
|
|
||||||
|
OSGTrackballManipulator::~OSGTrackballManipulator()
|
||||||
|
{
|
||||||
|
delete h;
|
||||||
|
}
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#include "OSGTrackballManipulator.moc"
|
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @file OSGTrackballManipulator.hpp
|
||||||
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_OSGQTQUICK_OSGTRACKBALLMANIPULATOR_H_
|
||||||
|
#define _H_OSGQTQUICK_OSGTRACKBALLMANIPULATOR_H_
|
||||||
|
|
||||||
|
#include "../Export.hpp"
|
||||||
|
#include "OSGCameraManipulator.hpp"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace osgQtQuick {
|
||||||
|
class OSGQTQUICK_EXPORT OSGTrackballManipulator : public OSGCameraManipulator {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
typedef OSGCameraManipulator Inherited;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OSGTrackballManipulator(QObject *parent = 0);
|
||||||
|
virtual ~OSGTrackballManipulator();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Hidden;
|
||||||
|
Hidden *const h;
|
||||||
|
};
|
||||||
|
} // namespace osgQtQuick
|
||||||
|
|
||||||
|
#endif // _H_OSGQTQUICK_OSGTRACKBALLMANIPULATOR_H_
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file osgearth.cpp
|
* @file osgearth.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -27,8 +27,8 @@
|
|||||||
|
|
||||||
#include "osgearth.h"
|
#include "osgearth.h"
|
||||||
|
|
||||||
#include "utility.h"
|
#include "utils/utility.h"
|
||||||
#include "qtwindowingsystem.h"
|
#include "utils/qtwindowingsystem.h"
|
||||||
|
|
||||||
#include "utils/pathutils.h"
|
#include "utils/pathutils.h"
|
||||||
|
|
||||||
@ -107,7 +107,9 @@ void OsgEarth::initialize()
|
|||||||
|
|
||||||
initializeCache();
|
initializeCache();
|
||||||
|
|
||||||
|
#ifdef OSG_VERBOSE
|
||||||
displayInfo();
|
displayInfo();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsgEarth::initializePathes()
|
void OsgEarth::initializePathes()
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file osgearth.h
|
* @file osgearth.h
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
|
@ -2,7 +2,7 @@ TEMPLATE = lib
|
|||||||
TARGET = GCSOsgEarth
|
TARGET = GCSOsgEarth
|
||||||
DEFINES += OSGEARTH_LIBRARY
|
DEFINES += OSGEARTH_LIBRARY
|
||||||
|
|
||||||
#CONFIG += mys2
|
#DEFINES += OSG_VERBOSE
|
||||||
|
|
||||||
osg:DEFINES += USE_OSG
|
osg:DEFINES += USE_OSG
|
||||||
osgQt:DEFINES += USE_OSG_QT
|
osgQt:DEFINES += USE_OSG_QT
|
||||||
@ -35,40 +35,54 @@ QMAKE_CXXFLAGS += -Wno-unused-parameter
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
osgearth_global.h \
|
osgearth_global.h \
|
||||||
utility.h \
|
osgearth.h \
|
||||||
shapeutils.h \
|
utils/qtwindowingsystem.h \
|
||||||
qtwindowingsystem.h \
|
utils/utility.h \
|
||||||
osgearth.h
|
utils/shapeutils.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
utility.cpp \
|
osgearth.cpp \
|
||||||
shapeutils.cpp \
|
utils/qtwindowingsystem.cpp \
|
||||||
qtwindowingsystem.cpp \
|
utils/utility.cpp \
|
||||||
osgearth.cpp
|
utils/shapeutils.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
osgQtQuick/Export.hpp \
|
osgQtQuick/Export.hpp \
|
||||||
|
osgQtQuick/DirtySupport.hpp \
|
||||||
osgQtQuick/OSGNode.hpp \
|
osgQtQuick/OSGNode.hpp \
|
||||||
osgQtQuick/OSGGroup.hpp \
|
osgQtQuick/OSGGroup.hpp \
|
||||||
osgQtQuick/OSGTransformNode.hpp \
|
osgQtQuick/OSGTransformNode.hpp \
|
||||||
osgQtQuick/OSGShapeNode.hpp \
|
osgQtQuick/OSGShapeNode.hpp \
|
||||||
|
osgQtQuick/OSGImageNode.hpp \
|
||||||
osgQtQuick/OSGTextNode.hpp \
|
osgQtQuick/OSGTextNode.hpp \
|
||||||
osgQtQuick/OSGFileNode.hpp \
|
osgQtQuick/OSGFileNode.hpp \
|
||||||
osgQtQuick/OSGBackgroundNode.hpp \
|
osgQtQuick/OSGBillboardNode.hpp \
|
||||||
osgQtQuick/OSGCamera.hpp \
|
osgQtQuick/OSGCamera.hpp \
|
||||||
osgQtQuick/OSGViewport.hpp
|
osgQtQuick/OSGViewport.hpp
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
osgQtQuick/DirtySupport.cpp \
|
||||||
osgQtQuick/OSGNode.cpp \
|
osgQtQuick/OSGNode.cpp \
|
||||||
osgQtQuick/OSGGroup.cpp \
|
osgQtQuick/OSGGroup.cpp \
|
||||||
osgQtQuick/OSGTransformNode.cpp \
|
osgQtQuick/OSGTransformNode.cpp \
|
||||||
osgQtQuick/OSGShapeNode.cpp \
|
osgQtQuick/OSGShapeNode.cpp \
|
||||||
|
osgQtQuick/OSGImageNode.cpp \
|
||||||
osgQtQuick/OSGTextNode.cpp \
|
osgQtQuick/OSGTextNode.cpp \
|
||||||
osgQtQuick/OSGFileNode.cpp \
|
osgQtQuick/OSGFileNode.cpp \
|
||||||
osgQtQuick/OSGBackgroundNode.cpp \
|
osgQtQuick/OSGBillboardNode.cpp \
|
||||||
osgQtQuick/OSGCamera.cpp \
|
osgQtQuick/OSGCamera.cpp \
|
||||||
osgQtQuick/OSGViewport.cpp
|
osgQtQuick/OSGViewport.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
osgQtQuick/ga/OSGCameraManipulator.hpp \
|
||||||
|
osgQtQuick/ga/OSGNodeTrackerManipulator.hpp \
|
||||||
|
osgQtQuick/ga/OSGTrackballManipulator.hpp
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
osgQtQuick/ga/OSGCameraManipulator.cpp \
|
||||||
|
osgQtQuick/ga/OSGNodeTrackerManipulator.cpp \
|
||||||
|
osgQtQuick/ga/OSGTrackballManipulator.cpp
|
||||||
|
|
||||||
osgearth:HEADERS += \
|
osgearth:HEADERS += \
|
||||||
osgQtQuick/OSGSkyNode.hpp \
|
osgQtQuick/OSGSkyNode.hpp \
|
||||||
osgQtQuick/OSGGeoTransformNode.hpp
|
osgQtQuick/OSGGeoTransformNode.hpp
|
||||||
@ -77,4 +91,12 @@ osgearth:SOURCES += \
|
|||||||
osgQtQuick/OSGSkyNode.cpp \
|
osgQtQuick/OSGSkyNode.cpp \
|
||||||
osgQtQuick/OSGGeoTransformNode.cpp
|
osgQtQuick/OSGGeoTransformNode.cpp
|
||||||
|
|
||||||
|
osgearth:HEADERS += \
|
||||||
|
osgQtQuick/ga/OSGEarthManipulator.hpp \
|
||||||
|
osgQtQuick/ga/OSGGeoTransformManipulator.hpp
|
||||||
|
|
||||||
|
osgearth:SOURCES += \
|
||||||
|
osgQtQuick/ga/OSGEarthManipulator.cpp \
|
||||||
|
osgQtQuick/ga/OSGGeoTransformManipulator.cpp
|
||||||
|
|
||||||
copy_osg:include(copydata.pro)
|
copy_osg:include(copydata.pro)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file osgearth_global.h
|
* @file osgearth_global.h
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
|
@ -4,3 +4,6 @@ References :
|
|||||||
- https://wiki.qt.io/OsgQtQuick-Demo
|
- https://wiki.qt.io/OsgQtQuick-Demo
|
||||||
- https://github.com/podsvirov
|
- https://github.com/podsvirov
|
||||||
- https://github.com/podsvirov/osgqtquick
|
- https://github.com/podsvirov/osgqtquick
|
||||||
|
|
||||||
|
known issues:
|
||||||
|
- http://forum.osgearth.org/VERTEX-glCompileShader-quot-oe-mp-vertModel-quot-FAILED-tt7588106.html#none
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file qtwindowingsystem.cpp
|
* @file qtwindowingsystem.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -103,20 +103,20 @@ GraphicsWindowQt::GraphicsWindowQt(osg::GraphicsContext::Traits *traits) :
|
|||||||
_glContext(NULL),
|
_glContext(NULL),
|
||||||
_surface(NULL)
|
_surface(NULL)
|
||||||
{
|
{
|
||||||
qDebug() << "GraphicsWindowQt::GraphicsWindowQt";
|
// qDebug() << "GraphicsWindowQt::GraphicsWindowQt";
|
||||||
_traits = traits;
|
_traits = traits;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsWindowQt::~GraphicsWindowQt()
|
GraphicsWindowQt::~GraphicsWindowQt()
|
||||||
{
|
{
|
||||||
qDebug() << "GraphicsWindowQt::~GraphicsWindowQt";
|
// qDebug() << "GraphicsWindowQt::~GraphicsWindowQt";
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWindowQt::init()
|
void GraphicsWindowQt::init()
|
||||||
{
|
{
|
||||||
qDebug() << "GraphicsWindowQt::init";
|
// qDebug() << "GraphicsWindowQt::init";
|
||||||
if (_closing || _initialized) {
|
if (_closing || _initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -199,7 +199,7 @@ bool GraphicsWindowQt::valid() const
|
|||||||
|
|
||||||
bool GraphicsWindowQt::realizeImplementation()
|
bool GraphicsWindowQt::realizeImplementation()
|
||||||
{
|
{
|
||||||
qDebug() << "GraphicsWindowQt::realizeImplementation";
|
// qDebug() << "GraphicsWindowQt::realizeImplementation";
|
||||||
// save the current context
|
// save the current context
|
||||||
// note: this will save only Qt-based contexts
|
// note: this will save only Qt-based contexts
|
||||||
|
|
||||||
@ -217,16 +217,18 @@ bool GraphicsWindowQt::realizeImplementation()
|
|||||||
QOpenGLContext *currentContext = QOpenGLContext::currentContext();
|
QOpenGLContext *currentContext = QOpenGLContext::currentContext();
|
||||||
|
|
||||||
if (!currentContext) {
|
if (!currentContext) {
|
||||||
qDebug() << "GraphicsWindowQt::realizeImplementation - creating owned context";
|
// qDebug() << "GraphicsWindowQt::realizeImplementation - creating owned context";
|
||||||
_owned = true;
|
_owned = true;
|
||||||
_glContext = new QOpenGLContext();
|
_glContext = new QOpenGLContext();
|
||||||
_glContext->create();
|
_glContext->create();
|
||||||
_surface = new QOffscreenSurface();
|
_surface = new QOffscreenSurface();
|
||||||
_surface->setFormat(_glContext->format());
|
_surface->setFormat(_glContext->format());
|
||||||
_surface->create();
|
_surface->create();
|
||||||
|
#ifdef OSG_VERBOSE
|
||||||
osgQtQuick::formatInfo(_surface->format());
|
osgQtQuick::formatInfo(_surface->format());
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "GraphicsWindowQt::realizeImplementation - using current context";
|
// qDebug() << "GraphicsWindowQt::realizeImplementation - using current context";
|
||||||
_glContext = currentContext;
|
_glContext = currentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +318,7 @@ bool GraphicsWindowQt::releaseContextImplementation()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_owned && _glContext) {
|
if (_owned && _glContext) {
|
||||||
qDebug() << "GraphicsWindowQt::releaseContextImplementation";
|
// qDebug() << "GraphicsWindowQt::releaseContextImplementation";
|
||||||
_glContext->doneCurrent();
|
_glContext->doneCurrent();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -324,14 +326,14 @@ bool GraphicsWindowQt::releaseContextImplementation()
|
|||||||
|
|
||||||
void GraphicsWindowQt::closeImplementation()
|
void GraphicsWindowQt::closeImplementation()
|
||||||
{
|
{
|
||||||
qDebug() << "GraphicsWindowQt::closeImplementation";
|
// qDebug() << "GraphicsWindowQt::closeImplementation";
|
||||||
_closing = true;
|
_closing = true;
|
||||||
_initialized = false;
|
_initialized = false;
|
||||||
_valid = false;
|
_valid = false;
|
||||||
_realized = false;
|
_realized = false;
|
||||||
if (_owned) {
|
if (_owned) {
|
||||||
if (_glContext) {
|
if (_glContext) {
|
||||||
qDebug() << "GraphicsWindowQt::closeImplementation - deleting owned context";
|
// qDebug() << "GraphicsWindowQt::closeImplementation - deleting owned context";
|
||||||
delete _glContext;
|
delete _glContext;
|
||||||
}
|
}
|
||||||
if (_surface) {
|
if (_surface) {
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file qtwindowingsystem.h
|
* @file qtwindowingsystem.h
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
@ -1,4 +1,4 @@
|
|||||||
#include "shapeutils.h"
|
#include "utils/shapeutils.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file utility.cpp
|
* @file utility.cpp
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
@ -25,7 +25,7 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utility.h"
|
#include "utils/utility.h"
|
||||||
|
|
||||||
// osgQtQuick qml types
|
// osgQtQuick qml types
|
||||||
#include "osgQtQuick/OSGNode.hpp"
|
#include "osgQtQuick/OSGNode.hpp"
|
||||||
@ -33,11 +33,16 @@
|
|||||||
#include "osgQtQuick/OSGFileNode.hpp"
|
#include "osgQtQuick/OSGFileNode.hpp"
|
||||||
#include "osgQtQuick/OSGTransformNode.hpp"
|
#include "osgQtQuick/OSGTransformNode.hpp"
|
||||||
#include "osgQtQuick/OSGShapeNode.hpp"
|
#include "osgQtQuick/OSGShapeNode.hpp"
|
||||||
|
#include "osgQtQuick/OSGImageNode.hpp"
|
||||||
#include "osgQtQuick/OSGTextNode.hpp"
|
#include "osgQtQuick/OSGTextNode.hpp"
|
||||||
#include "osgQtQuick/OSGBackgroundNode.hpp"
|
#include "osgQtQuick/OSGBillboardNode.hpp"
|
||||||
#include "osgQtQuick/OSGCamera.hpp"
|
#include "osgQtQuick/OSGCamera.hpp"
|
||||||
#include "osgQtQuick/OSGViewport.hpp"
|
#include "osgQtQuick/OSGViewport.hpp"
|
||||||
|
|
||||||
|
#include "osgQtQuick/ga/OSGCameraManipulator.hpp"
|
||||||
|
#include "osgQtQuick/ga/OSGNodeTrackerManipulator.hpp"
|
||||||
|
#include "osgQtQuick/ga/OSGTrackballManipulator.hpp"
|
||||||
|
|
||||||
#include <osg/NodeCallback>
|
#include <osg/NodeCallback>
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
#include <osg/MatrixTransform>
|
#include <osg/MatrixTransform>
|
||||||
@ -61,6 +66,9 @@
|
|||||||
#include "osgQtQuick/OSGSkyNode.hpp"
|
#include "osgQtQuick/OSGSkyNode.hpp"
|
||||||
#include "osgQtQuick/OSGGeoTransformNode.hpp"
|
#include "osgQtQuick/OSGGeoTransformNode.hpp"
|
||||||
|
|
||||||
|
#include "osgQtQuick/ga/OSGEarthManipulator.hpp"
|
||||||
|
#include "osgQtQuick/ga/OSGGeoTransformManipulator.hpp"
|
||||||
|
|
||||||
#include <osgEarth/Capabilities>
|
#include <osgEarth/Capabilities>
|
||||||
#include <osgEarth/MapNode>
|
#include <osgEarth/MapNode>
|
||||||
#include <osgEarth/SpatialReference>
|
#include <osgEarth/SpatialReference>
|
||||||
@ -75,9 +83,11 @@
|
|||||||
namespace osgQtQuick {
|
namespace osgQtQuick {
|
||||||
class CullCallback : public osg::NodeCallback {
|
class CullCallback : public osg::NodeCallback {
|
||||||
public:
|
public:
|
||||||
CullCallback() {}
|
CullCallback()
|
||||||
|
{}
|
||||||
|
|
||||||
virtual ~CullCallback() {}
|
virtual ~CullCallback()
|
||||||
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)
|
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)
|
||||||
@ -101,12 +111,14 @@ class InsertCallbacksVisitor : public osg::NodeVisitor {
|
|||||||
public:
|
public:
|
||||||
InsertCallbacksVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
|
InsertCallbacksVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void apply(osg::Node & node)
|
virtual void apply(osg::Node & node)
|
||||||
{
|
{
|
||||||
// node.setUpdateCallback(new UpdateCallback());
|
// node.setUpdateCallback(new UpdateCallback());
|
||||||
node.setCullCallback(new CullCallback());
|
node.setCullCallback(new CullCallback());
|
||||||
traverse(node);
|
traverse(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void apply(osg::Geode & geode)
|
virtual void apply(osg::Geode & geode)
|
||||||
{
|
{
|
||||||
// geode.setUpdateCallback(new UpdateCallback());
|
// geode.setUpdateCallback(new UpdateCallback());
|
||||||
@ -122,6 +134,7 @@ public:
|
|||||||
// geode.getDrawable(i)->setDrawCallback(new DrawableDrawCallback());
|
// geode.getDrawable(i)->setDrawCallback(new DrawableDrawCallback());
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void apply(osg::Transform & node)
|
virtual void apply(osg::Transform & node)
|
||||||
{
|
{
|
||||||
apply((osg::Node &)node);
|
apply((osg::Node &)node);
|
||||||
@ -469,7 +482,7 @@ bool clampGeoPoint(osgEarth::GeoPoint &geoPoint, float offset, osgEarth::MapNode
|
|||||||
if (eq.getElevation(geoPoint, elevation, 0.0)) {
|
if (eq.getElevation(geoPoint, elevation, 0.0)) {
|
||||||
clamped = ((geoPoint.z() - offset) < elevation);
|
clamped = ((geoPoint.z() - offset) < elevation);
|
||||||
if (clamped) {
|
if (clamped) {
|
||||||
qDebug() << "Utility::clampGeoPoint - clamping" << geoPoint.z() - offset << "/" << elevation;
|
// qDebug() << "Utility::clampGeoPoint - clamping" << geoPoint.z() - offset << "/" << elevation;
|
||||||
geoPoint.z() = elevation + offset;
|
geoPoint.z() = elevation + offset;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -522,33 +535,45 @@ void registerTypes()
|
|||||||
{
|
{
|
||||||
int maj = 1, min = 0;
|
int maj = 1, min = 0;
|
||||||
|
|
||||||
// @uri osgQtQuick
|
// viewport
|
||||||
|
qmlRegisterType<osgQtQuick::OSGViewport>("OsgQtQuick", maj, min, "OSGViewport");
|
||||||
|
qmlRegisterType<osgQtQuick::UpdateMode>("OsgQtQuick", maj, min, "UpdateMode");
|
||||||
|
|
||||||
|
// basic nodes
|
||||||
qmlRegisterType<osgQtQuick::OSGNode>("OsgQtQuick", maj, min, "OSGNode");
|
qmlRegisterType<osgQtQuick::OSGNode>("OsgQtQuick", maj, min, "OSGNode");
|
||||||
|
|
||||||
qmlRegisterType<osgQtQuick::OSGGroup>("OsgQtQuick", maj, min, "OSGGroup");
|
qmlRegisterType<osgQtQuick::OSGGroup>("OsgQtQuick", maj, min, "OSGGroup");
|
||||||
|
|
||||||
qmlRegisterType<osgQtQuick::OSGFileNode>("OsgQtQuick", maj, min, "OSGFileNode");
|
|
||||||
qmlRegisterType<osgQtQuick::OptimizeMode>("OsgQtQuick", maj, min, "OptimizeMode");
|
|
||||||
|
|
||||||
qmlRegisterType<osgQtQuick::OSGTransformNode>("OsgQtQuick", maj, min, "OSGTransformNode");
|
qmlRegisterType<osgQtQuick::OSGTransformNode>("OsgQtQuick", maj, min, "OSGTransformNode");
|
||||||
|
|
||||||
qmlRegisterType<osgQtQuick::OSGTextNode>("OsgQtQuick", maj, min, "OSGTextNode");
|
// primitive nodes
|
||||||
|
|
||||||
qmlRegisterType<osgQtQuick::OSGShapeNode>("OsgQtQuick", maj, min, "OSGShapeNode");
|
qmlRegisterType<osgQtQuick::OSGShapeNode>("OsgQtQuick", maj, min, "OSGShapeNode");
|
||||||
qmlRegisterType<osgQtQuick::ShapeType>("OsgQtQuick", maj, min, "ShapeType");
|
qmlRegisterType<osgQtQuick::ShapeType>("OsgQtQuick", maj, min, "ShapeType");
|
||||||
|
|
||||||
qmlRegisterType<osgQtQuick::OSGBackgroundNode>("OsgQtQuick", maj, min, "OSGBackgroundNode");
|
qmlRegisterType<osgQtQuick::OSGImageNode>("OsgQtQuick", maj, min, "OSGImageNode");
|
||||||
|
|
||||||
qmlRegisterType<osgQtQuick::OSGViewport>("OsgQtQuick", maj, min, "OSGViewport");
|
qmlRegisterType<osgQtQuick::OSGTextNode>("OsgQtQuick", maj, min, "OSGTextNode");
|
||||||
qmlRegisterType<osgQtQuick::UpdateMode>("OsgQtQuick", maj, min, "UpdateMode");
|
|
||||||
|
|
||||||
|
qmlRegisterType<osgQtQuick::OSGBillboardNode>("OsgQtQuick", maj, min, "OSGBillboardNode");
|
||||||
|
|
||||||
|
qmlRegisterType<osgQtQuick::OSGFileNode>("OsgQtQuick", maj, min, "OSGFileNode");
|
||||||
|
qmlRegisterType<osgQtQuick::OptimizeMode>("OsgQtQuick", maj, min, "OptimizeMode");
|
||||||
|
|
||||||
|
// camera nodes
|
||||||
qmlRegisterType<osgQtQuick::OSGCamera>("OsgQtQuick", maj, min, "OSGCamera");
|
qmlRegisterType<osgQtQuick::OSGCamera>("OsgQtQuick", maj, min, "OSGCamera");
|
||||||
qmlRegisterType<osgQtQuick::ManipulatorMode>("OsgQtQuick", maj, min, "ManipulatorMode");
|
|
||||||
|
// camera manipulators
|
||||||
|
qmlRegisterType<osgQtQuick::OSGCameraManipulator>("OsgQtQuick", maj, min, "OSGCameraManipulator");
|
||||||
|
qmlRegisterType<osgQtQuick::OSGNodeTrackerManipulator>("OsgQtQuick", maj, min, "OSGNodeTrackerManipulator");
|
||||||
qmlRegisterType<osgQtQuick::TrackerMode>("OsgQtQuick", maj, min, "TrackerMode");
|
qmlRegisterType<osgQtQuick::TrackerMode>("OsgQtQuick", maj, min, "TrackerMode");
|
||||||
|
qmlRegisterType<osgQtQuick::OSGTrackballManipulator>("OsgQtQuick", maj, min, "OSGTrackballManipulator");
|
||||||
|
|
||||||
#ifdef USE_OSGEARTH
|
#ifdef USE_OSGEARTH
|
||||||
qmlRegisterType<osgQtQuick::OSGSkyNode>("OsgQtQuick", maj, min, "OSGSkyNode");
|
qmlRegisterType<osgQtQuick::OSGSkyNode>("OsgQtQuick", maj, min, "OSGSkyNode");
|
||||||
qmlRegisterType<osgQtQuick::OSGGeoTransformNode>("OsgQtQuick", maj, min, "OSGGeoTransformNode");
|
qmlRegisterType<osgQtQuick::OSGGeoTransformNode>("OsgQtQuick", maj, min, "OSGGeoTransformNode");
|
||||||
|
|
||||||
|
qmlRegisterType<osgQtQuick::OSGEarthManipulator>("OsgQtQuick", maj, min, "OSGEarthManipulator");
|
||||||
|
qmlRegisterType<osgQtQuick::OSGGeoTransformManipulator>("OsgQtQuick", maj, min, "OSGGeoTransformManipulator");
|
||||||
#endif // USE_OSGEARTH
|
#endif // USE_OSGEARTH
|
||||||
}
|
}
|
||||||
} // namespace osgQtQuick
|
} // namespace osgQtQuick
|
@ -2,7 +2,7 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* @file utility.h
|
* @file utility.h
|
||||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||||
* @addtogroup
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup
|
* @addtogroup
|
@ -127,16 +127,16 @@ void QuickWidgetProxy::onStatusChanged(QQuickWidget::Status status)
|
|||||||
{
|
{
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case QQuickWidget::Null:
|
case QQuickWidget::Null:
|
||||||
qDebug() << "QuickWidgetProxy - status Null";
|
qWarning() << "QuickWidgetProxy - status Null";
|
||||||
break;
|
break;
|
||||||
case QQuickWidget::Ready:
|
case QQuickWidget::Ready:
|
||||||
qDebug() << "QuickWidgetProxy - status Ready";
|
// qDebug() << "QuickWidgetProxy - status Ready";
|
||||||
break;
|
break;
|
||||||
case QQuickWidget::Loading:
|
case QQuickWidget::Loading:
|
||||||
qDebug() << "QuickWidgetProxy - status Loading";
|
// qDebug() << "QuickWidgetProxy - status Loading";
|
||||||
break;
|
break;
|
||||||
case QQuickWidget::Error:
|
case QQuickWidget::Error:
|
||||||
qDebug() << "QuickWidgetProxy - status Error";
|
qWarning() << "QuickWidgetProxy - status Error";
|
||||||
foreach(const QQmlError &error, errors()) {
|
foreach(const QQmlError &error, errors()) {
|
||||||
qWarning() << error.description();
|
qWarning() << error.description();
|
||||||
}
|
}
|
||||||
@ -148,16 +148,16 @@ void QuickWidgetProxy::onStatusChanged(QQuickView::Status status)
|
|||||||
{
|
{
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case QQuickView::Null:
|
case QQuickView::Null:
|
||||||
qDebug() << "QuickWidgetProxy - status Null";
|
qWarning() << "QuickWidgetProxy - status Null";
|
||||||
break;
|
break;
|
||||||
case QQuickView::Ready:
|
case QQuickView::Ready:
|
||||||
qDebug() << "QuickWidgetProxy - status Ready";
|
// qDebug() << "QuickWidgetProxy - status Ready";
|
||||||
break;
|
break;
|
||||||
case QQuickView::Loading:
|
case QQuickView::Loading:
|
||||||
qDebug() << "QuickWidgetProxy - status Loading";
|
// qDebug() << "QuickWidgetProxy - status Loading";
|
||||||
break;
|
break;
|
||||||
case QQuickView::Error:
|
case QQuickView::Error:
|
||||||
qDebug() << "QuickWidgetProxy - status Error";
|
qWarning() << "QuickWidgetProxy - status Error";
|
||||||
foreach(const QQmlError &error, errors()) {
|
foreach(const QQmlError &error, errors()) {
|
||||||
qWarning() << error.description();
|
qWarning() << error.description();
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,18 @@
|
|||||||
#include "pfdqmlcontext.h"
|
#include "pfdqmlcontext.h"
|
||||||
|
|
||||||
#include "extensionsystem/pluginmanager.h"
|
#include "extensionsystem/pluginmanager.h"
|
||||||
#include "uavobjectmanager.h"
|
|
||||||
#include "uavobject.h"
|
#include "uavobject.h"
|
||||||
|
#include "uavobjectmanager.h"
|
||||||
#include "utils/stringutils.h"
|
#include "utils/stringutils.h"
|
||||||
|
#include "utils/pathutils.h"
|
||||||
|
|
||||||
#include "flightbatterysettings.h"
|
#include "flightbatterysettings.h"
|
||||||
|
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QDirIterator>
|
||||||
|
|
||||||
|
const QString PfdQmlContext::CONTEXT_PROPERTY_NAME = "pfdContext";
|
||||||
|
|
||||||
PfdQmlContext::PfdQmlContext(QObject *parent) : QObject(parent),
|
PfdQmlContext::PfdQmlContext(QObject *parent) : QObject(parent),
|
||||||
m_speedUnit("m/s"),
|
m_speedUnit("m/s"),
|
||||||
@ -50,8 +55,13 @@ PfdQmlContext::PfdQmlContext(QObject *parent) : QObject(parent),
|
|||||||
m_dateTime(QDateTime()),
|
m_dateTime(QDateTime()),
|
||||||
m_minAmbientLight(0.03),
|
m_minAmbientLight(0.03),
|
||||||
m_modelFile(""),
|
m_modelFile(""),
|
||||||
|
m_modelIndex(0),
|
||||||
m_backgroundImageFile("")
|
m_backgroundImageFile("")
|
||||||
{}
|
{
|
||||||
|
addModelDir("helis");
|
||||||
|
addModelDir("multi");
|
||||||
|
addModelDir("planes");
|
||||||
|
}
|
||||||
|
|
||||||
PfdQmlContext::~PfdQmlContext()
|
PfdQmlContext::~PfdQmlContext()
|
||||||
{}
|
{}
|
||||||
@ -220,11 +230,32 @@ QString PfdQmlContext::modelFile() const
|
|||||||
void PfdQmlContext::setModelFile(const QString &arg)
|
void PfdQmlContext::setModelFile(const QString &arg)
|
||||||
{
|
{
|
||||||
if (m_modelFile != arg) {
|
if (m_modelFile != arg) {
|
||||||
m_modelFile = arg;
|
m_modelFile = arg;
|
||||||
|
m_modelIndex = m_modelFileList.indexOf(m_modelFile);
|
||||||
|
if (m_modelIndex == -1) {
|
||||||
|
m_modelIndex = 0;
|
||||||
|
}
|
||||||
emit modelFileChanged(modelFile());
|
emit modelFileChanged(modelFile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PfdQmlContext::nextModel()
|
||||||
|
{
|
||||||
|
m_modelIndex = (m_modelIndex + 1) % m_modelFileList.length();
|
||||||
|
setModelFile(m_modelFileList[m_modelIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PfdQmlContext::previousModel()
|
||||||
|
{
|
||||||
|
m_modelIndex = (m_modelFileList.length() + m_modelIndex - 1) % m_modelFileList.length();
|
||||||
|
setModelFile(m_modelFileList[m_modelIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList PfdQmlContext::modelFileList() const
|
||||||
|
{
|
||||||
|
return m_modelFileList;
|
||||||
|
}
|
||||||
|
|
||||||
QString PfdQmlContext::backgroundImageFile() const
|
QString PfdQmlContext::backgroundImageFile() const
|
||||||
{
|
{
|
||||||
return m_backgroundImageFile;
|
return m_backgroundImageFile;
|
||||||
@ -281,12 +312,16 @@ void PfdQmlContext::loadConfiguration(PfdQmlGadgetConfiguration *config)
|
|||||||
|
|
||||||
void PfdQmlContext::saveState(QSettings *settings)
|
void PfdQmlContext::saveState(QSettings *settings)
|
||||||
{
|
{
|
||||||
Q_UNUSED(settings);
|
settings->setValue("modelFile", modelFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PfdQmlContext::restoreState(QSettings *settings)
|
void PfdQmlContext::restoreState(QSettings *settings)
|
||||||
{
|
{
|
||||||
Q_UNUSED(settings);
|
QString file = settings->value("modelFile").toString();
|
||||||
|
|
||||||
|
if (!file.isEmpty()) {
|
||||||
|
setModelFile(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PfdQmlContext::apply(QQmlContext *context)
|
void PfdQmlContext::apply(QQmlContext *context)
|
||||||
@ -339,6 +374,17 @@ void PfdQmlContext::apply(QQmlContext *context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// to expose settings values
|
// expose this context to Qml
|
||||||
context->setContextProperty("pfdContext", this);
|
context->setContextProperty(CONTEXT_PROPERTY_NAME, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PfdQmlContext::addModelDir(QString dir)
|
||||||
|
{
|
||||||
|
QDirIterator it(Utils::GetDataPath() + "models/" + dir, QStringList("*.3ds"), QDir::NoFilter, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
QString file = QDir::toNativeSeparators(it.next());
|
||||||
|
// qDebug() << file;
|
||||||
|
m_modelFileList.append(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,11 @@ class PfdQmlContext : public QObject {
|
|||||||
Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged)
|
Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged)
|
||||||
Q_PROPERTY(double minimumAmbientLight READ minimumAmbientLight WRITE setMinimumAmbientLight NOTIFY minimumAmbientLightChanged)
|
Q_PROPERTY(double minimumAmbientLight READ minimumAmbientLight WRITE setMinimumAmbientLight NOTIFY minimumAmbientLightChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QString modelFile READ modelFile WRITE setModelFile NOTIFY modelFileChanged)
|
// model
|
||||||
|
Q_PROPERTY(QString modelFile READ modelFile NOTIFY modelFileChanged)
|
||||||
|
Q_PROPERTY(QStringList modelFileList READ modelFileList CONSTANT FINAL)
|
||||||
|
|
||||||
|
// background
|
||||||
Q_PROPERTY(QString backgroundImageFile READ backgroundImageFile WRITE setBackgroundImageFile NOTIFY backgroundImageFileChanged)
|
Q_PROPERTY(QString backgroundImageFile READ backgroundImageFile WRITE setBackgroundImageFile NOTIFY backgroundImageFileChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -87,8 +91,14 @@ public:
|
|||||||
double minimumAmbientLight() const;
|
double minimumAmbientLight() const;
|
||||||
void setMinimumAmbientLight(double arg);
|
void setMinimumAmbientLight(double arg);
|
||||||
|
|
||||||
|
// model
|
||||||
QString modelFile() const;
|
QString modelFile() const;
|
||||||
void setModelFile(const QString &arg);
|
void setModelFile(const QString &arg);
|
||||||
|
QStringList modelFileList() const;
|
||||||
|
Q_INVOKABLE void nextModel();
|
||||||
|
Q_INVOKABLE void previousModel();
|
||||||
|
|
||||||
|
// background
|
||||||
QString backgroundImageFile() const;
|
QString backgroundImageFile() const;
|
||||||
void setBackgroundImageFile(const QString &arg);
|
void setBackgroundImageFile(const QString &arg);
|
||||||
|
|
||||||
@ -121,6 +131,9 @@ signals:
|
|||||||
void backgroundImageFileChanged(QString arg);
|
void backgroundImageFileChanged(QString arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// constants
|
||||||
|
static const QString CONTEXT_PROPERTY_NAME;
|
||||||
|
|
||||||
QString m_speedUnit;
|
QString m_speedUnit;
|
||||||
double m_speedFactor;
|
double m_speedFactor;
|
||||||
QString m_altitudeUnit;
|
QString m_altitudeUnit;
|
||||||
@ -138,7 +151,11 @@ private:
|
|||||||
double m_minAmbientLight;
|
double m_minAmbientLight;
|
||||||
|
|
||||||
QString m_modelFile;
|
QString m_modelFile;
|
||||||
|
int m_modelIndex;
|
||||||
|
QStringList m_modelFileList;
|
||||||
|
|
||||||
QString m_backgroundImageFile;
|
QString m_backgroundImageFile;
|
||||||
|
|
||||||
|
void addModelDir(QString dir);
|
||||||
};
|
};
|
||||||
#endif /* PFDQMLCONTEXT_H_ */
|
#endif /* PFDQMLCONTEXT_H_ */
|
||||||
|
@ -52,14 +52,10 @@ WelcomePlugin::WelcomePlugin()
|
|||||||
|
|
||||||
WelcomePlugin::~WelcomePlugin()
|
WelcomePlugin::~WelcomePlugin()
|
||||||
{
|
{
|
||||||
// The below code is commented out to avoid having the application
|
if (m_welcomeMode) {
|
||||||
// crash when it is terminated. TODO: Fix a real solution.
|
|
||||||
/*
|
|
||||||
if (m_welcomeMode) {
|
|
||||||
removeObject(m_welcomeMode);
|
removeObject(m_welcomeMode);
|
||||||
delete m_welcomeMode;
|
delete m_welcomeMode;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Initializes the plugin. Returns true on success.
|
/*! Initializes the plugin. Returns true on success.
|
||||||
|
@ -1635,7 +1635,7 @@
|
|||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
</configInfo>
|
</configInfo>
|
||||||
<data>
|
<data>
|
||||||
<qmlFile>%%DATAPATH%%qml/Pfd.qml</qmlFile>
|
<qmlFile>%%DATAPATH%%qml/PfdTerrain.qml</qmlFile>
|
||||||
<altitudeFactor>1</altitudeFactor>
|
<altitudeFactor>1</altitudeFactor>
|
||||||
<speedFactor>1</speedFactor>
|
<speedFactor>1</speedFactor>
|
||||||
<terrainEnabled>true</terrainEnabled>
|
<terrainEnabled>true</terrainEnabled>
|
||||||
@ -1659,7 +1659,7 @@
|
|||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
</configInfo>
|
</configInfo>
|
||||||
<data>
|
<data>
|
||||||
<qmlFile>%%DATAPATH%%qml/Pfd.qml</qmlFile>
|
<qmlFile>%%DATAPATH%%qml/PfdTerrain.qml</qmlFile>
|
||||||
<altitudeFactor>1</altitudeFactor>
|
<altitudeFactor>1</altitudeFactor>
|
||||||
<speedFactor>1</speedFactor>
|
<speedFactor>1</speedFactor>
|
||||||
<terrainEnabled>true</terrainEnabled>
|
<terrainEnabled>true</terrainEnabled>
|
||||||
@ -1683,7 +1683,7 @@
|
|||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
</configInfo>
|
</configInfo>
|
||||||
<data>
|
<data>
|
||||||
<qmlFile>%%DATAPATH%%qml/ModelView.qml</qmlFile>
|
<qmlFile>%%DATAPATH%%qml/Model.qml</qmlFile>
|
||||||
<altitudeFactor>1</altitudeFactor>
|
<altitudeFactor>1</altitudeFactor>
|
||||||
<speedFactor>1</speedFactor>
|
<speedFactor>1</speedFactor>
|
||||||
<terrainEnabled>false</terrainEnabled>
|
<terrainEnabled>false</terrainEnabled>
|
||||||
@ -1707,7 +1707,7 @@
|
|||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
</configInfo>
|
</configInfo>
|
||||||
<data>
|
<data>
|
||||||
<qmlFile>%%DATAPATH%%qml/ModelView.qml</qmlFile>
|
<qmlFile>%%DATAPATH%%qml/ModelTerrain.qml</qmlFile>
|
||||||
<altitudeFactor>1</altitudeFactor>
|
<altitudeFactor>1</altitudeFactor>
|
||||||
<speedFactor>1</speedFactor>
|
<speedFactor>1</speedFactor>
|
||||||
<terrainEnabled>true</terrainEnabled>
|
<terrainEnabled>true</terrainEnabled>
|
||||||
@ -1731,7 +1731,7 @@
|
|||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
</configInfo>
|
</configInfo>
|
||||||
<data>
|
<data>
|
||||||
<qmlFile>%%DATAPATH%%qml/ModelView.qml</qmlFile>
|
<qmlFile>%%DATAPATH%%qml/ModelTerrain.qml</qmlFile>
|
||||||
<altitudeFactor>1</altitudeFactor>
|
<altitudeFactor>1</altitudeFactor>
|
||||||
<speedFactor>1</speedFactor>
|
<speedFactor>1</speedFactor>
|
||||||
<terrainEnabled>true</terrainEnabled>
|
<terrainEnabled>true</terrainEnabled>
|
||||||
@ -1755,7 +1755,7 @@
|
|||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
</configInfo>
|
</configInfo>
|
||||||
<data>
|
<data>
|
||||||
<qmlFile>%%DATAPATH%%qml/EarthView.qml</qmlFile>
|
<qmlFile>%%DATAPATH%%qml/Earth.qml</qmlFile>
|
||||||
<altitudeFactor>1</altitudeFactor>
|
<altitudeFactor>1</altitudeFactor>
|
||||||
<speedFactor>1</speedFactor>
|
<speedFactor>1</speedFactor>
|
||||||
<terrainEnabled>true</terrainEnabled>
|
<terrainEnabled>true</terrainEnabled>
|
||||||
|
@ -18,22 +18,37 @@
|
|||||||
* along with LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
|
* along with LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import Pfd 1.0
|
import Pfd 1.0
|
||||||
import OsgQtQuick 1.0
|
import OsgQtQuick 1.0
|
||||||
|
|
||||||
import "common.js" as Utils
|
import "js/common.js" as Utils
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
OSGViewport {
|
OSGViewport {
|
||||||
|
id: osgViewport
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
sceneData: skyNode
|
|
||||||
|
sceneNode: skyNode
|
||||||
camera: camera
|
camera: camera
|
||||||
|
manipulator: earthManipulator
|
||||||
|
|
||||||
|
OSGCamera {
|
||||||
|
id: camera
|
||||||
|
fieldOfView: 90
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGEarthManipulator {
|
||||||
|
id: earthManipulator
|
||||||
|
}
|
||||||
|
|
||||||
OSGSkyNode {
|
OSGSkyNode {
|
||||||
id: skyNode
|
id: skyNode
|
||||||
sceneData: terrainNode
|
sceneNode: terrainNode
|
||||||
|
viewport: osgViewport
|
||||||
dateTime: Utils.getDateTime()
|
dateTime: Utils.getDateTime()
|
||||||
minimumAmbientLight: pfdContext.minimumAmbientLight
|
minimumAmbientLight: pfdContext.minimumAmbientLight
|
||||||
}
|
}
|
||||||
@ -44,11 +59,25 @@ Item {
|
|||||||
async: false
|
async: false
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGCamera {
|
}
|
||||||
id: camera
|
|
||||||
fieldOfView: 90
|
|
||||||
manipulatorMode: ManipulatorMode.Earth
|
|
||||||
}
|
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.margins: 4
|
||||||
|
|
||||||
|
running: osgViewport.busy
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.margins: 4
|
||||||
|
|
||||||
|
running: osgViewport.busy
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,10 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
Item {
|
import "model"
|
||||||
Loader {
|
|
||||||
anchors.fill: parent
|
ModelView {
|
||||||
focus: true
|
}
|
||||||
source: pfdContext.terrainEnabled ? "model/ModelTerrainView.qml" : "model/ModelView.qml"
|
|
||||||
}
|
|
||||||
}
|
|
25
ground/gcs/src/share/qml/ModelTerrain.qml
Normal file
25
ground/gcs/src/share/qml/ModelTerrain.qml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The LibrePilot Project
|
||||||
|
* Contact: http://www.librepilot.org
|
||||||
|
*
|
||||||
|
* This file is part of LibrePilot GCS.
|
||||||
|
*
|
||||||
|
* LibrePilot GCS 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.
|
||||||
|
*
|
||||||
|
* LibrePilot GCS 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 LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.4
|
||||||
|
|
||||||
|
import "model"
|
||||||
|
|
||||||
|
ModelTerrainView {
|
||||||
|
}
|
@ -19,107 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "pfd" as Pfd
|
import "pfd"
|
||||||
|
|
||||||
Rectangle {
|
PfdView {
|
||||||
color: "#515151"
|
worldFile: "PfdSimpleWorld.qml"
|
||||||
|
|
||||||
Pfd.SvgElementImage {
|
|
||||||
id: background
|
|
||||||
elementName: "pfd-window"
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: Qt.size(width, height)
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: Math.floor(parent.paintedHeight * 1.319)
|
|
||||||
height: Math.floor(parent.paintedHeight - parent.paintedHeight * 0.008)
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
border.color: "white"
|
|
||||||
border.width: Math.floor(parent.paintedHeight * 0.008)
|
|
||||||
radius: Math.floor(parent.paintedHeight * 0.01)
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: sceneItem
|
|
||||||
|
|
||||||
FontLoader {
|
|
||||||
id: pt_bold
|
|
||||||
source: "qrc:/utils/fonts/PTS75F.ttf"
|
|
||||||
}
|
|
||||||
|
|
||||||
width: Math.floor((parent.paintedHeight * 1.32) - (parent.paintedHeight * 0.013))
|
|
||||||
height: Math.floor(parent.paintedHeight - parent.paintedHeight * 0.02)
|
|
||||||
property variant viewportSize : Qt.size(width, height)
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: worldLoader
|
|
||||||
anchors.fill: parent
|
|
||||||
focus: true
|
|
||||||
source: pfdContext.terrainEnabled ? "pfd/PfdTerrainView.qml" : "pfd/PfdWorldView.qml"
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.HorizontCenter {
|
|
||||||
id: horizontCenterItem
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.RollScale {
|
|
||||||
id: rollscale
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
horizontCenter: horizontCenterItem.horizontCenter
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.SvgElementImage {
|
|
||||||
id: side_slip_fixed
|
|
||||||
elementName: "sideslip-fixed"
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
|
|
||||||
x: scaledBounds.x * sceneItem.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.Compass {
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.SpeedScale {
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.AltitudeScale {
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.VsiScale {
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
visible: pfdContext.altitudeUnit != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.Info {
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.Panels {
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfd.Warnings {
|
|
||||||
anchors.fill: parent
|
|
||||||
sceneSize: sceneItem.viewportSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
27
ground/gcs/src/share/qml/PfdTerrain.qml
Normal file
27
ground/gcs/src/share/qml/PfdTerrain.qml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The LibrePilot Project
|
||||||
|
* Contact: http://www.librepilot.org
|
||||||
|
*
|
||||||
|
* This file is part of LibrePilot GCS.
|
||||||
|
*
|
||||||
|
* LibrePilot GCS 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.
|
||||||
|
*
|
||||||
|
* LibrePilot GCS 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 LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.4
|
||||||
|
|
||||||
|
import "pfd"
|
||||||
|
|
||||||
|
PfdView {
|
||||||
|
opaque: false
|
||||||
|
worldFile: "PfdTerrainWorld.qml"
|
||||||
|
}
|
@ -28,7 +28,7 @@
|
|||||||
.import UAVTalk.VtolPathFollowerSettings 1.0 as VtolPathFollowerSettings
|
.import UAVTalk.VtolPathFollowerSettings 1.0 as VtolPathFollowerSettings
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
.import UAVTalk.HomeLocation 1.0 as HomeLocation
|
.import UAVTalk.HomeLocation 1.0 as HomeLocation
|
||||||
.import UAVTalk.TakeOffLocation 1.0 as TakeOffLocation
|
.import UAVTalk.TakeOffLocation 1.0 as TakeOffLocation
|
||||||
|
|
||||||
// Sensors
|
// Sensors
|
||||||
@ -147,7 +147,7 @@ function defaultPosition() {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function isCC3D() {
|
function isCC3D() {
|
||||||
// Hack: detect Coptercontrol with mem free
|
// Hack: detect Coptercontrol with mem free
|
||||||
return (freeMemoryBytes() < 3096);
|
return (freeMemoryBytes() < 3096);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ function gpsStatus() {
|
|||||||
return ["NO GPS", "NO FIX", "2D", "3D"][gpsPositionSensor.status];
|
return ["NO GPS", "NO FIX", "2D", "3D"][gpsPositionSensor.status];
|
||||||
}
|
}
|
||||||
|
|
||||||
function fusionAlgorithm() {
|
function fusionAlgorithm() {
|
||||||
return ["None", "Basic (No Nav)", "CompMag", "Comp+Mag+GPS", "EKFIndoor", "GPSNav (INS13)"][revoSettings.fusionAlgorithm];
|
return ["None", "Basic (No Nav)", "CompMag", "Comp+Mag+GPS", "EKFIndoor", "GPSNav (INS13)"][revoSettings.fusionAlgorithm];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ function batteryModuleEnabled() {
|
|||||||
return (hwSettings.optionalModulesBattery == HwSettings.OptionalModules.Enabled);
|
return (hwSettings.optionalModulesBattery == HwSettings.OptionalModules.Enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
function batteryNbCells() {
|
function batteryNbCells() {
|
||||||
return flightBatterySettings.nbCells;
|
return flightBatterySettings.nbCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ function batteryConsumedEnergy() {
|
|||||||
return flightBatteryState.consumedEnergy.toFixed(0);
|
return flightBatteryState.consumedEnergy.toFixed(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function estimatedFlightTimeValue() {
|
function estimatedFlightTimeValue() {
|
||||||
return Math.round(flightBatteryState.estimatedFlightTime);
|
return Math.round(flightBatteryState.estimatedFlightTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ function waypointHeading() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function homeDistance() {
|
function homeDistance() {
|
||||||
return Math.sqrt(Math.pow((takeOffLocation.east - positionState.east), 2) +
|
return Math.sqrt(Math.pow((takeOffLocation.east - positionState.east), 2) +
|
||||||
Math.pow((takeOffLocation.north - positionState.north), 2));
|
Math.pow((takeOffLocation.north - positionState.north), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,8 +377,8 @@ function isVtolPathFollowerSettingsThrustAuto() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function flightModeName() {
|
function flightModeName() {
|
||||||
return ["MANUAL", "STAB 1", "STAB 2", "STAB 3", "STAB 4", "STAB 5", "STAB 6",
|
return ["MANUAL", "STAB 1", "STAB 2", "STAB 3", "STAB 4", "STAB 5", "STAB 6",
|
||||||
"POS HOLD", "COURSELOCK", "VEL ROAM", "HOME LEASH", "ABS POS", "RTB",
|
"POS HOLD", "COURSELOCK", "VEL ROAM", "HOME LEASH", "ABS POS", "RTB",
|
||||||
"LAND", "PATHPLAN", "POI", "AUTOCRUISE", "AUTOTAKEOFF"][flightStatus.flightMode];
|
"LAND", "PATHPLAN", "POI", "AUTOCRUISE", "AUTOTAKEOFF"][flightStatus.flightMode];
|
||||||
}
|
}
|
||||||
|
|
@ -18,75 +18,105 @@
|
|||||||
* along with LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
|
* along with LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import Pfd 1.0
|
import Pfd 1.0
|
||||||
import OsgQtQuick 1.0
|
import OsgQtQuick 1.0
|
||||||
|
|
||||||
import "../common.js" as Utils
|
import "../js/common.js" as Utils
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
OSGViewport {
|
Item {
|
||||||
anchors.fill: parent
|
OSGViewport {
|
||||||
focus: true
|
id: osgViewport
|
||||||
sceneData: skyNode
|
|
||||||
camera: camera
|
|
||||||
|
|
||||||
OSGSkyNode {
|
anchors.fill: parent
|
||||||
id: skyNode
|
focus: true
|
||||||
sceneData: sceneGroup
|
|
||||||
dateTime: Utils.getDateTime()
|
|
||||||
minimumAmbientLight: pfdContext.minimumAmbientLight
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGGroup {
|
sceneNode: skyNode
|
||||||
id: sceneGroup
|
camera: camera
|
||||||
children: [ terrainNode, modelNode ]
|
manipulator: nodeTrackerManipulator
|
||||||
}
|
|
||||||
|
|
||||||
OSGFileNode {
|
OSGCamera {
|
||||||
id: terrainNode
|
id: camera
|
||||||
source: pfdContext.terrainFile
|
fieldOfView: 90
|
||||||
async: false
|
logarithmicDepthBuffer: true
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGGeoTransformNode {
|
OSGNodeTrackerManipulator {
|
||||||
id: modelNode
|
id: nodeTrackerManipulator
|
||||||
|
// use model to compute camera home position
|
||||||
|
sceneNode: modelTransformNode
|
||||||
|
// model will be tracked
|
||||||
|
trackNode: modelTransformNode
|
||||||
|
}
|
||||||
|
|
||||||
modelData: modelTransformNode
|
OSGSkyNode {
|
||||||
sceneData: terrainNode
|
id: skyNode
|
||||||
|
sceneNode: sceneGroup
|
||||||
|
viewport: osgViewport
|
||||||
|
dateTime: Utils.getDateTime()
|
||||||
|
minimumAmbientLight: pfdContext.minimumAmbientLight
|
||||||
|
}
|
||||||
|
|
||||||
clampToTerrain: true
|
OSGGroup {
|
||||||
|
id: sceneGroup
|
||||||
|
children: [ terrainFileNode, modelNode ]
|
||||||
|
}
|
||||||
|
|
||||||
position: UAV.position()
|
OSGGeoTransformNode {
|
||||||
}
|
id: modelNode
|
||||||
|
|
||||||
OSGTransformNode {
|
sceneNode: terrainFileNode
|
||||||
id: modelTransformNode
|
children: [ modelTransformNode ]
|
||||||
modelData: modelFileNode
|
|
||||||
// model dimensions are in mm, scale to meters
|
|
||||||
scale: Qt.vector3d(0.001, 0.001, 0.001)
|
|
||||||
attitude: UAV.attitude()
|
|
||||||
}
|
|
||||||
|
|
||||||
OSGFileNode {
|
clampToTerrain: true
|
||||||
id: modelFileNode
|
|
||||||
|
|
||||||
// use ShaderGen pseudoloader to generate the shaders expected by osgEarth
|
position: UAV.position()
|
||||||
// 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
|
OSGTransformNode {
|
||||||
optimizeMode: OptimizeMode.OptimizeAndCheck
|
id: modelTransformNode
|
||||||
}
|
|
||||||
|
children: [ modelFileNode ]
|
||||||
|
|
||||||
|
// model dimensions are in mm, scale to meters
|
||||||
|
scale: Qt.vector3d(0.001, 0.001, 0.001)
|
||||||
|
attitude: UAV.attitude()
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGFileNode {
|
||||||
|
id: terrainFileNode
|
||||||
|
source: pfdContext.terrainFile
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGFileNode {
|
||||||
|
id: modelFileNode
|
||||||
|
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
optimizeMode: OptimizeMode.OptimizeAndCheck
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onUpPressed: {
|
||||||
|
pfdContext.nextModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onDownPressed: {
|
||||||
|
pfdContext.previousModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.margins: 4
|
||||||
|
|
||||||
|
running: osgViewport.busy
|
||||||
|
}
|
||||||
|
|
||||||
OSGCamera {
|
|
||||||
id: camera
|
|
||||||
fieldOfView: 90
|
|
||||||
logarithmicDepthBuffer: true
|
|
||||||
manipulatorMode: ManipulatorMode.Track
|
|
||||||
// use model to compute camera home position
|
|
||||||
sceneNode: modelTransformNode
|
|
||||||
// model will be tracked
|
|
||||||
trackNode: modelTransformNode
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,32 +21,48 @@ import QtQuick 2.4
|
|||||||
|
|
||||||
import OsgQtQuick 1.0
|
import OsgQtQuick 1.0
|
||||||
|
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
||||||
OSGViewport {
|
OSGViewport {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
sceneData: sceneNode
|
|
||||||
|
sceneNode: sceneNode
|
||||||
camera: camera
|
camera: camera
|
||||||
|
manipulator: trackballManipulator
|
||||||
|
|
||||||
|
OSGCamera {
|
||||||
|
id: camera
|
||||||
|
fieldOfView: 90
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGTrackballManipulator {
|
||||||
|
id: trackballManipulator
|
||||||
|
sceneNode: transformNode
|
||||||
|
}
|
||||||
|
|
||||||
OSGGroup {
|
OSGGroup {
|
||||||
id: sceneNode
|
id: sceneNode
|
||||||
children: [
|
children: [ transformNode, backgroundNode ]
|
||||||
transformNode,
|
|
||||||
backgroundNode
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGBackgroundNode {
|
OSGBillboardNode {
|
||||||
id: backgroundNode
|
id: backgroundNode
|
||||||
|
children: [ backgroundImageNode ]
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGImageNode {
|
||||||
|
id: backgroundImageNode
|
||||||
imageFile: pfdContext.backgroundImageFile
|
imageFile: pfdContext.backgroundImageFile
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGTransformNode {
|
OSGTransformNode {
|
||||||
id: transformNode
|
id: transformNode
|
||||||
modelData: fileNode
|
|
||||||
|
children: [ fileNode ]
|
||||||
|
|
||||||
attitude: UAV.attitude()
|
attitude: UAV.attitude()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,10 +73,12 @@ Item {
|
|||||||
optimizeMode: OptimizeMode.OptimizeAndCheck
|
optimizeMode: OptimizeMode.OptimizeAndCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGCamera {
|
Keys.onUpPressed: {
|
||||||
id: camera
|
pfdContext.nextModel();
|
||||||
fieldOfView: 90
|
}
|
||||||
sceneNode: transformNode
|
|
||||||
|
Keys.onDownPressed: {
|
||||||
|
pfdContext.previousModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../common.js" as Utils
|
import "../js/common.js" as Utils
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: sceneItem
|
id: sceneItem
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: sceneItem
|
id: sceneItem
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../common.js" as Utils
|
import "../js/common.js" as Utils
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: info
|
id: info
|
||||||
@ -62,7 +62,7 @@ Item {
|
|||||||
sceneSize: info.sceneSize
|
sceneSize: info.sceneSize
|
||||||
elementName: "info-bg"
|
elementName: "info-bg"
|
||||||
width: parent.width
|
width: parent.width
|
||||||
opacity: pfdContext.terrainEnabled ? 0.3 : 1
|
opacity: opaque ? 1 : 0.3
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -452,7 +452,7 @@ Item {
|
|||||||
x: Math.floor(scaledBounds.x * sceneItem.width)
|
x: Math.floor(scaledBounds.x * sceneItem.width)
|
||||||
y: Math.floor(scaledBounds.y * sceneItem.height)
|
y: Math.floor(scaledBounds.y * sceneItem.height)
|
||||||
|
|
||||||
opacity: pfdContext.terrainEnabled ? 0.6 : 1
|
opacity: opaque ? 1 : 0.6
|
||||||
|
|
||||||
states: State {
|
states: State {
|
||||||
name: "fading"
|
name: "fading"
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
|
||||||
import "../common.js" as Utils
|
import "../js/common.js" as Utils
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: panels
|
id: panels
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: worldView
|
id: worldView
|
@ -22,50 +22,59 @@ import QtQuick 2.4
|
|||||||
import Pfd 1.0
|
import Pfd 1.0
|
||||||
import OsgQtQuick 1.0
|
import OsgQtQuick 1.0
|
||||||
|
|
||||||
import "../common.js" as Utils
|
import "../js/common.js" as Utils
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
OSGViewport {
|
OSGViewport {
|
||||||
id: fullview
|
id: osgViewport
|
||||||
|
|
||||||
//anchors.fill: parent
|
//anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
sceneData: skyNode
|
|
||||||
camera: camera
|
|
||||||
|
|
||||||
property real horizontCenter : horizontCenterItem.horizontCenter
|
readonly property real horizontCenter : horizontCenterItem.horizontCenter
|
||||||
|
|
||||||
// Factor for OSGview vertical offset
|
// Factor for OSGViewer vertical offset
|
||||||
property double factor: 0.04
|
readonly property double factor: 0.04
|
||||||
|
|
||||||
// Stretch height and apply offset
|
// Stretch height and apply offset
|
||||||
//height: height * (1 + factor)
|
//height: height * (1 + factor)
|
||||||
y: -height * factor
|
y: -height * factor
|
||||||
|
|
||||||
|
sceneNode: skyNode
|
||||||
|
camera: camera
|
||||||
|
manipulator: geoTransformManipulator
|
||||||
|
|
||||||
|
OSGCamera {
|
||||||
|
id: camera
|
||||||
|
|
||||||
|
fieldOfView: 100
|
||||||
|
logarithmicDepthBuffer: true
|
||||||
|
}
|
||||||
|
|
||||||
|
OSGGeoTransformManipulator {
|
||||||
|
id: geoTransformManipulator
|
||||||
|
|
||||||
|
sceneNode: terrainFileNode
|
||||||
|
clampToTerrain: true
|
||||||
|
|
||||||
|
attitude: UAV.attitude()
|
||||||
|
position: UAV.position()
|
||||||
|
}
|
||||||
|
|
||||||
OSGSkyNode {
|
OSGSkyNode {
|
||||||
id: skyNode
|
id: skyNode
|
||||||
sceneData: terrainNode
|
sceneNode: terrainFileNode
|
||||||
|
viewport: osgViewport
|
||||||
dateTime: Utils.getDateTime()
|
dateTime: Utils.getDateTime()
|
||||||
minimumAmbientLight: pfdContext.minimumAmbientLight
|
minimumAmbientLight: pfdContext.minimumAmbientLight
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGFileNode {
|
OSGFileNode {
|
||||||
id: terrainNode
|
id: terrainFileNode
|
||||||
source: pfdContext.terrainFile
|
source: pfdContext.terrainFile
|
||||||
async: false
|
async: false
|
||||||
}
|
}
|
||||||
|
|
||||||
OSGCamera {
|
|
||||||
id: camera
|
|
||||||
fieldOfView: 100
|
|
||||||
sceneNode: terrainNode
|
|
||||||
logarithmicDepthBuffer: true
|
|
||||||
clampToTerrain: true
|
|
||||||
manipulatorMode: ManipulatorMode.User
|
|
||||||
|
|
||||||
attitude: UAV.attitude()
|
|
||||||
position: UAV.position()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
// using rectangle instead of svg rendered to pixmap
|
// using rectangle instead of svg rendered to pixmap
|
||||||
// as it's much more memory efficient
|
// as it's much more memory efficient
|
||||||
@ -82,7 +91,6 @@ OSGViewport {
|
|||||||
|
|
||||||
property double pitch1DegHeight: sceneItem.height * pitch1DegScaledHeight
|
property double pitch1DegHeight: sceneItem.height * pitch1DegScaledHeight
|
||||||
|
|
||||||
|
|
||||||
transform: [
|
transform: [
|
||||||
Translate {
|
Translate {
|
||||||
id: pitchTranslate
|
id: pitchTranslate
|
||||||
@ -104,7 +112,7 @@ OSGViewport {
|
|||||||
property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch-window-terrain")
|
property variant scaledBounds: svgRenderer.scaledElementBounds("pfd/pfd.svg", "pitch-window-terrain")
|
||||||
|
|
||||||
x: Math.floor(scaledBounds.x * sceneItem.width)
|
x: Math.floor(scaledBounds.x * sceneItem.width)
|
||||||
y: Math.floor(scaledBounds.y * sceneItem.height) - fullview.y
|
y: Math.floor(scaledBounds.y * sceneItem.height) - osgViewport.y
|
||||||
width: Math.floor(scaledBounds.width * sceneItem.width)
|
width: Math.floor(scaledBounds.width * sceneItem.width)
|
||||||
height: Math.floor(scaledBounds.height * sceneItem.height)
|
height: Math.floor(scaledBounds.height * sceneItem.height)
|
||||||
|
|
127
ground/gcs/src/share/qml/pfd/PfdView.qml
Normal file
127
ground/gcs/src/share/qml/pfd/PfdView.qml
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The LibrePilot Project
|
||||||
|
* Contact: http://www.librepilot.org
|
||||||
|
*
|
||||||
|
* This file is part of LibrePilot GCS.
|
||||||
|
*
|
||||||
|
* LibrePilot GCS 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.
|
||||||
|
*
|
||||||
|
* LibrePilot GCS 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 LibrePilot GCS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
|
||||||
|
color: "#515151"
|
||||||
|
|
||||||
|
property string worldFile: "PfdSimpleWorld.qml"
|
||||||
|
property bool opaque: true
|
||||||
|
|
||||||
|
SvgElementImage {
|
||||||
|
id: background
|
||||||
|
elementName: "pfd-window"
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: Qt.size(width, height)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: Math.floor(parent.paintedHeight * 1.319)
|
||||||
|
height: Math.floor(parent.paintedHeight - parent.paintedHeight * 0.008)
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
border.color: "white"
|
||||||
|
border.width: Math.floor(parent.paintedHeight * 0.008)
|
||||||
|
radius: Math.floor(parent.paintedHeight * 0.01)
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: sceneItem
|
||||||
|
|
||||||
|
FontLoader {
|
||||||
|
id: pt_bold
|
||||||
|
source: "qrc:/utils/fonts/PTS75F.ttf"
|
||||||
|
}
|
||||||
|
|
||||||
|
width: Math.floor((parent.paintedHeight * 1.32) - (parent.paintedHeight * 0.013))
|
||||||
|
height: Math.floor(parent.paintedHeight - parent.paintedHeight * 0.02)
|
||||||
|
property variant viewportSize : Qt.size(width, height)
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: worldLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
focus: true
|
||||||
|
source: worldFile
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontCenter {
|
||||||
|
id: horizontCenterItem
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
RollScale {
|
||||||
|
id: rollscale
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
horizontCenter: horizontCenterItem.horizontCenter
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
SvgElementImage {
|
||||||
|
id: side_slip_fixed
|
||||||
|
elementName: "sideslip-fixed"
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
|
||||||
|
x: scaledBounds.x * sceneItem.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Compass {
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
}
|
||||||
|
|
||||||
|
SpeedScale {
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
}
|
||||||
|
|
||||||
|
AltitudeScale {
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
}
|
||||||
|
|
||||||
|
VsiScale {
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
visible: pfdContext.altitudeUnit != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Info {
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
}
|
||||||
|
|
||||||
|
Panels {
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
}
|
||||||
|
|
||||||
|
Warnings {
|
||||||
|
anchors.fill: parent
|
||||||
|
sceneSize: sceneItem.viewportSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: sceneItem
|
id: sceneItem
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: sceneItem
|
id: sceneItem
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: sceneItem
|
id: sceneItem
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
import "../common.js" as Utils
|
import "../js/common.js" as Utils
|
||||||
import "../uav.js" as UAV
|
import "../js/uav.js" as UAV
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: warnings
|
id: warnings
|
||||||
|
Loading…
Reference in New Issue
Block a user