Bounding box as selection box does not show

classic Classic list List threaded Threaded
1 message Options
bclay bclay
Reply | Threaded
Open this post in threaded view
|

Bounding box as selection box does not show

I am trying to use the code shown below as a means of object or region selection.  The code was adapted from the osgEarth source file applications/osgEarth_package_qt/SceneController.cpp.  The code does get what seems to be a valid selection / bounding box but the box is not visible while it is being drawn.  Other objects drawn in the same group osg::group do show up.

Any ideas as to how to see the box while it is drawn would be appreciated.

Bruce

/////////////////////////////////////////////////////////////////////////////////////
#include "BoundingBox.h"

#include <osgEarth/Common>
#include <osgEarth/Map>
#include <osgEarth/MapNode>
#include <osgEarthAnnotation/FeatureNode>
#include <osgEarthUtil/Controls>
#include <osgEarthUtil/ExampleResources>

struct BoundingBoxMouseHandler : public osgGA::GUIEventHandler
  {
    BoundingBoxMouseHandler(BoundingBox *controller, osgEarth::MapNode *mapNode,
                bool startCapture=false)
      : _controller(controller),  _mouseDown(false), _capturing(startCapture)
    {
                mMapNode = mapNode;
    }

    void startCapture()
    {
      _capturing = true;
    }

    void stopCapture()
    {
      _capturing = false;
    }

    bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
    {
      if (!_capturing )
        return false;

      osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());

      if ( ea.getEventType() == osgGA::GUIEventAdapter::PUSH  && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
      {
        osg::Vec3d world;
        if (mMapNode->getTerrain()->getWorldCoordsUnderMouse(aa.asView(), ea.getX(), ea.getY(), world))
        {
          osgEarth::GeoPoint mapPoint;
          mapPoint.fromWorld( mMapNode->getMapSRS(), world );
          _startPoint = mapPoint;
        }

//        std::cout << "BBox DOWN" << std::endl;

        _mouseDown = true;

        ea.setHandled(true);
        return true;
      }
      else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG && _mouseDown)
      {
        osg::Vec3d world;
        if ( mMapNode->getTerrain()->getWorldCoordsUnderMouse(aa.asView(), ea.getX(), ea.getY(), world))
        {
          osgEarth::GeoPoint mapPoint;
          mapPoint.fromWorld( mMapNode->getMapSRS(), world );
          _controller->setBounds(_startPoint, mapPoint);
        }

//        std::cout << "BBox MOVE" << std::endl;

        ea.setHandled(true);
        return true;
      }
      else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON && _mouseDown)
      {
        _mouseDown = false;
        _capturing = false;
        _controller->endBoundsCapture();

//        std::cout << "BBox UP" << std::endl;

        ea.setHandled(true);
        return true;
      }

      return false;
    }

        BoundingBox *_controller;
     osg::ref_ptr<osgEarth::MapNode> mMapNode;
    bool _capturing;
    bool _mouseDown;
    osgEarth::GeoPoint _startPoint;
  };


BoundingBox::BoundingBox(osg::Group* root, osgViewer::View* view, osgEarth::MapNode *mapNode)
: _root(root), _view(view)
{
        mMapNode = mapNode;
        _annoRoot = root;

  //Setup bounding box style
        osgEarth::Symbology::LineSymbol* ls = _boundsStyle.getOrCreate<osgEarth::Symbology::LineSymbol>();
        ls->stroke()->color() = osgEarth::Symbology::Color::Red;
        ls->stroke()->width() = 3.0f;
        ls->stroke()->stipple() = 0xCCCC;
        ls->tessellation() = 20;

        _boundsStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>()->clamping() = osgEarth::Symbology::AltitudeSymbol::CLAMP_TO_TERRAIN;
        _boundsStyle.getOrCreate<osgEarth::Symbology::AltitudeSymbol>()->technique() = osgEarth::Symbology::AltitudeSymbol::TECHNIQUE_GPU;

}


void BoundingBox::captureBounds(BoundsSetCallback* callback)
{
  _boundsCallback = callback;

  if (!_guiHandler.valid())
  {
    _guiHandler = new BoundingBoxMouseHandler(this, mMapNode, true);
    _view->addEventHandler(_guiHandler.get());
  }
  else
  {
    dynamic_cast<BoundingBoxMouseHandler *>(_guiHandler.get())->startCapture();
  }
}

void BoundingBox::endBoundsCapture()
{
  if (_guiHandler.valid())
    dynamic_cast<BoundingBoxMouseHandler *>(_guiHandler.get())->stopCapture();

  if (_boundsCallback.valid())
    _boundsCallback->boundsSet(_boundsLL, _boundsUR);
}

void BoundingBox::clearBounds()
{
  if (_bboxNode.valid())
  {
    _annoRoot->removeChild(_bboxNode.get());
    _bboxNode = 0L;
  }

  _boundsLL.set(0., 0.);
  _boundsUR.set(0., 0.);
}

void BoundingBox::setBounds(const osgEarth::GeoPoint& p1, const osgEarth::GeoPoint& p2)
{
  _boundsLL.set(osg::minimum(p1.x(), p2.x()), osg::minimum(p1.y(), p2.y()));
  _boundsUR.set(osg::maximum(p1.x(), p2.x()), osg::maximum(p1.y(), p2.y()));

  if (_annoRoot.valid())
  {
    //TODO: use correct coords here
    osgEarth::Symbology::Geometry* geom = new osgEarth::Symbology::Polygon();
    geom->push_back(_boundsLL.x(), _boundsLL.y());
    geom->push_back(_boundsUR.x(), _boundsLL.y());
    geom->push_back(_boundsUR.x(), _boundsUR.y());
    geom->push_back(_boundsLL.x(), _boundsUR.y());

    osgEarth::Features::Feature* feature = new osgEarth::Features::Feature(geom, mMapNode->getMapSRS()->getGeographicSRS(), _boundsStyle);

    if (!_bboxNode.valid())
    {
      _bboxNode = new osgEarth::Annotation::FeatureNode(mMapNode, feature);
      _bboxNode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

          _bboxNode->setNodeMask(1);

      _annoRoot->addChild( _bboxNode.get() );
    }
    else
    {
                _bboxNode->setNodeMask(1);
                feature->setNodeMask(1);

      _bboxNode->setFeature(feature);
    }
  }
}