2 ******************************************************************************
4 * @file OSGFileNode.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "OSGFileNode.hpp"
30 #include <osgDB/ReadFile>
31 #include <osgUtil/Optimizer>
34 #include <QOpenGLContext>
36 #include <QElapsedTimer>
39 namespace osgQtQuick
{
40 enum DirtyFlag
{ Source
= 1 << 0, Async
= 1 << 1, OptimizeMode
= 1 << 2 };
42 class OSGFileLoader
: public QThread
{
46 OSGFileLoader(const QUrl
&url
) : url(url
)
51 osg::Node
*node
= load();
52 emit
loaded(url
, node
);
60 // qDebug() << "OSGFileLoader::load - reading node file" << url.path();
61 // qDebug() << "OSGFileLoader - load - currentContext" << QOpenGLContext::currentContext();
62 osg::Node
*node
= osgDB::readNodeFile(url
.path().toStdString());
64 qWarning() << "OSGFileLoader::load - failed to load" << url
.path();
66 // qDebug() << "OSGFileLoader::load - reading node" << node << "took" << t.elapsed() << "ms";
71 void loaded(const QUrl
& url
, osg::Node
*node
);
77 struct OSGFileNode::Hidden
: public QObject
{
81 OSGFileNode
* const self
;
86 OptimizeMode::Enum optimizeMode
;
88 Hidden(OSGFileNode
*self
) : QObject(self
), self(self
), source(), async(false), optimizeMode(OptimizeMode::None
)
93 // qDebug() << "OSGFileNode::updateNode" << source;
94 if (!source
.isValid()) {
96 if (!source
.isEmpty()) {
97 qWarning() << "OSGFileNode::updateNode - invalid source" << source
;
100 if (false /*async*/) {
102 // it is not clear if thread safety is insured...
105 setNode(syncLoad(source
));
110 osg::Node
*syncLoad(const QUrl
&url
)
112 OSGFileLoader
loader(url
);
114 return loader
.load();
117 void asyncLoad(const QUrl
&url
)
119 OSGFileLoader
*loader
= new OSGFileLoader(url
);
121 connect(loader
, &OSGFileLoader::loaded
, this, &Hidden::onLoaded
);
122 connect(loader
, &OSGFileLoader::finished
, loader
, &OSGFileLoader::deleteLater
);
126 void setNode(osg::Node
*node
)
128 // qDebug() << "OSGFileNode::setNode" << node;
129 if (node
&& optimizeMode
!= OptimizeMode::None
) {
130 // qDebug() << "OSGFileNode::acceptNode - optimize" << node << optimizeMode;
131 osgUtil::Optimizer optimizer
;
132 optimizer
.optimize(node
, osgUtil::Optimizer::DEFAULT_OPTIMIZATIONS
);
138 void onLoaded(const QUrl
&url
, osg::Node
*node
)
140 // called in async mode
141 // question : is it thread safe to call setNode() ?
142 // could calling setDirty help? is setDirty() thread safe ?
147 /* class OSGFileNode */
149 OSGFileNode::OSGFileNode(QObject
*parent
) : Inherited(parent
), h(new Hidden(this))
152 OSGFileNode::~OSGFileNode()
157 const QUrl
OSGFileNode::source() const
162 void OSGFileNode::setSource(const QUrl
&source
)
164 if (h
->source
!= source
) {
167 emit
sourceChanged(source
);
171 bool OSGFileNode::async() const
176 void OSGFileNode::setAsync(const bool async
)
178 if (h
->async
!= async
) {
181 emit
asyncChanged(async
);
185 OptimizeMode::Enum
OSGFileNode::optimizeMode() const
187 return h
->optimizeMode
;
190 void OSGFileNode::setOptimizeMode(OptimizeMode::Enum optimizeMode
)
192 if (h
->optimizeMode
!= optimizeMode
) {
193 h
->optimizeMode
= optimizeMode
;
194 setDirty(OptimizeMode
);
195 emit
optimizeModeChanged(optimizeMode
);
199 osg::Node
*OSGFileNode::createNode()
201 // node is created later
205 void OSGFileNode::updateNode()
207 Inherited::updateNode();
209 if (isDirty(Async
)) {
212 if (isDirty(OptimizeMode
)) {
213 // TODO: trigger a node update ?
215 if (isDirty(Source
)) {
219 } // namespace osgQtQuick
221 #include "OSGFileNode.moc"