bool TimerHandler::handle( const osgGA::GUIEventAdapter& ea,
		                       osgGA::GUIActionAdapter& aa )
{
	
	switch ( ea.getEventType())
	{
	case osgGA::GUIEventAdapter::FRAME:
		//std::cout << "MouseButton mask: " << ea.getButtonMask() << std::endl;
		if(ea.getButtonMask() == 0)
			Constants::getInstance()->mouseDown = false;
		else if (ea.getButtonMask() & 2)
			Constants::getInstance()->mouseDown = true;
		float x = ea.getX();
		float y = ea.getY();
		//std::cout << "X:  " << x << std::endl;
		//std::cout << "Y:  " << y << std::endl;
		if(Constants::getInstance()->mouseDown == false && Constants::getInstance()->disableMouse == false && ScriptRunner::getInstance()->isRunning == false) gameRender->updateDirection(x, y);
		gameRender->updateGamePlay();
		_count++;
		break;
	}

	return false;



}
示例#2
0
bool Vwr::CameraManipulator::handlePush(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
	if (ea.getButtonMask() == GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
	{
		if (_distance != 0)
		{
			lastDistance = _distance;

			osg::Vec3d eye, cameraCenter, up;

			osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>( &us );
			viewer->getCamera()->getViewMatrixAsLookAt(eye, cameraCenter, up);

			_center = eye;
			_distance = 0;
		}
		else
		{
			_distance = lastDistance;
		}

		return true;
	}
	else
	{
		flushMouseEventStack();
		addMouseEvent(ea);
		if (calcMovement()) us.requestRedraw();
		us.requestContinuousUpdate(false);
		_thrown = false;
		return true;
	}
}
bool Vwr::CameraManipulator::handleRelease(const osgGA::GUIEventAdapter& ea,
		osgGA::GUIActionAdapter& us) {
	if (ea.getButtonMask() == 0) {

		double timeSinceLastRecordEvent = _ga_t0.valid() ? (ea.getTime()
				- _ga_t0->getTime()) : DBL_MAX;
		if (timeSinceLastRecordEvent > 0.02)
			flushMouseEventStack();

		if (isMouseMoving()) {
			if (calcMovement()) {
				us.requestRedraw();
				us.requestContinuousUpdate(true);
				_thrown = _allowThrow;
			}
		} else {
			flushMouseEventStack();
			addMouseEvent(ea);
			if (calcMovement())
				us.requestRedraw();
			us.requestContinuousUpdate(false);
			_thrown = false;
		}

	} else {
		flushMouseEventStack();
		addMouseEvent(ea);
		if (calcMovement())
			us.requestRedraw();
		us.requestContinuousUpdate(false);
		_thrown = false;
	}
	return true;
}
示例#4
0
bool TranslatePlaneDragger::handle(const PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    // Check if the dragger node is in the nodepath.
    if (!pointer.contains(this)) return false;

    if ((ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) &&
        ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
        _usingTranslate1DDragger = true;

    bool handled = false;
    if (_usingTranslate1DDragger)
    {
        if (_translate1DDragger->handle(pointer, ea, aa))
            handled = true;
    }
    else
    {
        if (_translate2DDragger->handle(pointer, ea, aa))
            handled = true;
    }

    if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
        _usingTranslate1DDragger = false;

    return handled;
}
示例#5
0
bool QueryCoordinatesHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
  if ( ea.getEventType() == osgGA::GUIEventAdapter::MOVE )
  {
    osgViewer::View* view = static_cast<osgViewer::View*>( aa.asView() );
    osg::Vec3d coords = getCoords( ea.getX(), ea.getY(), view, false );
    mGlobe->showCurrentCoordinates( coords.x(), coords.y() );
  }
  if ( ea.getEventType() == osgGA::GUIEventAdapter::PUSH
       && ea.getButtonMask() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
  {
    osgViewer::View* view = static_cast<osgViewer::View*>( aa.asView() );
    osg::Vec3d coords = getCoords( ea.getX(), ea.getY(), view, false );

    OE_NOTICE << "SelectedCoordinates set to:\nLon: " << coords.x() << " Lat: " << coords.y()
    << " Ele: " << coords.z() << std::endl;

    mGlobe->setSelectedCoordinates( coords );

    if ( ea.getModKeyMask() == osgGA::GUIEventAdapter::MODKEY_CTRL )
      //ctrl + rightclick pops up a QMessageBox
    {
      mGlobe->showSelectedCoordinates();
    }
  }

  return false;
}
示例#6
0
    bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
    { 
        if ( ea.getHandled() ) return false;
        if ( ea.getEventType() == osgGA::GUIEventAdapter::PUSH &&
             ea.getButtonMask() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON &&
             (ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL) != 0 &&
             terrain_srs.valid() &&
             layer.valid() )
        {
            osgViewer::View* view = dynamic_cast<osgViewer::View*>( &aa );
            if ( !view ) return false;
            osgUtil::LineSegmentIntersector::Intersections hits;
            if ( view->computeIntersections( ea.getX(), ea.getY(), hits ) )
            {
                osgUtil::LineSegmentIntersector::Intersection first = *hits.begin();
                osg::Vec3d hit = first.getWorldIntersectPoint() - first.getWorldIntersectNormal()*0.2;
                osgGIS::GeoPoint world( hit, terrain_srs.get() );
                osgGIS::GeoPoint result = terrain_srs->getGeographicSRS()->transform( world );

                osgGIS::FeatureCursor cursor = layer->getCursor( result );
                highlight( cursor );

                std::stringstream buf;

                buf << "World: " << world.toString() << std::endl
                    << "Geo: " << result.toString() << std::endl
                    << "SRS: " << terrain_srs->getName() << std::endl;
                int line_count = 2;

                for( cursor.reset(); cursor.hasNext(); )
                {
                    osgGIS::Feature* f = cursor.next();
                    osgGIS::AttributeList attrs = f->getAttributes();
                    for( osgGIS::AttributeList::const_iterator i = attrs.begin(); i != attrs.end(); i++ )
                    {
                        std::string key = i->getKey();
                        if ( key.length() > 0 )
                        {
                            buf << key << " : " << i->asString() << std::endl;
                            line_count++;
                        }
                    }
                    break;
                }

                if ( buf.str().length() == 0 )
                {
                    buf << "Control-Left-Click to query";
                    line_count++;
                }
                hud_text->setText( buf.str() );
                hud_text->setPosition( osg::Vec3( 10, line_count*TEXT_SIZE*1.1f, 0 ) );
                hud_text->dirtyDisplayList();
            }
        }

        return false; // never "handled"
    }
bool OrbitCameraManipulator::handleMouseRelease( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
	if( !view )	return false;

	if( ea.getButtonMask() == 0 )
	{
		double timeSinceLastRecordEvent = _ga_t0.valid() ? (ea.getTime() - _ga_t0->getTime()) : DBL_MAX;
		if( timeSinceLastRecordEvent > 0.02 )
		{
			flushMouseEventStack();
		}

		if( isMouseMoving() )
		{
			if( performMovement( ea, aa ) && _allowThrow )
			{
				aa.requestRedraw();
				aa.requestContinuousUpdate( true );
				_thrown = true;
				// TODO: fade out throw animation
			}

			return true;
		}
	}
	
	if( !m_pointer_push_drag )
	{
		// select object
		bool intersection_geometry_found = intersectSceneSelect( ea, view );

		if( !intersection_geometry_found )
		{
			// click to background -> unselect all
			if( m_system != nullptr )
			{
				m_system->clearSelection();
			}
			
		}
	}
	m_pointer_push_drag = false;

	flushMouseEventStack();
	addMouseEvent( ea );
	if( performMovement( ea, aa ) )
	{
		aa.requestRedraw();
	}
	aa.requestContinuousUpdate( false );
	_thrown = false;

	return true;
}
示例#8
0
bool NavigationControl::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, ControlContext& cx )
{
  switch ( ea.getEventType() )
  {
    case osgGA::GUIEventAdapter::PUSH:
      _mouse_down_event = &ea;
      break;
    case osgGA::GUIEventAdapter::FRAME:
      if ( _mouse_down_event )
      {
        _mouse_down_event = &ea;
      }
      break;
    case osgGA::GUIEventAdapter::RELEASE:
      for ( ControlEventHandlerList::const_iterator i = _eventHandlers.begin(); i != _eventHandlers.end(); ++i )
      {
        NavigationControlHandler* handler = dynamic_cast<NavigationControlHandler*>( i->get() );
        if ( handler )
        {
          handler->onClick( this, ea.getButtonMask(), ea, aa );
        }
      }
      _mouse_down_event = NULL;
      break;
    default:
      /* ignore */
      ;
  }
  if ( _mouse_down_event )
  {
    //OE_NOTICE << "NavigationControl::handle getEventType " << ea.getEventType() << std::endl;
    for ( ControlEventHandlerList::const_iterator i = _eventHandlers.begin(); i != _eventHandlers.end(); ++i )
    {
      NavigationControlHandler* handler = dynamic_cast<NavigationControlHandler*>( i->get() );
      if ( handler )
      {
        handler->onMouseDown( this, ea.getButtonMask() );
      }
    }
  }
  return Control::handle( ea, aa, cx );
}
示例#9
0
bool InteractiveImageHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
{
    if (ea.getHandled()) return false;

    if (!_image) return false;

    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::MOVE):
        case(osgGA::GUIEventAdapter::DRAG):
        case(osgGA::GUIEventAdapter::PUSH):
        case(osgGA::GUIEventAdapter::RELEASE):
        {
            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
            int x,y;
            if (mousePosition(view, nv, ea, x, y))
            {
                return _image->sendPointerEvent(x, y, ea.getButtonMask());
            }
            break;
        }
        case(osgGA::GUIEventAdapter::KEYDOWN):
        case(osgGA::GUIEventAdapter::KEYUP):
        {
            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
            int x,y;
            bool sendKeyEvent = mousePosition(view, nv, ea, x, y);

            if (sendKeyEvent)
            {
                return _image->sendKeyEvent(ea.getKey(), ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN);
            }
            break;
        }
        case (osgGA::GUIEventAdapter::RESIZE):
        {
            if (_fullscreen && _camera.valid())
            {
                _camera->setViewport(0, 0, ea.getWindowWidth(), ea.getWindowHeight());

                resize(ea.getWindowWidth(), ea.getWindowHeight());
                return true;
            }
            break;
        }

        default:
            return false;
    }
    return false;
}
bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
{
    switch(ea.getEventType())
    {
    case(osgGA::GUIEventAdapter::PUSH):
        {
            if (ea.getModKeyMask() == 0)
                return false;

            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
            if (view == NULL)
                return false;

            osgUtil::LineSegmentIntersector::Intersection intersection;
            osg::NodePath node_path;
            Renderable* renderable = NULL;
            if (ea.getButtonMask() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
                renderable = computeIntersection<Renderable>(view, ea, intersection, node_path);
            else if (ea.getButtonMask() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
                renderable = computePointIntersection<Renderable>(view, ea, intersection, node_path);
            else 
                return false;

            if (renderable == NULL)
                return false;

            renderable->pickEvent(ea.getModKeyMask(), intersection.getWorldIntersectPoint());
            return true;
        }
        break;
    default:
        return false;
    }

    return false;
}
示例#11
0
 void write(const osgGA::GUIEventAdapter& event)
 {
     writeUInt(event.getEventType());
     writeUInt(event.getKey());
     writeUInt(event.getButton());
     writeInt(event.getWindowX());
     writeInt(event.getWindowY());
     writeUInt(event.getWindowWidth());
     writeUInt(event.getWindowHeight());
     writeFloat(event.getXmin());
     writeFloat(event.getYmin());
     writeFloat(event.getXmax());
     writeFloat(event.getYmax());
     writeFloat(event.getX());
     writeFloat(event.getY());
     writeUInt(event.getButtonMask());
     writeUInt(event.getModKeyMask());
     writeDouble(event.getTime());
 }
示例#12
0
bool PickHandler::handlePush( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	if (ea.getButtonMask() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
	{
		leftButtonPressed = true;

		origin_mX = ea.getX();
		origin_mY = ea.getY();

		origin_mX_normalized = ea.getXnormalized();
		origin_mY_normalized = ea.getYnormalized();

		if (pickMode != PickMode::NONE && !isShiftPressed && !isCtrlPressed)
		{
			unselectPickedNodes();
			unselectPickedEdges();
		}

		osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>( &aa );

		if (!viewer)
			return false;

		if (pickMode == PickMode::MULTI)
		{
			isDrawingSelectionQuad = true;

			drawSelectionQuad(origin_mX, origin_mY, viewer);
		}

		else
		{
			return pick(ea.getXnormalized() - 0.00005f, ea.getYnormalized() - 0.00005f, ea.getXnormalized() + 0.00005f, ea.getYnormalized() + 0.00005f, viewer );

		}
	}

	_mX = ea.getX();
	_mY = ea.getY();
	return false;
}
// mouse button has been pushed down
bool OrbitCameraManipulator::handleMousePush( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
	if( !view )
	{
		return false;
	}

	m_pointer_push_drag = false;
	flushMouseEventStack();
	addMouseEvent( ea );
	m_ga_pointer_push = &ea;

	intersectSceneRotateCenter( ea, view );

	int buttonMask = ea.getButtonMask();
	if( buttonMask == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON || buttonMask == (osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON | osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) )
	{
		m_pan_point.set( m_pointer_intersection );
	}
	
	if( buttonMask == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
	{
		osg::Vec3d distance_intersect_eye( m_pointer_intersection - m_eye );
		//double distance_eye_intersection = distance_intersect_eye.length();

		// rotate the intersection cone into mouse ray direction
		if( m_intersect_hit_geometry )
		{

		}
	}
	aa.requestRedraw();
	aa.requestContinuousUpdate( false );
	_thrown = false;

	return false;
}
bool TabPlaneDragger::handle(const PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    if (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) return false;

    // Check if the dragger node is in the nodepath.
    if (!pointer.contains(this)) return false;

    // Since the translate plane and the handleNode lie on the same plane the hit could've been on either one. But we
    // need to handle the scaling draggers before the translation. Check if the node path has the scaling nodes else
    // check for the scaling nodes in next hit.
    if (_cornerScaleDragger->handle(pointer, ea, aa))
        return true;
    if (_horzEdgeScaleDragger->handle(pointer, ea, aa))
        return true;
    if (_vertEdgeScaleDragger->handle(pointer, ea, aa))
        return true;

    PointerInfo nextPointer(pointer);
    nextPointer.next();

    while (!nextPointer.completed())
    {
        if (_cornerScaleDragger->handle(nextPointer, ea, aa))
            return true;
        if (_horzEdgeScaleDragger->handle(nextPointer, ea, aa))
            return true;
        if (_vertEdgeScaleDragger->handle(nextPointer, ea, aa))
            return true;

        nextPointer.next();
    }

    if (_translateDragger->handle(pointer, ea, aa))
        return true;

    return false;
}
示例#15
0
//==============================================================================
static void assignEventToButtons(
    MouseButtonEvent (&mLastButtonEvent)[NUM_MOUSE_BUTTONS],
    const osgGA::GUIEventAdapter& ea)
{
    MouseButtonEvent event = BUTTON_NOTHING;
    if(ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
        event = BUTTON_PUSH;
    else if(ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
        event = BUTTON_DRAG;
    else if(ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
        event = BUTTON_RELEASE;

    if(BUTTON_RELEASE == event)
    {
        if( (ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) == 0
                && wasActive(mLastButtonEvent[LEFT_MOUSE]) )
            mLastButtonEvent[LEFT_MOUSE] = event;

        if( (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) == 0
                && wasActive(mLastButtonEvent[RIGHT_MOUSE]) )
            mLastButtonEvent[RIGHT_MOUSE] = event;

        if( (ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) == 0
                && wasActive(mLastButtonEvent[MIDDLE_MOUSE]) )
            mLastButtonEvent[MIDDLE_MOUSE] = event;
    }
    else
    {
        if(ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
            mLastButtonEvent[LEFT_MOUSE] = event;

        if(ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
            mLastButtonEvent[RIGHT_MOUSE] = event;

        if(ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
            mLastButtonEvent[MIDDLE_MOUSE] = event;
    }
}
示例#16
0
//==============================================================================
void DefaultEventHandler::eventPick(const osgGA::GUIEventAdapter& ea)
{
    MouseButtonEvent mbe;
    switch(ea.getEventType())
    {
    case osgGA::GUIEventAdapter::PUSH:
        mbe = BUTTON_PUSH;
        break;
    case osgGA::GUIEventAdapter::DRAG:
        mbe = BUTTON_DRAG;
        break;
    case osgGA::GUIEventAdapter::RELEASE:
        mbe = BUTTON_RELEASE;
        break;
    default:
        return;
    }

    if(   ( (ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
            && !mSuppressButtonPicks[LEFT_MOUSE][mbe])
            || ( (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
                 && !mSuppressButtonPicks[RIGHT_MOUSE][mbe])
            || ( (ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
                 && !mSuppressButtonPicks[MIDDLE_MOUSE][mbe]))
    {
        pick(mTempPicks, ea);

        if(ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
            mButtonPicks[LEFT_MOUSE][mbe] = mTempPicks;

        if(ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
            mButtonPicks[RIGHT_MOUSE][mbe] = mTempPicks;

        if(ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
            mButtonPicks[MIDDLE_MOUSE][mbe] = mTempPicks;
    }
}
示例#17
0
bool
dmz::RenderEventHandlerOSG::handle (
      const osgGA::GUIEventAdapter &Event,
      osgGA::GUIActionAdapter &acion,
      osg::Object *object,
      osg::NodeVisitor *visitor) {

   Boolean result (false);

   if (_channels) {

      switch (Event.getEventType ()) {

         case (osgGA::GUIEventAdapter::KEYDOWN): {

            __set_key_down (Event);
            _channels->send_key_event (_keyEvent);
            result = true;
            break;
         }

         case (osgGA::GUIEventAdapter::KEYUP): {

            __set_key_up (Event);
            _channels->send_key_event (_keyEvent);
            result = true;
            break;
         }

         case (osgGA::GUIEventAdapter::PUSH):
         case (osgGA::GUIEventAdapter::RELEASE):
         case (osgGA::GUIEventAdapter::DOUBLECLICK):
         case (osgGA::GUIEventAdapter::RESIZE):
         case (osgGA::GUIEventAdapter::MOVE):
         case (osgGA::GUIEventAdapter::DRAG):
         case (osgGA::GUIEventAdapter::SCROLL): {

            _mouseEvent.set_button_mask (Event.getButtonMask ());

            const Int32 Width = Event.getWindowWidth ();
            const Int32 Height = Event.getWindowHeight ();

            _mouseEvent.set_window_size (Width, Height);

            _mouseEvent.set_mouse_position (
               // Width - Event.getX (),
               // Height - Event.getY ());
               Event.getX (),
               Height - Event.getY ());

            _mouseEvent.set_scroll_delta (
               Event.getScrollingDeltaX (),
               Event.getScrollingDeltaY ());

            _channels->send_mouse_event (_mouseEvent);
            result = true;
            break;
         }

         case (osgGA::GUIEventAdapter::CLOSE_WINDOW): {

            _exit.request_exit (ExitStatusNormal, "Application Quit.");
            break;
         }

         case (osgGA::GUIEventAdapter::QUIT_APPLICATION):  {

            _exit.request_exit (ExitStatusNormal, "Application Quit.");
            break;
         }

         default:
            break;
      }
   }

   return result;
}
示例#18
0
void PickHandler::pick(osgViewer::Viewer* viewer, const osgGA::GUIEventAdapter& ea)
{


    
    std::string gdlist="";
    std::ostringstream os;
      
    osgUtil::LineSegmentIntersector::Intersections intersections;
    if (viewer->computeIntersections(ea.getX(), ea.getY(), intersections)){
      
      // use the nearest intersection                 
      const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin());
      if(measuring_tool_on){
	if(!measure_anchored){
	  if(!measure_added){
	    group->addChild(measure_geode);
	    measure_added=true;
	  }
	  text_ptr->setText("");
	  //	printf("Anchor\n");
	  (*measure_vertices)[0].set( intersection.getWorldIntersectPoint());
	  (*measure_vertices)[1].set( intersection.getWorldIntersectPoint()+osg::Vec3(0,1.0,0.0));
	  
	  measure_anchored=true;
	}else{
	  (*measure_vertices)[1].set( intersection.getWorldIntersectPoint());
	  //	printf("Complete\n");
	  osg::Vec3 start=(*measure_vertices)[0];
	  osg::Vec3 end=(*measure_vertices)[1];
	  
	  osg::Vec3 diff=end-start;
	  double dist=sqrt(pow(diff[0],2)+pow(diff[1],2)+pow(diff[2],2));
	  
	  char text_str[255];
          sprintf(text_str,"Dist: %.2f\nX: %.2f\nY: %.2f\nZ: %.2f\n",dist,diff[0],diff[2],diff[1]);
	  text_ptr->setText(string(text_str));
	  text_ptr->setPosition(end+osg::Vec3(0,-0.5,0));
	  measure_anchored=false;
          osg::Vec3 distV(dist,dist,dist);
          _mf->measureResultsEmit(distV,diff);
	}
      }
      if(ea.getButtonMask() ==GUIEventAdapter::MIDDLE_MOUSE_BUTTON){
      osg::Drawable* drawable = intersection.drawable.get();
      osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0;
      
      osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0;
      if (vertices){
	
	// get the vertex indices.
	const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList;
	const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList;
	
	if (indices.size()==3 && ratios.size()==3){
	  bool textured = false;
	  osg::StateSet* stateset = drawable->getStateSet();
	  if(stateset){
	    textured=(stateset->getTextureMode(0,GL_TEXTURE_1D)) || 
	      (stateset->getTextureMode(0,GL_TEXTURE_2D)) || 
		      (stateset->getTextureMode(0,GL_TEXTURE_3D)); 
	  }
	  if(textured){

	    osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
	 
	    osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(texture);

/*	    if(texture && texshow){
	      texshow->show(texture);
            }*/
	  unsigned int i1 = indices[0];
	  unsigned int i2 = indices[1];
	  unsigned int i3 = indices[2];
	 
	  float r1 = ratios[0];
	  float r2 = ratios[1];
	  float r3 = ratios[2];
	  
	  osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0;
	  
	  osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords);
	  if (texcoords_Vec2Array){
	    // we have tex coord array so now we can compute the final tex coord at the point of intersection.                                
	    osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1];
	    osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2];
	    osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3];
	    osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3;
	    cout << "We hit tex coords "<<tc << " " <<std::endl;
	    osg::Vec2 tc_noatlas = (tc / 4.0) ;//- osg::Vec2(fmod(tc[0],4.0f),fmod(tc[1],4.0f)) ;
	    cout << tc_noatlas<<endl;
	    /*    osg::notify(osg::NOTICE)<<"We hit tex coords "<<tc << " " << name <<std::endl;
	    os << "We hit tex coords "<<tc << " " << name <<std::endl;
	    cout << "We hit tex coords "<<tc << " " << name <<std::endl;*/
	    gdlist += os.str();
	    //winPtr->loadImage(QString(name.c_str()));
	  }
	  
	  }
	}
      }
    
    else {
      osg::notify(osg::NOTICE)<<"Intersection has insufficient indices to work with";
	}
	
      }
    }
    else{
      
      osg::notify(osg::NOTICE)<<"No intersection"<<std::endl;
    }

    /*if (_viewer->computeIntersections(ea.getX(),ea.getY(),hlist))
    {
    for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin();
    hitr!=hlist.end();
    ++hitr)
    {
            
    if (hitr->_geode.valid() && !hitr->_geode->getName().empty())
    {
    // the geodes are identified by name.
    os<<"Object \""<<hitr->_geode->getName()<<"\""<<std::endl;
    }
    else if (hitr->_drawable.valid())
    {
    os<<"Object \""<<hitr->_drawable->className()<<"\""<<std::endl;
    }
    
            os<<"        local coords vertex("<< hitr->getLocalIntersectPoint()<<")"<<"  normal("<<hitr->getLocalIntersectNormal()<<")"<<std::endl;
            os<<"        world coords vertex("<< hitr->getWorldIntersectPoint()<<")"<<"  normal("<<hitr->getWorldIntersectNormal()<<")"<<std::endl;
            osgUtil::Hit::VecIndexList& vil = hitr->_vecIndexList;
            for(unsigned int i=0;i<vil.size();++i)
            {
	    os<<"        vertex indices ["<<i<<"] = "<<vil[i]<<std::endl;
            }
            
            gdlist += os.str();
	    }
	    }*/
    //setLabel(gdlist);
}
示例#19
0
	virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
	{
		if (ea.getHandled() == true)
		{
			return true;
		}

		osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
		if (!viewer)
		{
			return false;
		}

		float x = ea.getX ();
		float y = ea.getY ();

		switch (ea.getEventType())
		{
		case osgGA::GUIEventAdapter::KEYDOWN:
			{
				if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1)
				{
					CustomDraggerManager::Instence()->setActiveDragger("move");

				}

				if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2)
				{
					CustomDraggerManager::Instence()->setActiveDragger("rotate");

				}
			}
			break;

		case osgGA::GUIEventAdapter::PUSH:
			{
				//更改与模型相关联的Selection
				if(osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON & ea.getButtonMask())
				{

					osg::MatrixTransform* mt= pick(viewer, x, y);

					if (mt)
					{
						if ( (ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL) == 0)
						{
							_pickSelections.clear();
						}
						
						_pickSelections.push_back(mt);

						OSG_WARN<<mt->getName()<<std::endl;
						OSG_WARN<<"in"<<std::endl;
						CustomDraggerManager::Instence()->setSelections(_pickSelections);
						osgDragger::ShowBound::Instence()->setSelections(_pickSelections);
						
					}

				   //std::cout<<_pickSelections.size()<<std::endl;

				}
			}
			break;
		}

		return false;
	}
示例#20
0
文件: Dragger.cpp 项目: 4ker/osg
bool Dragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    if (ea.getHandled()) return false;

    osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
    if (!view) return false;

    bool handled = false;

    bool activationPermitted = true;
    if (_activationModKeyMask!=0 || _activationMouseButtonMask!=0 || _activationKeyEvent!=0)
    {
        _activationPermittedByModKeyMask = (_activationModKeyMask!=0) ?
            ((ea.getModKeyMask() & _activationModKeyMask)!=0) :
            false;

        _activationPermittedByMouseButtonMask = (_activationMouseButtonMask!=0) ?
            ((ea.getButtonMask() & _activationMouseButtonMask)!=0) :
            false;

        if (_activationKeyEvent!=0)
        {
            switch (ea.getEventType())
            {
                case osgGA::GUIEventAdapter::KEYDOWN:
                {
                    if (ea.getKey()==_activationKeyEvent) _activationPermittedByKeyEvent = true;
                    break;
                }
                case osgGA::GUIEventAdapter::KEYUP:
                {
                    if (ea.getKey()==_activationKeyEvent) _activationPermittedByKeyEvent = false;
                    break;
                }
                default:
                    break;
            }
        }

        activationPermitted =  _activationPermittedByModKeyMask || _activationPermittedByMouseButtonMask || _activationPermittedByKeyEvent;

    }

    if (activationPermitted || _draggerActive)
    {
        switch (ea.getEventType())
        {
            case osgGA::GUIEventAdapter::PUSH:
            {
                osgUtil::LineSegmentIntersector::Intersections intersections;

                _pointer.reset();

                if (view->computeIntersections(ea ,intersections, _intersectionMask))
                {
                    for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
                        hitr != intersections.end();
                        ++hitr)
                    {
                        _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint());
                    }
                    for (osg::NodePath::iterator itr = _pointer._hitList.front().first.begin();
                            itr != _pointer._hitList.front().first.end();
                            ++itr)
                    {
                        osgManipulator::Dragger* dragger = dynamic_cast<osgManipulator::Dragger*>(*itr);
                        if (dragger)
                        {
                            if (dragger==this)
                            {
                                osg::Camera *rootCamera = view->getCamera();
                                osg::NodePath nodePath = _pointer._hitList.front().first;
                                osg::NodePath::reverse_iterator ritr;
                                for(ritr = nodePath.rbegin();
                                    ritr != nodePath.rend();
                                    ++ritr)
                                {
                                    osg::Camera* camera = dynamic_cast<osg::Camera*>(*ritr);
                                    if (camera && (camera->getReferenceFrame()!=osg::Transform::RELATIVE_RF || camera->getParents().empty()))
                                    {
                                         rootCamera = camera;
                                         break;
                                    }
                                }

                                _pointer.setCamera(rootCamera);
                                _pointer.setMousePosition(ea.getX(), ea.getY());

                                if(dragger->handle(_pointer, ea, aa))
                                {
                                    dragger->setDraggerActive(true);
                                    handled = true;
                                }
                            }
                        }
                    }
                }
                break;
            }
            case osgGA::GUIEventAdapter::DRAG:
            case osgGA::GUIEventAdapter::RELEASE:
            {
                if (_draggerActive)
                {
                    _pointer._hitIter = _pointer._hitList.begin();
//                    _pointer.setCamera(view->getCamera());
                    _pointer.setMousePosition(ea.getX(), ea.getY());

                    if(handle(_pointer, ea, aa))
                    {
                        handled = true;
                    }
                }
                break;
            }
            default:
                break;
        }

        if (_draggerActive && ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
        {
            setDraggerActive(false);
            _pointer.reset();
        }
    }

    return handled;
}
bool EpipolarVertexDragger::handle(const PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, bool shift)
{
    // Check if the dragger node is in the nodepath, implemented my own method since osg's one only checks the first list (and this results in a non pickable dragger when it is behind the surface...)

    bool dragger = false;
    {
        typedef std::pair<osg::NodePath, osg::Vec3d> NodePathIntersectionPair;
        typedef std::list<NodePathIntersectionPair> IntersectionList;

        IntersectionList::const_iterator Iter;
        for (Iter=pointer._hitList.begin(); Iter!=pointer._hitList.end(); Iter++)
        {
            dragger = dragger || (std::find((*Iter).first.begin(), (*Iter).first.end(), this) != (*Iter).first.end());
        }
    }
    if (!dragger) return false;

    bool handled = false;
    _stopEdition = false;

    if ((ea.getButtonMask() == _usingTranslate1DVertexDraggerMouseButton) &&
            (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) && !shift)
        _usingTranslate1DVertexDragger = true;
    else if ((ea.getButtonMask() == _usingTranslate2DVertexDraggerMouseButton) &&
             (ea.getEventType() == osgGA::GUIEventAdapter::PUSH))
        _usingTranslate2DVertexDragger = true;

    if (_usingTranslate1DVertexDragger)
    {
        BaseViewer* baseViewer = dynamic_cast<BaseViewer*>(&aa);
        if(baseViewer)
        {
            // to have a correct translation along epipolar line (even if the vertex was previously edited in the (x,y) plane, indeed in that case the current lineprojector is no more correct)
            (dynamic_cast<EpipolarTranslate1DVertexDragger*>(_translate1DVertexDragger.get()))->updateLineProjector(baseViewer->getCameraManipulator()->getInverseMatrix().preMult(_currentFocalPoint),
                                                                                                                    baseViewer->getCameraManipulator()->getInverseMatrix().preMult(getVertexEdited()));
        }

        if (_translate1DVertexDragger->handle(pointer, ea, aa))
            handled = true;
    }
    else if (_usingTranslate2DVertexDragger)
    {
        if (_translate2DVertexDragger->handle(pointer, ea, aa))
            handled = true;
    }

    if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
    {
        _usingTranslate1DVertexDragger = false;
        _usingTranslate2DVertexDragger = false;
    }

    /*
    if ((ea.getButtonMask() == _vertexDeletionMouseButton) && (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) && s)
    {
        // *************** vertex deletion with and without retriangulation  ********************** /
        // TODO
    }

    if ((ea.getButtonMask() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) && (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) && shift && s)
    {
        // *************** boundary edge addition  ********************** /
        // TODO
    }
    */

    return handled;
}
示例#22
0
/* virtual */ bool 
av::osg::viewer::InputEventHandler::handle(const ::osgGA::GUIEventAdapter& event, ::osgGA::GUIActionAdapter& action)
{
  logger.trace() << "handle()";

  if (mEventFields->MouseButtonLeftDoubleClick.getValue())
    mEventFields->MouseButtonLeftDoubleClick.setValue(false);
  if (mEventFields->MouseButtonMiddleDoubleClick.getValue())
    mEventFields->MouseButtonMiddleDoubleClick.setValue(false);
  if (mEventFields->MouseButtonRightDoubleClick.getValue())
    mEventFields->MouseButtonRightDoubleClick.setValue(false);
  if (mEventFields->MouseScrollUp.getValue())
    mEventFields->MouseScrollUp.setValue(false);
  if (mEventFields->MouseScrollDown.getValue())
    mEventFields->MouseScrollDown.setValue(false);

  switch(event.getEventType())
  {
    case(::osgGA::GUIEventAdapter::DRAG):
    {
      const ::osg::Vec2 mousePos(event.getX(), event.getY());
      mEventFields->DragEvent.setValue(mousePos);

      break;
    }

    case(::osgGA::GUIEventAdapter::MOVE):
    {
      const ::osg::Vec2 mousePos(event.getX(), event.getY());
      mEventFields->MoveEvent.setValue(mousePos);

      break;
    }

    case(::osgGA::GUIEventAdapter::PUSH):
    case(::osgGA::GUIEventAdapter::RELEASE):
    {
      const unsigned int buttonmask = event.getButtonMask();
      const bool left   = (buttonmask & ::osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) != 0u;
      const bool middle = (buttonmask & ::osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) != 0u;
      const bool right  = (buttonmask & ::osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) != 0u;

      if (mEventFields->MouseButtonLeft.getValue() != left)
        mEventFields->MouseButtonLeft.setValue(left);
      if (mEventFields->MouseButtonMiddle.getValue() != middle)
        mEventFields->MouseButtonMiddle.setValue(middle);
      if (mEventFields->MouseButtonRight.getValue() != right)
        mEventFields->MouseButtonRight.setValue(right);

      if (mEventFields->MouseButtons_OnlyLeft.getValue() != (left && !middle && !right))
        mEventFields->MouseButtons_OnlyLeft.setValue(left && !middle && !right);
      if (mEventFields->MouseButtons_OnlyMiddle.getValue() != (!left && middle && !right))
        mEventFields->MouseButtons_OnlyMiddle.setValue(!left && middle && !right);
      if (mEventFields->MouseButtons_OnlyRight.getValue() != (!left && !middle && right))
        mEventFields->MouseButtons_OnlyRight.setValue(!left && !middle && right);
      if (mEventFields->MouseButtons_LeftAndMiddle.getValue() != (left && middle && !right))
        mEventFields->MouseButtons_LeftAndMiddle.setValue(left && middle && !right);
      if (mEventFields->MouseButtons_LeftAndRight.getValue() != (left && !middle && right))
        mEventFields->MouseButtons_LeftAndRight.setValue(left && !middle && right);
      if (mEventFields->MouseButtons_MiddleAndRight.getValue() != (!left && middle && right))
        mEventFields->MouseButtons_MiddleAndRight.setValue(!left && middle && right);
      if (mEventFields->MouseButtons_LeftAndMiddleAndRight.getValue() != (left && middle && right))
        mEventFields->MouseButtons_LeftAndMiddleAndRight.setValue(left && middle && right);

      break;
    }

    case(::osgGA::GUIEventAdapter::DOUBLECLICK):
    {
      switch (event.getButton())
      {
        case ::osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
        {
          mEventFields->MouseButtonLeftDoubleClick.setValue(true);
          break;
        }

        case ::osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
        {
          mEventFields->MouseButtonMiddleDoubleClick.setValue(true);
          break;
        }

        case ::osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
        {
          mEventFields->MouseButtonRightDoubleClick.setValue(true);
          break;
        }

        default:
          break;
      }

      break;
    }

    case(::osgGA::GUIEventAdapter::SCROLL):
    {
      switch (event.getScrollingMotion())
      {
        case ::osgGA::GUIEventAdapter::SCROLL_UP:
        {
          mEventFields->MouseScrollUp.setValue(true);
          break;
        }

        case ::osgGA::GUIEventAdapter::SCROLL_DOWN:
        {
          mEventFields->MouseScrollDown.setValue(true);
          break;
        }

        default:
          break;
      }

      break;
    }

    case(::osgGA::GUIEventAdapter::KEYDOWN):
    case(::osgGA::GUIEventAdapter::KEYUP):
    {
      const bool pressed = (event.getEventType() == ::osgGA::GUIEventAdapter::KEYDOWN);
      const int key = event.getKey();

      const bool shiftPressed =
        (event.getModKeyMask() & (::osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT |
                                  ::osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT)) != 0u;
      const bool ctrlPressed =
        (event.getModKeyMask() & (::osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL |
                                  ::osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL)) != 0u;
      const bool altPressed =
        (event.getModKeyMask() & (::osgGA::GUIEventAdapter::MODKEY_LEFT_ALT |
                                  ::osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT)) != 0u;

      if (mEventFields->KeyShift.getValue() != shiftPressed)
        mEventFields->KeyShift.setValue(shiftPressed);
      if (mEventFields->KeyCtrl.getValue() != ctrlPressed)
        mEventFields->KeyCtrl.setValue(ctrlPressed);
      if (mEventFields->KeyAlt.getValue() != altPressed)
        mEventFields->KeyAlt.setValue(altPressed);

      if (pressed)
        mKeys.insert(key);
      else
        mKeys.erase(key);

      std::vector<int> keys(mKeys.size());
      std::copy(mKeys.begin(), mKeys.end(), keys.begin());
      mEventFields->KeysPressed.setValue(keys);

      switch (key)
      {
        case ::osgGA::GUIEventAdapter::KEY_Insert:    mEventFields->KeyInsert.setValue(pressed);   break;
        case ::osgGA::GUIEventAdapter::KEY_Delete:    mEventFields->KeyDelete.setValue(pressed);   break;
        case ::osgGA::GUIEventAdapter::KEY_Home:      mEventFields->KeyHome.setValue(pressed);     break;
        case ::osgGA::GUIEventAdapter::KEY_End:       mEventFields->KeyEnd.setValue(pressed);      break;
        case ::osgGA::GUIEventAdapter::KEY_Page_Up:   mEventFields->KeyPageUp.setValue(pressed);   break;
        case ::osgGA::GUIEventAdapter::KEY_Page_Down: mEventFields->KeyPageDown.setValue(pressed); break;
        case ::osgGA::GUIEventAdapter::KEY_Left:      mEventFields->KeyLeft.setValue(pressed);     break;
        case ::osgGA::GUIEventAdapter::KEY_Right:     mEventFields->KeyRight.setValue(pressed);    break;
        case ::osgGA::GUIEventAdapter::KEY_Up:        mEventFields->KeyUp.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_Down:      mEventFields->KeyDown.setValue(pressed);     break;
        case ::osgGA::GUIEventAdapter::KEY_Escape:    mEventFields->KeyEsc.setValue(pressed);      break;
        case ::osgGA::GUIEventAdapter::KEY_Space:     mEventFields->KeySpace.setValue(pressed);    break;
        case ::osgGA::GUIEventAdapter::KEY_Return:    mEventFields->KeyEnter.setValue(pressed);    break;
        case ::osgGA::GUIEventAdapter::KEY_F1:        mEventFields->KeyF1.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F2:        mEventFields->KeyF2.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F3:        mEventFields->KeyF3.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F4:        mEventFields->KeyF4.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F5:        mEventFields->KeyF5.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F6:        mEventFields->KeyF6.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F7:        mEventFields->KeyF7.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F8:        mEventFields->KeyF8.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F9:        mEventFields->KeyF9.setValue(pressed);       break;
        case ::osgGA::GUIEventAdapter::KEY_F10:       mEventFields->KeyF10.setValue(pressed);      break;
        case ::osgGA::GUIEventAdapter::KEY_F11:       mEventFields->KeyF11.setValue(pressed);      break;
        case ::osgGA::GUIEventAdapter::KEY_F12:       mEventFields->KeyF12.setValue(pressed);      break;

      }

      if (altPressed && key == ::osgGA::GUIEventAdapter::KEY_Return && pressed)
      {
        mEventFields->KeyAltReturn.setValue(true);
      }

      break;
    }

    default:
      break;
  }

  return false;
}
void ViewerManipulator::handleMouse(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
{
    using namespace osgGA;

	osg::ref_ptr<GroupNode> hitNode, drawNode;
	
	float dX = lastX - ea.getXnormalized();
	float dY = lastY - ea.getYnormalized();

	float dXclick = clickX - ea.getXnormalized();
	float dYclick = clickY - ea.getYnormalized();

	unsigned int buttonMask = ea.getButtonMask();
	unsigned int modkeyMask = ea.getModKeyMask();

	// adjust modkeyMask to ignore numlock and capslock:
	if (modkeyMask>=GUIEventAdapter::MODKEY_CAPS_LOCK) modkeyMask -= GUIEventAdapter::MODKEY_CAPS_LOCK;
	if (modkeyMask>=GUIEventAdapter::MODKEY_NUM_LOCK) modkeyMask -= GUIEventAdapter::MODKEY_NUM_LOCK;
	
	
	// correct dX for aspect ratio:		
	//std::cout << "aspect= " << (float)ea.getWindowWidth()/ea.getWindowHeight() << std::endl;
	dX *= (float)ea.getWindowWidth()/ea.getWindowHeight();
	dXclick *= (float)ea.getWindowWidth()/ea.getWindowHeight();

#if 0
	if (0) // (ea.getEventType() != osgGA::GUIEventAdapter::MOVE)
	{
		switch(ea.getEventType())
		{
			case(osgGA::GUIEventAdapter::PUSH):
				std::cout << "PUSH ("<<ea.getEventType()<<")"; break;
			case(osgGA::GUIEventAdapter::RELEASE):
				std::cout << "RELEASE ("<<ea.getEventType()<<")"; break;
			case(osgGA::GUIEventAdapter::DOUBLECLICK):
				std::cout << "DOUBLECLICK ("<<ea.getEventType()<<")"; break;
			case(osgGA::GUIEventAdapter::DRAG):
				std::cout << "DRAG ("<<ea.getEventType()<<")"; break;
			case(osgGA::GUIEventAdapter::MOVE):
				std::cout << "MOVE ("<<ea.getEventType()<<")"; break;
			case(osgGA::GUIEventAdapter::SCROLL):
				std::cout << "SCROLL ("<<ea.getEventType()<<")"; break;
			default:
				std::cout << "some other message?" << std::endl; break;
		}
		std::cout << " buttonMask=" << buttonMask << ", modkeyMask=" << modkeyMask << ", dXYclick: " << dXclick<<","<<dYclick << std::endl;
		std::cout << " currently selected nodes:";
		for (unsigned j = 0; j < selectedNodes.size(); ++j)
		{
			std::cout << " " << selectedNodes[j]->s_name;
		}
		std::cout << std::endl;
	}
#endif


	float scrollX = 0.0;
    float scrollY = 0.0;
	if (ea.getEventType()==osgGA::GUIEventAdapter::SCROLL)
	{
		scrollX = ea.getScrollingDeltaX();
		scrollY = ea.getScrollingDeltaY();

		// some devices can't report the delta, so we check if both deltas are
		// zero and in that case, we set the delta to a unit value (1.0) in the 
		// appropriate direction
		if (scrollX == 0 && scrollY == 0)
		{
			switch (ea.getScrollingMotion())
			{
				case osgGA::GUIEventAdapter::SCROLL_LEFT:
					scrollX = 1.0;
					break;
				case osgGA::GUIEventAdapter::SCROLL_RIGHT:
					scrollX = -1.0;
					break;
				case osgGA::GUIEventAdapter::SCROLL_UP:
					scrollY = -1.0;
					break;
				case osgGA::GUIEventAdapter::SCROLL_DOWN:
					scrollY = 1.0;
					break;
				default:
					// nothing
					break;
			}
		}
	}
	
	if (this->picker)
	{
		// This is how the Picker works:
		//
		// A node is "selected" when the user does a PUSH on an GroupNode that
		// has an appropriate interactionMode property (eg, DRAG, THROW)
		//
		// We store the id of the selectedNodes, so that we can disable camera
		// motion if anything is selected.
		//
		// Morover, it is possible for the user to move the cursor so quickly
		// that a selected node is not intersecting anymore and we won't find
		// the node in the intersections list. However, SPIN expects us to send
		// a RELEASE event for that node, so the id must be stored.

		osgUtil::LineSegmentIntersector::Intersections intersections;
		view->computeIntersections(ea.getX(),ea.getY(),intersections);
		//bool haveIntersections = view->computeIntersections(ea.getX(),ea.getY(),intersections, INTERACTIVE_NODE_MASK);

		// first, we fill 2 vectors with data (the pointer to the node, and the
		// local intersect point)
        std::vector<GroupNode*> hitNodes;
        std::vector<osg::Vec3> hitPoints;

		// intersections are ordered from nearest to furthest, so we iterate and
		// a return list of all nodes that can be cast as interactive SPIN nodes
		osgUtil::LineSegmentIntersector::Intersections::const_iterator itr;
		for (itr = intersections.begin(); itr != intersections.end(); ++itr)
		{
			// look down the nodePath for the first SPIN node:
			for (int i = (*itr).nodePath.size() - 1; i >= 0; i--)
			{
				osg::ref_ptr<GroupNode> testNode = dynamic_cast<GroupNode*>((*itr).nodePath[i]);
				if (testNode.valid())
				{
					// we check if this node is interactive, or if it has an
					// owner (since sometimes interactive mode can be unset
					// before the RELEASE event gets sent)
					//if ((testNode->getInteractionMode()>0) || (testNode->owner.valid()))
					if (testNode->getInteractionMode()>0)
					{
						// Yes. This is an interactive SPIN node, so add it to 
						// the list, but only once! ... we must check if it has
						// already been added since the intersector can
						// intersect with the same node several times:
						if (std::find( hitNodes.begin(), hitNodes.end(), testNode.get() ) == hitNodes.end())
						{
							osg::Vec3 v = (*itr).getLocalIntersectPoint();
							hitPoints.push_back((*itr).getLocalIntersectPoint());
							hitNodes.push_back(testNode.get());
						}
					}

					// Once we've found the first SPIN node, we break and move
					// to the next intersection. We don't look up the nodePath
					// to see if parentNodes are interactive, otherwise we'll
					// get bad intersect points.
					break;
				}
			}
		}

		// ******
	
		// If any nodes are currently "selected" (ie, the user did a PUSH but
		// hasn't done a RELEASE yet), we are ONLY interested in subsequent
		// events to those node(s). ie, we do not select additional nodes until
		// a RELEASE has been performed.
		//
		// We do however try to use the intersect list to update the hitPoint.
		
		if (selectedNodes.size())
		{
			//for (j=0; j<selectedNodes.size(); j++)
			for (std::vector<t_symbol*>::iterator it=selectedNodes.begin(); it!=selectedNodes.end();)
			{	
				bool found = false;
				GroupNode *n = dynamic_cast<GroupNode*>((*it)->s_thing);
				for (unsigned i = 0; i < hitNodes.size(); i++)
				{
					if (hitNodes[i] == n)
					{
						sendPick(n, ea.getEventType(), modkeyMask, buttonMask,
								scrollX, scrollY, dX, dY, hitPoints[i]);
						found = true;
						break;
					}
				}
				
				// if it wasn't found in the intersections list, we still want to
				// send the event (eg, a RELEASE), but we set the hitpoint to 0,0,0
				if (!found)
				{
					sendPick(n, ea.getEventType(), modkeyMask, buttonMask,
							scrollX, scrollY, dX, dY, osg::Vec3(0.0,0.0,0.0));
				}

				// if the event is a RELEASE, then remove it from selectedNodes
				if (ea.getEventType()==GUIEventAdapter::RELEASE)
					selectedNodes.erase(it);
				else
					++it;
			}
		}
		
		// if no nodes are selected, then we go through the intersect list and
		// send events to the first selectable (ie, type SELECT, DRAG, or THROW)
		// in the list, and the first DRAW node. We NEVER send to more than one
		// selectable, or we will end up selecting several nodes at once.
		//
		// Also, the rule with DRAW nodes is that once we find one, we no longer
		// look for selectables. ie, a selectable node can be selected in front
		// of a drawable (eg, for a brush), but we cannot select nodes behind
		// a drawable.
		else
		{	
			bool foundSelectable = false;
			bool foundDrawable = false;
			
			for (unsigned i = 0; i < hitNodes.size(); i++)
			{
				if ( hitNodes[i]->getInteractionMode()==GroupNode::DRAW )
				{
					if (!foundDrawable)
					{
						sendPick(hitNodes[i], ea.getEventType(), modkeyMask, buttonMask,
								scrollX, scrollY, dX, dY, hitPoints[i]);
						
						// add it to the selectedNodes in the case of a PUSH
						if (ea.getEventType()==GUIEventAdapter::PUSH)
							selectedNodes.push_back(hitNodes[i]->id);
						
						foundDrawable = true;
					}
				}

				// If we've found a drawable, thus we stop right away so that
				// nodes behind cannot be selected
				if (foundDrawable) break;
				
				else if ((int) hitNodes[i]->getInteractionMode()>0)
				{
					if (!foundSelectable)
					{
						sendPick(hitNodes[i], ea.getEventType(), modkeyMask, buttonMask,
								scrollX, scrollY, dX, dY, hitPoints[i]);
						
						// add it to the selectedNodes in the case of a PUSH
						if (ea.getEventType()==GUIEventAdapter::PUSH)
							selectedNodes.push_back(hitNodes[i]->id);
						
						foundSelectable = true;
					}
				}
				
				// if we've found one of each, we can stop:
				if (foundSelectable && foundDrawable) break;

				// otherwise we keep looking, allowing one selectable in front
				// of one drawable
			}
		}

		
	} // end picker
	
	
	
    // scene event processing (eg, camera motion):
	if ( this->mover && selectedNodes.empty() )
	{
		float movScalar = 10.0;
		float rotScalar = 30.0;
		
		switch(ea.getEventType())
		{
			case(GUIEventAdapter::PUSH):
				// in the case of a mouse click, we store the current coords
				clickX = ea.getXnormalized();
				clickY = ea.getYnormalized();
				
				
				sendEvent(user->s_name, "sfff", "setVelocity", 0.0, 0.0, 0.0, LO_ARGS_END);
				if (buttonMask == (GUIEventAdapter::LEFT_MOUSE_BUTTON+GUIEventAdapter::RIGHT_MOUSE_BUTTON))
					sendEvent(user->s_name, "sfff", "setSpin", 0.0, 0.0, 0.0, LO_ARGS_END);

				
				break;
				
			case(GUIEventAdapter::DRAG):
				
				// here we can move the user relative to the current camera
				// view, so we get the view's world coords:
				/*
			    osg::Vec3d camCenter;
			    osg::Quat camRotation;
			    computeNodeCenterAndRotation(camCenter, camRotation);
			    osg::Vec3 camEulers = QuatToEuler( camRotation );
			    float camDistance = ((*itr).getWorldIntersectPoint() - camCenter).length();
			    
			    std::cout << "cam center=("<<camCenter.x()<<","<<camCenter.y()<<","<<camCenter.z()<<")";
			    std::cout << ", distance="<<camDistance;
			    std::cout << ", pitch="<<osg::RadiansToDegrees(camEulers.x());
			    std::cout << ", yaw="<<osg::RadiansToDegrees(camEulers.z());
			    std::cout << std::endl;
			    */
				
				if (!modkeyMask)
				{
				    if (buttonMask == GUIEventAdapter::LEFT_MOUSE_BUTTON)
				    {
				    	// pan forward/back & left/right:
				    	sendEvent(user->s_name, "sfff", "move", dX*movScalar, dY*movScalar, 0.0, LO_ARGS_END);
				    }
				    else if (buttonMask == GUIEventAdapter::RIGHT_MOUSE_BUTTON)
				    {
				    	// pan up/down & left/right:
				    	sendEvent(user->s_name, "sfff", "move", dX*movScalar, 0.0, dY*movScalar, LO_ARGS_END);
				    }
				    else if (buttonMask == (GUIEventAdapter::LEFT_MOUSE_BUTTON+GUIEventAdapter::RIGHT_MOUSE_BUTTON))
				    {
				    	// rotate mode:
				    	sendEvent(user->s_name, "sfff", "rotate", dY*rotScalar, 0.0, dX*rotScalar, LO_ARGS_END);
				    }
				}
			
			    else if ( (modkeyMask==GUIEventAdapter::MODKEY_LEFT_CTRL) || (modkeyMask==GUIEventAdapter::MODKEY_RIGHT_CTRL) )
			    	
			    {
			    	int dXsign, dYsign;
			    	(dXclick<0) ? dXsign=-1 : dXsign=1;
			    	(dYclick<0) ? dYsign=-1 : dYsign=1;
			    	
			    	// drive mode:
				    if (buttonMask == GUIEventAdapter::LEFT_MOUSE_BUTTON)
				    {
				    	// drive forward/back & left/right:
			    		sendEvent(user->s_name, "sfff", "setVelocity", dXsign*pow(dXclick*movScalar,2), dYsign*pow(dYclick*movScalar,2), 0.0f, LO_ARGS_END);
			    		
				    }
				    else if (buttonMask == GUIEventAdapter::RIGHT_MOUSE_BUTTON)
				    {
				    	// drive up/down & left/right:
			    		sendEvent(user->s_name, "sfff", "setVelocity", dXsign*pow(dXclick*movScalar,2), 0.0f, dYsign*pow(dYclick*movScalar,2), LO_ARGS_END);
			    	}
				    else if (buttonMask == (GUIEventAdapter::LEFT_MOUSE_BUTTON+GUIEventAdapter::RIGHT_MOUSE_BUTTON))
				    {
				    	// rotate mode:
			    		sendEvent(user->s_name, "sfff", "setSpin", dYsign*pow(dYclick*rotScalar,2), 0.0, dXsign*pow(dXclick*rotScalar,2), LO_ARGS_END);
				    }
			    }

				break;
				
			case(GUIEventAdapter::RELEASE):
				sendEvent(user->s_name, "sfff", "setVelocity", 0.0, 0.0, 0.0, LO_ARGS_END);
				sendEvent(user->s_name, "sfff", "setSpin", 0.0, 0.0, 0.0, LO_ARGS_END);
				break;
				
			case(GUIEventAdapter::SCROLL):
				// zoom?
				break;
			default:
				// here we could pop up an HUD menu if someone double-clicks or right-clicks
				break;
		}
	}

	// send raw events if user requests them
	if (this->raw)
	{
		sendEvent(user->s_name,
		    "siiiff",
		    "mouseEvent",
			(int)ea.getEventType(),
			(int) ea.getModKeyMask(),
			(int) ea.getButtonMask(),
		    (float) ea.getXnormalized(),
		    (float) ea.getYnormalized(),
		    LO_ARGS_END);
	}

	lastX = ea.getXnormalized();
	lastY = ea.getYnormalized();
}
bool
FeatureQueryTool::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
    bool handled = false;
    bool attempt;

    if ( _inputPredicate.valid() )
    {
        attempt = _inputPredicate->accept(ea);
    }
    else
    {
        attempt =
            ea.getEventType() == osgGA::GUIEventAdapter::RELEASE &&
            _mouseDown && 
            fabs(ea.getX()-_mouseDownX) <= 3.0 && 
            fabs(ea.getY()-_mouseDownY) <= 3.0;
    }

    if ( attempt )
    {
        osg::View* view = aa.asView();

        Picker picker(
            dynamic_cast<osgViewer::View*>(view),
            _mapNode->getModelLayerGroup() );

        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            // find the closest indexed feature to the camera. It must be a feature
            // that is not only closest, but exists in the index as well.

            FeatureSourceIndexNode* closestIndex    = 0L;
            FeatureID               closestFID;
            double                  closestDistance = DBL_MAX;
            osg::Vec3d              closestWorldPt;

            for(Picker::Hits::iterator hit = hits.begin(); hit != hits.end(); ++hit )
            {
                FeatureSourceIndexNode* index = picker.getNode<FeatureSourceIndexNode>( *hit );
                if ( index && (hit->distance < closestDistance) )
                {
                    FeatureID fid;
                    if ( index->getFID( hit->drawable, hit->primitiveIndex, fid ) )
                    {
                        closestIndex    = index;
                        closestFID      = fid;
                        closestDistance = hit->distance;
                        closestWorldPt  = hit->matrix.valid() ? hit->localIntersectionPoint * (*hit->matrix.get()) : hit->localIntersectionPoint;
                    }
                }
            }

            if ( closestIndex )
            {
                OE_DEBUG << LC << "HIT: feature ID = " << (unsigned)closestFID << std::endl;

                Callback::EventArgs args;
                args._ea = &ea;
                args._aa = &aa;
                args._worldPoint = closestWorldPt;

                for( Callbacks::iterator i = _callbacks.begin(); i != _callbacks.end(); )
                {
                    if ( i->valid() )
                    {
                        i->get()->onHit( closestIndex, closestFID, args );
                        ++i;
                    }
                    else
                    {
                        i = _callbacks.erase( i );
                    }
                }

                handled = true;
            }
        }

        if ( !handled )
        {
            OE_DEBUG << LC << "miss" << std::endl;

            Callback::EventArgs args;
            args._ea = &ea;
            args._aa = &aa;

            for( Callbacks::iterator i = _callbacks.begin(); i != _callbacks.end(); )
            {
                if ( i->valid() )
                {
                    i->get()->onMiss( args );
                    ++i;
                }
                else
                {
                    i = _callbacks.erase( i );
                }
            }
        }

        _mouseDown = false;
    }

    // unmodified left mouse click
    else if (
        ea.getEventType()  == osgGA::GUIEventAdapter::PUSH &&
        ea.getModKeyMask() == 0 &&
        ea.getButtonMask() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
    {
        _mouseDown = true;
        _mouseDownX = ea.getX();
        _mouseDownY = ea.getY();
    }

    return handled;
}