/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2020 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #ifndef OSGEARTH_SCREEN_SPACE_LAYOUT_IMPL_H #define OSGEARTH_SCREEN_SPACE_LAYOUT_IMPL_H 1 #include #include #include namespace osgEarth { namespace Internal { // Sort wrapper to satisfy the template processor. struct SortContainer { SortContainer(DeclutterSortFunctor& f) : _f(f) { } const DeclutterSortFunctor& _f; bool operator()(const osgUtil::RenderLeaf* lhs, const osgUtil::RenderLeaf* rhs) const { return _f(lhs, rhs); } }; // Custom sorting functor that sorts drawables front-to-back, and when drawables share the // same parent Geode, sorts them in traversal order. struct SortFrontToBackPreservingGeodeTraversalOrder { bool operator()(const osgUtil::RenderLeaf* lhs, const osgUtil::RenderLeaf* rhs) const { if (lhs->getDrawable()->getNumParents() > 0 && rhs->getDrawable()->getNumParents() > 0 && rhs->getDrawable()->getParent(0) == lhs->getDrawable()->getParent(0)) { const osg::Group* parent = static_cast(lhs->getDrawable()->getParent(0)); return parent->getChildIndex(lhs->getDrawable()) > parent->getChildIndex(rhs->getDrawable()); } else { return (lhs->_depth < rhs->_depth); } } }; // Custom sorting functor that sorts drawables by Priority, and when drawables share the // same parent Geode, sorts them in traversal order. struct SortByPriorityPreservingGeodeTraversalOrder : public DeclutterSortFunctor { bool operator()(const osgUtil::RenderLeaf* lhs, const osgUtil::RenderLeaf* rhs) const { if (lhs->getDrawable()->getNumParents() > 0 && rhs->getDrawable()->getNumParents() > 0 && rhs->getDrawable()->getParent(0) == lhs->getDrawable()->getParent(0)) { const osg::Group* parent = static_cast(lhs->getDrawable()->getParent(0)); return parent->getChildIndex(lhs->getDrawable()) > parent->getChildIndex(rhs->getDrawable()); } else { const ScreenSpaceLayoutData* lhsdata = dynamic_cast(lhs->getDrawable()->getUserData()); float lhsPriority = lhsdata ? lhsdata->_priority : 0.0f; const ScreenSpaceLayoutData* rhsdata = dynamic_cast(rhs->getDrawable()->getUserData()); float rhsPriority = rhsdata ? rhsdata->_priority : 0.0f; float diff = lhsPriority - rhsPriority; if (diff != 0.0f) return diff > 0.0f; // first fallback on depth: diff = lhs->_depth - rhs->_depth; if (diff != 0.0f) return diff < 0.0f; // then fallback on traversal order. diff = float(lhs->_traversalOrderNumber) - float(rhs->_traversalOrderNumber); return diff < 0.0f; } } }; // Data structure shared across entire layout system. /*internal*/ struct ScreenSpaceLayoutContext : public osg::Referenced { ScreenSpaceLayoutOptions _options; bool _debug; ScreenSpaceLayoutContext() { _debug = (::getenv("OSGEARTH_DECLUTTER_DEBUG") != nullptr); } }; } } #endif