1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-21 11:54:15 +01:00

LP-29 replace OSGBackgroundNode with new OSGBillboardNode and OSGImageNode

- refactor how nodes are created
- allows deriving from OSGGroup which was needed by OSGBillboardNode
This commit is contained in:
Philippe Renon 2016-03-26 17:38:31 +01:00
parent 1f649f4327
commit 5800f17d03
25 changed files with 410 additions and 168 deletions

View File

@ -1,7 +1,7 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file OSGBackgroundNode.cpp * @file OSGBillboardNode.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015. * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @addtogroup * @addtogroup
* @{ * @{
@ -25,95 +25,69 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "OSGBackgroundNode.hpp" #include "OSGBillboardNode.hpp"
#include <osg/Depth> #include <osg/Depth>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/ImageSequence>
#include <osgDB/ReadFile> #include <osgDB/ReadFile>
#include <QUrl>
#include <QDebug> #include <QDebug>
namespace osgQtQuick { namespace osgQtQuick {
enum DirtyFlag { URL = 1 << 0 }; enum DirtyFlag {};
struct OSGBackgroundNode::Hidden : public QObject { struct OSGBillboardNode::Hidden : public QObject {
Q_OBJECT Q_OBJECT
private: private:
OSGBackgroundNode * const self; OSGBillboardNode * const self;
osg::ref_ptr<osg::Camera> camera;
public: public:
QUrl url; Hidden(OSGBillboardNode *self) : QObject(self), self(self)
Hidden(OSGBackgroundNode *self) : QObject(self), self(self), url()
{} {}
void updateURL() osg::Node *createNode()
{ {
qDebug() << "OSGBackgroundNode::updateNode - reading image file" << url.path(); camera = new osg::Camera;
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
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->setClearMask(0);
camera->setCullingActive(false); camera->setCullingActive(false);
camera->setAllowEventFocus(false); camera->setAllowEventFocus(false);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0)); camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0));
camera->addChild(geode.get());
osg::StateSet *ss = camera->getOrCreateStateSet(); osg::StateSet *ss = camera->getOrCreateStateSet();
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0)); ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0));
self->setNode(camera); return camera;
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(url.path().toStdString());
texture->setImage(image.get());
} }
}; };
/* class OSGBackgroundNode */ /* class OSGBillboardNode */
OSGBackgroundNode::OSGBackgroundNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) OSGBillboardNode::OSGBillboardNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
{} {}
OSGBackgroundNode::~OSGBackgroundNode() OSGBillboardNode::~OSGBillboardNode()
{ {
qDebug() << "OSGBackgroundNode::~OSGBackgroundNode"; qDebug() << "OSGBillboardNode::~OSGBillboardNode";
delete h; delete h;
} }
const QUrl OSGBackgroundNode::imageFile() const osg::Node *OSGBillboardNode::createNode()
{ {
return h->url; return h->createNode();
} }
void OSGBackgroundNode::setImageFile(const QUrl &url) void OSGBillboardNode::updateNode()
{ {
if (h->url != url) { Inherited::updateNode();
h->url = url;
setDirty(URL);
emit imageFileChanged(url);
}
}
void OSGBackgroundNode::update()
{
Inherited::update();
if (isDirty(URL)) {
h->updateURL();
}
} }
} // namespace osgQtQuick } // namespace osgQtQuick
#include "OSGBackgroundNode.moc" #include "OSGBillboardNode.moc"

View File

@ -0,0 +1,54 @@
/**
******************************************************************************
*
* @file OSGBillboardNode.hpp
* @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
*/
#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_

View File

