From: Stuart Buchanan Date: Thu, 29 Oct 2015 20:07:12 +0000 (+0000) Subject: Use quadtree to improve culling of STG objects X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=08fb4339236536be2a31768d03d9826d1491437d;p=simgear.git Use quadtree to improve culling of STG objects --- diff --git a/simgear/scene/tgdb/ReaderWriterSTG.cxx b/simgear/scene/tgdb/ReaderWriterSTG.cxx index 30e15fb0..97216ec8 100644 --- a/simgear/scene/tgdb/ReaderWriterSTG.cxx +++ b/simgear/scene/tgdb/ReaderWriterSTG.cxx @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -113,48 +114,73 @@ struct ReaderWriterSTG::_ModelBin { }; class DelayLoadReadFileCallback : public OptionsReadFileCallback { + + private: + // QuadTreeBuilder for structuring static objects + struct MakeQuadLeaf { + osg::LOD* operator() () const { return new osg::LOD; } + }; + struct AddModelLOD { + void operator() (osg::LOD* leaf, _ObjectStatic o) const + { + osg::ref_ptr node; + if (o._proxy) { + osg::ref_ptr proxy = new osg::ProxyNode; + proxy->setName("proxyNode"); + proxy->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER); + proxy->setFileName(0, o._name); + proxy->setDatabaseOptions(o._options.get()); + node = proxy; + } else { + node = osgDB::readRefNodeFile(o._name, o._options.get()); + if (!node.valid()) { + SG_LOG(SG_TERRAIN, SG_ALERT, o._errorLocation << ": Failed to load " + << o._token << " '" << o._name << "'"); + return; + } + } + if (SGPath(o._name).lower_extension() == "ac") + node->setNodeMask(~simgear::MODELLIGHT_BIT); + + osg::Matrix matrix; + matrix = makeZUpFrame(SGGeod::fromDegM(o._lon, o._lat, o._elev)); + matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(o._hdg), osg::Vec3(0, 0, 1))); + matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(o._pitch), osg::Vec3(0, 1, 0))); + matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(o._roll), osg::Vec3(1, 0, 0))); + + osg::MatrixTransform* matrixTransform; + matrixTransform = new osg::MatrixTransform(matrix); + matrixTransform->setName("rotateStaticObject"); + matrixTransform->setDataVariance(osg::Object::STATIC); + matrixTransform->addChild(node.get()); + leaf->addChild(matrixTransform, 0, 20000); //TODO: Make configurable? + } + }; + struct GetModelLODCoord { + GetModelLODCoord() {} + GetModelLODCoord(const GetModelLODCoord& rhs) + {} + osg::Vec3 operator() (const _ObjectStatic& o) const + { + SGVec3d coord; + SGGeodesy::SGGeodToCart(SGGeod::fromDegM(o._lon, o._lat, o._elev), coord); + return toOsg(coord); + } + }; + typedef QuadTreeBuilder STGObjectsQuadtree; + + public: virtual osgDB::ReaderWriter::ReadResult readNode(const std::string&, const osgDB::Options*) { - osg::ref_ptr group = new osg::Group; + STGObjectsQuadtree quadtree((GetModelLODCoord()), (AddModelLOD())); + quadtree.buildQuadTree(_objectStaticList.begin(), _objectStaticList.end()); + osg::ref_ptr group = quadtree.getRoot(); group->setName("STG-group-A"); group->setDataVariance(osg::Object::STATIC); - - for (std::list<_ObjectStatic>::iterator i = _objectStaticList.begin(); i != _objectStaticList.end(); ++i) { - osg::ref_ptr node; - if (i->_proxy) { - osg::ref_ptr proxy = new osg::ProxyNode; - proxy->setName("proxyNode"); - proxy->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER); - proxy->setFileName(0, i->_name); - proxy->setDatabaseOptions(i->_options.get()); - node = proxy; - } else { - node = osgDB::readRefNodeFile(i->_name, i->_options.get()); - if (!node.valid()) { - SG_LOG(SG_TERRAIN, SG_ALERT, i->_errorLocation << ": Failed to load " - << i->_token << " '" << i->_name << "'"); - continue; - } - } - if (SGPath(i->_name).lower_extension() == "ac") - node->setNodeMask(~simgear::MODELLIGHT_BIT); - - osg::Matrix matrix; - matrix = makeZUpFrame(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev)); - matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_hdg), osg::Vec3(0, 0, 1))); - matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_pitch), osg::Vec3(0, 1, 0))); - matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_roll), osg::Vec3(1, 0, 0))); - - osg::MatrixTransform* matrixTransform; - matrixTransform = new osg::MatrixTransform(matrix); - matrixTransform->setName("positionStaticObject"); - matrixTransform->setDataVariance(osg::Object::STATIC); - matrixTransform->addChild(node.get()); - group->addChild(matrixTransform); - } - + simgear::AirportSignBuilder signBuilder(_options->getMaterialLib(), _bucket.get_center()); for (std::list<_Sign>::iterator i = _signList.begin(); i != _signList.end(); ++i) signBuilder.addSign(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev), i->_hdg, i->_name, i->_size);