/* -*-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