@ -66,16 +66,6 @@ public:
public: public:
Hidden(OSGCamera *self) : QObject(self), self(self), fieldOfView(90), clearColor(0, 0, 0, 255), logDepthBufferEnabled(false) Hidden(OSGCamera *self) : QObject(self), self(self), fieldOfView(90), clearColor(0, 0, 0, 255), logDepthBufferEnabled(false)
{ {
// default blue osg::Vec4f(0.2f, 0.99f, 0.4f, 1.0f)
camera = new osg::Camera();
camera->setClearColor(osg::Vec4(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF()));
osg::StateSet *stateset = camera->getOrCreateStateSet();
stateset->setGlobalDefaults();
self->setNode(camera);
#ifdef USE_OSGEARTH #ifdef USE_OSGEARTH
logDepthBuffer = NULL; logDepthBuffer = NULL;
#endif #endif
@ -92,6 +82,18 @@ public:
#endif #endif
} }
osg::Node *createNode()
{
camera = new osg::Camera();
camera->setClearColor(osg::Vec4(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF()));
osg::StateSet *stateset = camera->getOrCreateStateSet();
stateset->setGlobalDefaults();
return camera;
}
void updateClearColor() void updateClearColor()
{ {
if (!camera.valid()) { if (!camera.valid()) {
@ -239,20 +241,14 @@ void OSGCamera::setLogarithmicDepthBuffer(bool enabled)
} }
} }
osg::Camera *OSGCamera::asCamera() const osg::Node *OSGCamera::createNode()
{ {
// BAD introduce templating return h->createNode();
return (osg::Camera *)node();
} }
void OSGCamera::setGraphicsContext(osg::GraphicsContext *gc) void OSGCamera::updateNode()
{ {
h->setGraphicsContext(gc); Inherited::updateNode();
}
void OSGCamera::update()
{
Inherited::update();
if (isDirty(ClearColor)) { if (isDirty(ClearColor)) {
h->updateClearColor(); h->updateClearColor();
@ -264,6 +260,17 @@ void OSGCamera::update()
h->updateLogDepthBuffer(); h->updateLogDepthBuffer();
} }
} }
osg::Camera *OSGCamera::asCamera() const
{
// BAD introduce templating
return (osg::Camera *)node();
}
void OSGCamera::setGraphicsContext(osg::GraphicsContext *gc)
{
h->setGraphicsContext(gc);
}
} // namespace osgQtQuick } // namespace osgQtQuick
#include "OSGCamera.moc" #include "OSGCamera.moc"

View File

@ -68,7 +68,8 @@ signals:
void logarithmicDepthBufferChanged(bool enabled); void logarithmicDepthBufferChanged(bool enabled);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -88,7 +88,7 @@ public:
Hidden(OSGFileNode *self) : QObject(self), self(self), 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()) {
@ -197,9 +197,15 @@ void OSGFileNode::setOptimizeMode(OptimizeMode::Enum optimizeMode)
} }
} }
void OSGFileNode::update() osg::Node *OSGFileNode::createNode()
{ {
Inherited::update(); // node is created later
return NULL;
}
void OSGFileNode::updateNode()
{
Inherited::updateNode();
if (isDirty(Async)) { if (isDirty(Async)) {
// do nothing... // do nothing...
@ -208,7 +214,7 @@ void OSGFileNode::update()
// TODO: trigger a node update ? // TODO: trigger a node update ?
} }
if (isDirty(Source)) { if (isDirty(Source)) {
h->updateNode(); h->updateSource();
} }
} }
} // namespace osgQtQuick } // namespace osgQtQuick

View File

