find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
find_package(ALUT REQUIRED)
- find_package(OpenSceneGraph 2.8.1 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
+ find_package(OpenSceneGraph 3.0.0 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
endif(SIMGEAR_HEADLESS)
if(JPEG_FACTORY)
RelativePath="..\..\simgear\scene\model\SGOffsetTransform.hxx"\r
>\r
</File>\r
- <File\r
- RelativePath="..\..\simgear\scene\model\SGPagedLOD.cxx"\r
- >\r
- </File>\r
- <File\r
- RelativePath="..\..\simgear\scene\model\SGPagedLOD.hxx"\r
- >\r
- </File>\r
<File\r
RelativePath="..\..\simgear\scene\model\SGReaderWriterXML.cxx"\r
>\r
SGInteractionAnimation.hxx
SGMaterialAnimation.hxx
SGOffsetTransform.hxx
- SGPagedLOD.hxx
SGReaderWriterXML.hxx
SGReaderWriterXMLOptions.hxx
SGRotateTransform.hxx
SGInteractionAnimation.cxx
SGMaterialAnimation.cxx
SGOffsetTransform.cxx
- SGPagedLOD.cxx
SGReaderWriterXML.cxx
SGRotateTransform.cxx
SGScaleTransform.cxx
// Copyright (C) 2008 Till Busch buti@bux.at
+// Copyright (C) 2011 Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
#endif
#include <osg/Transform>
+#include <osg/ProxyNode>
+#include <osgDB/DatabasePager>
#include <simgear/debug/logstream.hxx>
#include "CheckSceneryVisitor.hxx"
-#include "SGPagedLOD.hxx"
#include <simgear/math/SGMath.hxx>
osg::FrameStamp* framestamp)
:osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR,
osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
-_position(position), _range(range), _loaded(true), _dbp(dbp), _framestamp(framestamp)
+ _position(position), _range(range), _loaded(true), _matrix(osg::Matrix::identity())
{
- _viewMatrices.push_back(osg::Matrix::identity());
+ setDatabaseRequestHandler(dbp);
+ setFrameStamp(framestamp);
}
void CheckSceneryVisitor::apply(osg::Node& node)
traverse(node);
}
-void CheckSceneryVisitor::apply(osg::PagedLOD& node)
+void CheckSceneryVisitor::apply(osg::ProxyNode& node)
{
- SGPagedLOD *sgplod = dynamic_cast<SGPagedLOD*>(&node);
- if (sgplod) {
- osg::Vec3 pos = sgplod->getCenter() * _viewMatrices.back();
- double dist = (pos-_position).length();
- if (dist < _range) {
- if (sgplod->getNumChildren() < 1) {
- // if the DatabasePager would load LODs while the splashscreen
- // is there, we could just wait for the models to be loaded
- // by only setting setLoaded(false) here
- sgplod->forceLoad(_dbp,_framestamp, getNodePath());
- setLoaded(false);
- }
+ osg::Vec3 pos = node.getCenter() * _matrix;
+ double dist = (pos - _position).length();
+ if (dist < _range) {
+ for (unsigned i = 0; i < node.getNumFileNames(); ++i) {
+ if (node.getFileName(i).empty())
+ continue;
+ // Check if this is already loaded.
+ if (i < node.getNumChildren() && node.getChild(i))
+ continue;
+
+ // if the DatabasePager would load LODs while the splashscreen
+ // is there, we could just wait for the models to be loaded
+ // by only setting setLoaded(false) here
+ osg::NodePath nodePath = getNodePath();
+ DatabaseRequestHandler* db = getDatabaseRequestHandler();
+ const osg::FrameStamp* fs = getFrameStamp();
+ db->requestNodeFile(node.getFileName(i), nodePath, 1.0 /*priority*/, fs,
+ node.getDatabaseRequest(i), node.getDatabaseOptions());
+ setLoaded(false);
}
}
traverse(node);
}
-void CheckSceneryVisitor::apply(osg::Transform &node)
+void CheckSceneryVisitor::apply(osg::PagedLOD& node)
{
- osg::Matrix currMatrix = _viewMatrices.back();
- bool pushMatrix = node.computeLocalToWorldMatrix(currMatrix, this);
+ osg::Vec3 pos = node.getCenter() * _matrix;
+ double dist = (pos - _position).length();
+ if (dist < _range) {
+ for (unsigned i = 0; i < node.getNumFileNames(); ++i) {
+ if (node.getFileName(i).empty())
+ continue;
+ // Check if this is already loaded.
+ if (i < node.getNumChildren() && node.getChild(i))
+ continue;
- if (pushMatrix) {
- _viewMatrices.push_back(currMatrix);
+ // if the DatabasePager would load LODs while the splashscreen
+ // is there, we could just wait for the models to be loaded
+ // by only setting setLoaded(false) here
+ osg::NodePath nodePath = getNodePath();
+ DatabaseRequestHandler* db = getDatabaseRequestHandler();
+ const osg::FrameStamp* fs = getFrameStamp();
+ db->requestNodeFile(node.getFileName(i), nodePath, 1.0 /*priority*/, fs,
+ node.getDatabaseRequest(i), node.getDatabaseOptions());
+ setLoaded(false);
+ }
}
traverse(node);
- if (pushMatrix) {
- _viewMatrices.pop_back();
- }
+}
+
+void CheckSceneryVisitor::apply(osg::Transform &node)
+{
+ osg::Matrix matrix = _matrix;
+ node.computeLocalToWorldMatrix(_matrix, this);
+ traverse(node);
+ _matrix = matrix;
}
// Copyright (C) 2008 Till Busch buti@bux.at
+// Copyright (C) 2011 Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
#define CHECKSCENERYVISITOR_HXX
#include <osg/NodeVisitor>
-#include <osg/fast_back_stack>
namespace osgDB {
class DatabasePager;
namespace simgear
{
-class SGPagedLOD;
-
-// Checks the scene graph for SGPagedLODs that are within range
+// Checks the scene graph for PagedLOD or ProxyNodes that are within range
// (compared to postion) and injects them into the DatabasePager.
// After visiting, isLoaded() returns true if all models in range
// are available.
CheckSceneryVisitor(osgDB::DatabasePager* dbp, const osg::Vec3 &position, double range, osg::FrameStamp* framestamp);
virtual void apply(osg::Node& node);
+ virtual void apply(osg::ProxyNode& node);
virtual void apply(osg::PagedLOD& node);
virtual void apply(osg::Transform& node);
osg::Vec3 _position;
double _range;
bool _loaded;
- osgDB::DatabasePager* _dbp;
- osg::FrameStamp* _framestamp;
-
- osg::fast_back_stack<osg::Matrix> _viewMatrices;
+ osg::Matrix _matrix;
};
}
+++ /dev/null
-// Copyright (C) 2008 Till Busch buti@bux.at
-//
-// 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 2 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-#ifdef HAVE_CONFIG_H
-# include <simgear_config.h>
-#endif
-
-#include <osgDB/ReadFile>
-#include <osgDB/Input>
-#include <osgDB/ParameterOutput>
-#include <osgDB/DatabasePager>
-
-#include <simgear/debug/logstream.hxx>
-#include <simgear/structure/OSGVersion.hxx>
-
-#include "modellib.hxx"
-#include "SGReaderWriterXMLOptions.hxx"
-#include "SGPagedLOD.hxx"
-
-#include <simgear/math/SGMath.hxx>
-
-using namespace osg;
-using namespace simgear;
-
-bool SGPagedLOD::_cache = true;
-
-SGPagedLOD::SGPagedLOD()
- : PagedLOD()
-{
-}
-
-SGPagedLOD::~SGPagedLOD()
-{
- //SG_LOG(SG_GENERAL, SG_ALERT, "SGPagedLOD::~SGPagedLOD(" << getFileName(0) << ")");
-}
-
-SGPagedLOD::SGPagedLOD(const SGPagedLOD& plod,const CopyOp& copyop)
- : osg::PagedLOD(plod, copyop)
-#if !SG_PAGEDLOD_HAS_OPTIONS
- , _readerWriterOptions(plod._readerWriterOptions)
-#endif
-{
-}
-
-void
-SGPagedLOD::setReaderWriterOptions(osgDB::ReaderWriter::Options *options)
-{
- if (_cache)
- options->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
- else
- options->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_NONE);
-#if SG_PAGEDLOD_HAS_OPTIONS
- setDatabaseOptions(options);
-#else
- _readerWriterOptions = options;
-#endif
-}
-
-bool SGPagedLOD::addChild(osg::Node *child)
-{
- if (!PagedLOD::addChild(child))
- return false;
-
- setRadius(getBound().radius());
- setCenter(getBound().center());
- return true;
-}
-
-// Work around interface change in osgDB::DatabasePager::requestNodeFile
-struct NodePathProxy
-{
- NodePathProxy(NodePath& nodePath)
- : _nodePath(nodePath)
- {
- }
- operator Group* () { return static_cast<Group*>(_nodePath.back()); }
- operator NodePath& () { return _nodePath; }
- NodePath& _nodePath;
-};
-
-void SGPagedLOD::forceLoad(osgDB::DatabasePager *dbp, FrameStamp* framestamp,
- NodePath& path)
-{
- //SG_LOG(SG_GENERAL, SG_ALERT, "SGPagedLOD::forceLoad(" <<
- //getFileName(getNumChildren()) << ")");
- unsigned childNum = getNumChildren();
- setTimeStamp(childNum, 0);
- double priority=1.0;
- dbp->requestNodeFile(getFileName(childNum), NodePathProxy(path),
- priority, framestamp,
- getDatabaseRequest(childNum),
- getReaderWriterOptions());
-}
-
-bool SGPagedLOD_writeLocalData(const Object& obj, osgDB::Output& fw)
-{
- return true;
-}
-
-namespace
-{
-osgDB::RegisterDotOsgWrapperProxy sgPagedLODProxy
-(
- new SGPagedLOD,
- "simgear::SGPagedLOD",
- "Object Node LOD PagedLOD SGPagedLOD Group",
- 0,
- &SGPagedLOD_writeLocalData
- );
-}
+++ /dev/null
-// Copyright (C) 2008 Till Busch buti@bux.at
-//
-// 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 2 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-#ifndef SGPAGEDLOD_HXX
-#define SGPAGEDLOD_HXX 1
-
-#include <simgear/structure/OSGVersion.hxx>
-
-#define SG_PAGEDLOD_HAS_OPTIONS \
- (SG_OSG_VERSION >= 29005)
-
-#include <osg/PagedLOD>
-#include <osgDB/Registry>
-#include <osgDB/ReaderWriter>
-#include <simgear/props/props.hxx>
-
-namespace osgDB {
-class DatabasePager;
-}
-
-
-namespace simgear
-{
-
-class SGPagedLOD : public osg::PagedLOD
-{
-public:
- SGPagedLOD();
-
- SGPagedLOD(const SGPagedLOD&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
-
- META_Node(simgear, SGPagedLOD);
-
- // virtual void traverse(osg::NodeVisitor& nv);
- virtual void forceLoad(osgDB::DatabasePager* dbp,
- osg::FrameStamp* framestamp,
- osg::NodePath& path);
-
- // reimplemented to notify the loading through ModelData
- bool addChild(osg::Node *child);
-
- void setReaderWriterOptions(osgDB::ReaderWriter::Options *options);
-
- osgDB::ReaderWriter::Options* getReaderWriterOptions() {
-#if SG_PAGEDLOD_HAS_OPTIONS
- return static_cast<osgDB::ReaderWriter::Options*>(getDatabaseOptions());
-#else
- return _readerWriterOptions.get();
-#endif
- }
-
- static void setRenderingCache(bool cache) {_cache = cache;}
-protected:
- virtual ~SGPagedLOD();
-#if !SG_PAGEDLOD_HAS_OPTIONS
- osg::ref_ptr<osgDB::ReaderWriter::Options> _readerWriterOptions;
-#endif
-private:
- static bool _cache;
-};
-}
-#endif
#include <simgear/scene/util/SGNodeMasks.hxx>
#include "modellib.hxx"
-#include "SGPagedLOD.hxx"
#include "SGReaderWriterXML.hxx"
#include "SGReaderWriterXMLOptions.hxx"
#include <boost/algorithm/string.hpp>
+#include <osg/PagedLOD>
+#include <osg/ProxyNode>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>
#include <simgear/scene/model/ModelRegistry.hxx>
#include <simgear/misc/ResourceManager.hxx>
-#include "SGPagedLOD.hxx"
#include "SGReaderWriterXML.hxx"
#include "SGReaderWriterXMLOptions.hxx"
{
osgDB::Registry::instance()->getDataFilePathList().push_front(root_dir);
static_propRoot = root;
- SGPagedLOD::setRenderingCache(root->getBoolValue("/sim/rendering/cache",true));
}
void SGModelLib::setPanelFunc(panel_func pf)
}
+osg::Node*
+SGModelLib::loadDeferedModel(const string &path, SGPropertyNode *prop_root,
+ SGModelData *data)
+{
+ osg::ProxyNode* proxyNode = new osg::ProxyNode;
+ proxyNode->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
+ proxyNode->setFileName(0, path);
+
+ osg::ref_ptr<SGReaderWriterXMLOptions> opt
+ = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()
+ ->getOptions()));
+ opt->setPropRoot(prop_root ? prop_root: static_propRoot.get());
+ opt->setModelData(data);
+ opt->setLoadPanel(static_panelFunc);
+ if (SGPath(path).lower_extension() == "ac")
+ opt->setInstantiateEffects(true);
+ if (!prop_root || prop_root->getBoolValue("/sim/rendering/cache", true))
+ opt->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
+ else
+ opt->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_NONE);
+ proxyNode->setDatabaseOptions(opt.get());
+
+ return proxyNode;
+}
+
osg::Node*
SGModelLib::loadPagedModel(const string &path, SGPropertyNode *prop_root,
SGModelData *data)
{
- SGPagedLOD *plod = new SGPagedLOD;
+ osg::PagedLOD *plod = new osg::PagedLOD;
plod->setName("Paged LOD for \"" + path + "\"");
plod->setFileName(0, path);
plod->setRange(0, 0.0, 50.0*SG_NM_TO_METER);
opt->setPropRoot(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data);
opt->setLoadPanel(static_panelFunc);
- if (boost::iends_with(path, ".ac"))
+ if (SGPath(path).lower_extension() == "ac")
opt->setInstantiateEffects(true);
- plod->setReaderWriterOptions(opt.get());
+ if (!prop_root || prop_root->getBoolValue("/sim/rendering/cache", true))
+ opt->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
+ else
+ opt->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_NONE);
+ plod->setDatabaseOptions(opt.get());
return plod;
}
SGModelData *data=0, bool load2DPanels=false);
// Load a 3D model (any format) through the DatabasePager.
- // Most models should be loaded using this function!
- // This function will initially return an SGPagedLOD node.
- // data->modelLoaded() will be called after the model is loaded and
- // connected to the scene graph. See AIModelData on how to use this.
- // NOTE: AIModelData uses observer_ptr to avoid circular references.
+ // This function initially just returns a proxy node that refers to
+ // the model file. Once the viewer steps onto that node the
+ // model will be loaded.
+ static osg::Node* loadDeferedModel(const std::string &path,
+ SGPropertyNode *prop_root = NULL,
+ SGModelData *data=0);
+ // Load a 3D model (any format) through the DatabasePager.
+ // This function initially just returns a PagedLOD node that refers to
+ // the model file. Once the viewer steps onto that node the
+ // model will be loaded. When the viewer does no longer reference this
+ // node for a long time the node is unloaded again.
static osg::Node* loadPagedModel(const std::string &path,
SGPropertyNode *prop_root = NULL,
SGModelData *data=0);