@ -71,7 +71,8 @@ signals:
void optimizeModeChanged(OptimizeMode::Enum); void optimizeModeChanged(OptimizeMode::Enum);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -60,10 +60,13 @@ public:
QVector3D position; QVector3D position;
Hidden(OSGGeoTransformNode *self) : QObject(self), self(self), childNode(NULL), sceneNode(NULL), offset(-1.0), clampToTerrain(false), intoTerrain(false) Hidden(OSGGeoTransformNode *self) : QObject(self), self(self), childNode(NULL), 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) bool acceptChildNode(OSGNode *node)
@ -268,9 +271,14 @@ void OSGGeoTransformNode::setPosition(QVector3D arg)
} }
} }
void OSGGeoTransformNode::update() osg::Node *OSGGeoTransformNode::createNode()
{ {
Inherited::update(); return h->createNode();
}
void OSGGeoTransformNode::updateNode()
{
Inherited::updateNode();
if (isDirty(Child)) { if (isDirty(Child)) {
h->updateChildNode(); h->updateChildNode();

View File

@ -36,8 +36,7 @@
// TODO derive from OSGGroup... // TODO derive from OSGGroup...
namespace osgQtQuick { namespace osgQtQuick {
class OSGQTQUICK_EXPORT OSGGeoTransformNode : public OSGNode { class OSGQTQUICK_EXPORT OSGGeoTransformNode : public OSGNode {
Q_OBJECT Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *childNode READ childNode WRITE setChildNode NOTIFY childNodeChanged)
Q_PROPERTY(osgQtQuick::OSGNode *childNode READ childNode WRITE setChildNode NOTIFY childNodeChanged)
Q_PROPERTY(osgQtQuick::OSGNode * sceneNode READ sceneNode WRITE setSceneNode NOTIFY sceneNodeChanged) Q_PROPERTY(osgQtQuick::OSGNode * sceneNode 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)
@ -74,7 +73,8 @@ signals:
void positionChanged(QVector3D arg); void positionChanged(QVector3D arg);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -41,17 +41,17 @@ struct OSGGroup::Hidden : public QObject {
private: private:
OSGGroup * const self; OSGGroup * const self;
osg::ref_ptr<osg::Group> group;
QMap<OSGNode *, osg::Node *> cache; QMap<OSGNode *, osg::Node *> cache;
public:
QList<OSGNode *> children; QList<OSGNode *> children;
public:
Hidden(OSGGroup *self) : QObject(self), self(self) Hidden(OSGGroup *self) : QObject(self), self(self)
{}
osg::Node *createNode()
{ {
group = new osg::Group(); return new osg::Group();
self->setNode(group);
} }
void appendChild(OSGNode *childNode) void appendChild(OSGNode *childNode)
@ -86,9 +86,16 @@ public:
self->setDirty(Children); self->setDirty(Children);
} }
void updateGroupNode() void updateChildren()
{ {
qDebug() << "OSGGeoTransformNode::updateGroupNode"; 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;
@ -145,6 +152,13 @@ private slots:
void onChildNodeChanged(osg::Node *node) void onChildNodeChanged(osg::Node *node)
{ {
qDebug() << "OSGGroup::onChildNodeChanged" << node; qDebug() << "OSGGroup::onChildNodeChanged" << node;
osg::Group *group = static_cast<osg::Group *>(self->node());
if (!group) {
qWarning() << "OSGGroup::onChildNodeChanged - null group";
return;
}
OSGNode *obj = qobject_cast<OSGNode *>(sender()); OSGNode *obj = qobject_cast<OSGNode *>(sender());
if (obj) { if (obj) {
osg::Node *cacheNode = cache.value(obj, NULL); osg::Node *cacheNode = cache.value(obj, NULL);
@ -179,12 +193,17 @@ QQmlListProperty<OSGNode> OSGGroup::children() const
&Hidden::clear_child); &Hidden::clear_child);
} }
void OSGGroup::update() osg::Node *OSGGroup::createNode()
{ {
Inherited::update(); return h->createNode();
}
void OSGGroup::updateNode()
{
Inherited::updateNode();
if (isDirty(Children)) { if (isDirty(Children)) {
h->updateGroupNode(); h->updateChildren();
} }
} }
} // namespace osgQtQuick } // namespace osgQtQuick

View File

@ -48,7 +48,8 @@ public:
QQmlListProperty<OSGNode> children() const; QQmlListProperty<OSGNode> children() const;
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -0,0 +1,129 @@
/**
******************************************************************************
*
* @file OSGImageNode.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 "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()
{
qDebug() << "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"

View File

@ -1,7 +1,7 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @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) 2015.
* @addtogroup * @addtogroup
* @{ * @{
@ -25,26 +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; 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);
@ -53,7 +50,8 @@ signals:
void imageFileChanged(const QUrl &url); void imageFileChanged(const QUrl &url);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;
@ -61,4 +59,4 @@ private:
}; };
} // namespace osgQtQuick } // namespace osgQtQuick
#endif // _H_OSGQTQUICK_BACKGROUNDNODE_H_ #endif // _H_OSGQTQUICK_IMAGENODE_H_

View File

@ -59,7 +59,7 @@ public:
void update() void update()
{ {
return self->update(); return self->updateNode();
} }
bool acceptNode(osg::Node *aNode) bool acceptNode(osg::Node *aNode)
@ -119,21 +119,13 @@ void OSGNode::clearDirty()
h->clearDirty(); h->clearDirty();
} }
void OSGNode::classBegin() osg::Node *OSGNode::createNode()
{ {
// qDebug() << "OSGNode::classBegin" << this; return NULL;
} }
void OSGNode::componentComplete() void OSGNode::updateNode()
{ {}
qDebug() << "OSGNode::componentComplete" << this;
update();
clearDirty();
h->complete = true;
if (!h->node.valid()) {
qWarning() << "OSGNode::componentComplete - node is not valid!" << this;
}
}
void OSGNode::emitNodeChanged() void OSGNode::emitNodeChanged()
{ {
@ -142,8 +134,25 @@ void OSGNode::emitNodeChanged()
} }
} }
void OSGNode::update() void OSGNode::classBegin()
{} {
qDebug() << "OSGNode::classBegin" << this;
setNode(createNode());
}
void OSGNode::componentComplete()
{
qDebug() << "OSGNode::componentComplete" << this;
updateNode();
clearDirty();
h->complete = true;
if (!h->node.valid()) {
qWarning() << "OSGNode::componentComplete - node is not valid!" << this;
}
qDebug() << "OSGNode::componentComplete DONE" << this;
}
} // namespace osgQtQuick } // namespace osgQtQuick
#include "OSGNode.moc" #include "OSGNode.moc"

View File

@ -69,12 +69,13 @@ protected:
void setDirty(int mask = 0xFFFF); void setDirty(int mask = 0xFFFF);
void clearDirty(); void clearDirty();
void classBegin(); virtual osg::Node *createNode();
void componentComplete(); virtual void updateNode();
void emitNodeChanged(); void emitNodeChanged();
virtual void update(); void classBegin();
void componentComplete();
private: private:
struct Hidden; struct Hidden;

View File

@ -37,7 +37,7 @@
#include <QDebug> #include <QDebug>
namespace osgQtQuick { namespace osgQtQuick {
enum DirtyFlag { Type = 1 << 0 }; enum DirtyFlag { ShapeType = 1 << 0 };
struct OSGShapeNode::Hidden : public QObject { struct OSGShapeNode::Hidden : public QObject {
Q_OBJECT Q_OBJECT
@ -51,7 +51,7 @@ public:
Hidden(OSGShapeNode *self) : QObject(self), self(self), 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;
@ -69,18 +69,15 @@ 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 */
// TODO turn into generic shape node...
// see http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/TransformsAndStates
OSGShapeNode::OSGShapeNode(QObject *parent) : Inherited(parent), h(new Hidden(this)) OSGShapeNode::OSGShapeNode(QObject *parent) : Inherited(parent), h(new Hidden(this))
{ {
setDirty(Type); setDirty(ShapeType);
} }
OSGShapeNode::~OSGShapeNode() OSGShapeNode::~OSGShapeNode()
@ -98,17 +95,22 @@ 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()
{ {
Inherited::update(); return NULL;
}
if (isDirty(Type)) { void OSGShapeNode::updateNode()
h->updateNode(); {
Inherited::updateNode();
if (isDirty(ShapeType)) {
h->updateShapeType();
} }
} }
} // namespace osgQtQuick } // namespace osgQtQuick

View File

@ -55,7 +55,8 @@ signals:
void shapeTypeChanged(ShapeType::Enum); void shapeTypeChanged(ShapeType::Enum);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -303,9 +303,14 @@ void OSGSkyNode::setMinimumAmbientLight(double ambient)
} }
} }
void OSGSkyNode::update() osg::Node *OSGSkyNode::createNode()
{ {
Inherited::update(); return NULL;
}
void OSGSkyNode::updateNode()
{
Inherited::updateNode();
if (isDirty(Scene)) { if (isDirty(Scene)) {
h->updateSkyNode(); h->updateSkyNode();

View File

@ -82,7 +82,8 @@ signals:
void minimumAmbientLightChanged(double arg); void minimumAmbientLightChanged(double arg);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -52,23 +52,23 @@ public:
QColor color; QColor color;
Hidden(OSGTextNode *self) : QObject(self), self(self) 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()
@ -128,9 +128,14 @@ void OSGTextNode::setColor(const QColor &color)
} }
} }
void OSGTextNode::update() osg::Node *OSGTextNode::createNode()
{ {
Inherited::update(); return h->createNode();
}
void OSGTextNode::updateNode()
{
Inherited::updateNode();
if (isDirty(Text)) { if (isDirty(Text)) {
h->updateText(); h->updateText();

View File

@ -55,7 +55,8 @@ signals:
void colorChanged(const QColor &color); void colorChanged(const QColor &color);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -52,9 +52,12 @@ public:
QVector3D position; QVector3D position;
Hidden(OSGTransformNode *self) : QObject(self), self(self), childNode(NULL) Hidden(OSGTransformNode *self) : QObject(self), self(self), childNode(NULL)
{}
osg::Node *createNode()
{ {
transform = new osg::PositionAttitudeTransform(); transform = new osg::PositionAttitudeTransform();
self->setNode(transform); return transform;
} }
bool acceptChildNode(OSGNode *node) bool acceptChildNode(OSGNode *node)
@ -202,9 +205,14 @@ void OSGTransformNode::setPosition(QVector3D arg)
} }
} }
void OSGTransformNode::update() osg::Node *OSGTransformNode::createNode()
{ {
Inherited::update(); return h->createNode();
}
void OSGTransformNode::updateNode()
{
Inherited::updateNode();
if (isDirty(Child)) { if (isDirty(Child)) {
h->updateChildNode(); h->updateChildNode();

View File

@ -36,8 +36,7 @@
// TODO derive from OSGGroup... // TODO derive from OSGGroup...
namespace osgQtQuick { namespace osgQtQuick {
class OSGQTQUICK_EXPORT OSGTransformNode : public OSGNode { class OSGQTQUICK_EXPORT OSGTransformNode : public OSGNode {
Q_OBJECT Q_OBJECT Q_PROPERTY(osgQtQuick::OSGNode *childNode READ childNode WRITE setChildNode NOTIFY childNodeChanged)
Q_PROPERTY(osgQtQuick::OSGNode *childNode READ childNode WRITE setChildNode NOTIFY childNodeChanged)
Q_PROPERTY(QVector3D scale READ scale WRITE setScale NOTIFY scaleChanged) 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)
@ -68,7 +67,8 @@ signals:
void positionChanged(QVector3D arg); void positionChanged(QVector3D arg);
protected: protected:
virtual void update(); virtual osg::Node *createNode();
virtual void updateNode();
private: private:
struct Hidden; struct Hidden;

View File

@ -53,9 +53,10 @@ HEADERS += \
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
@ -65,9 +66,10 @@ SOURCES += \
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

View File

@ -33,8 +33,9 @@
#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"
@ -534,28 +535,34 @@ 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");
// camera manipulators
qmlRegisterType<osgQtQuick::OSGCameraManipulator>("OsgQtQuick", maj, min, "OSGCameraManipulator"); qmlRegisterType<osgQtQuick::OSGCameraManipulator>("OsgQtQuick", maj, min, "OSGCameraManipulator");
qmlRegisterType<osgQtQuick::OSGNodeTrackerManipulator>("OsgQtQuick", maj, min, "OSGNodeTrackerManipulator"); qmlRegisterType<osgQtQuick::OSGNodeTrackerManipulator>("OsgQtQuick", maj, min, "OSGNodeTrackerManipulator");
qmlRegisterType<osgQtQuick::TrackerMode>("OsgQtQuick", maj, min, "TrackerMode"); qmlRegisterType<osgQtQuick::TrackerMode>("OsgQtQuick", maj, min, "TrackerMode");

View File

@ -45,14 +45,16 @@ Item {
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
} }