コード例 #1
0
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;
}
コード例 #2
0
ファイル: RTTPicker.cpp プロジェクト: Karamaz0V1/osgearth
bool
RTTPicker::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    if ( ea.getEventType() == ea.FRAME )
    {
        osg::FrameStamp* fs = aa.asView() ? aa.asView()->getFrameStamp() : 0L;
        if ( fs )
        {
            runPicks( fs->getFrameNumber() );           
        }

        // if there are picks in the queue, need to continuing rendering:
        if ( !_picks.empty() )
        {
            aa.requestRedraw();
        }
    }

    else if ( _defaultCallback.valid() && _defaultCallback->accept(ea, aa) )
    {        
        pick( aa.asView(), ea.getX(), ea.getY(), _defaultCallback.get() );
        aa.requestRedraw();
    }

    return false;
}
コード例 #3
0
bool OrbitCameraManipulator::handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();

	// TODO: increase scroll factor when eye is far away from model bounding sphere
	double scroll_distance_factor = ( m_eye - m_rotate_center ).length()*0.1;

	switch( sm )
	{
		// mouse scroll up event
	case osgGA::GUIEventAdapter::SCROLL_UP:
		{
			// perform zoom
			zoomCamera( m_wheel_zoom_factor*scroll_distance_factor );
			aa.requestRedraw();
			aa.requestContinuousUpdate( isAnimating() || _thrown );
			return true;
		}

		// mouse scroll down event
	case osgGA::GUIEventAdapter::SCROLL_DOWN:
		{
			// perform zoom
			zoomCamera( -m_wheel_zoom_factor*scroll_distance_factor );
			aa.requestRedraw();
			aa.requestContinuousUpdate( isAnimating() || _thrown );
			return true;
		}

		// unhandled mouse scrolling motion
	default:
		return false;
	}
}
コード例 #4
0
bool TerrainZoomManipulator::handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )
{
    // no zooming by intersection is choosed
    if (! (_flags & 0x08))
    {
        setCenterByMousePointer(ea, us);
    }

    switch( ea.getScrollingMotion() )
    {
        // mouse scroll up event
        case osgGA::GUIEventAdapter::SCROLL_UP:
        {
            // perform zoom
            zoomModel( _wheelZoomFactor, true );
            us.requestRedraw();
            us.requestContinuousUpdate( isAnimating() || _thrown );
            return true;
        }

        // mouse scroll down event
        case osgGA::GUIEventAdapter::SCROLL_DOWN:

            zoomModel( -_wheelZoomFactor, true );
            us.requestRedraw();
            us.requestContinuousUpdate( false );
            return true;

        // unhandled mouse scrolling motion
        default:
            return false;
   }
   
}
コード例 #5
0
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;

    if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            _dragging = true;
            aa.requestRedraw();
            return true;
        }
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
    {
        _dragging = false;
        aa.requestRedraw();
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
    {
        if (_dragging)
        {
            osg::Vec3d world;
            if ( _mapNode->getTerrain()->getWorldCoordsUnderMouse(view, ea.getX(), ea.getY(), world) )
            {
                GeoPoint mapPoint;
                _mapNode->getMap()->worldPointToMapPoint(world, mapPoint);
                setPosition( mapPoint );
                aa.requestRedraw();
                return true;
            }
        }
    }   
    else if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            setHover( true );
        }
        else
        {
            setHover( false );
        }        
        aa.requestRedraw();
    }
    return false;
}
コード例 #6
0
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;
}
コード例 #7
0
ファイル: UFOManipulator.cpp プロジェクト: aalex/osg
void UFOManipulator::home(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us) 
{
    home(ea.getTime());
    us.requestRedraw();
    us.requestContinuousUpdate(false);

}
コード例 #8
0
ファイル: CameraManipulator.cpp プロジェクト: Cecko/3dsoftviz
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;
	}
}
コード例 #9
0
ファイル: CameraManipulator.cpp プロジェクト: Cecko/3dsoftviz
/*!
 * 
 * \param ea
 * Adapter udalosti.
 * 
 * Metoda spomali pohyb na zaklade zdroja prijatej udalosti. 
 * 
 */
bool Vwr::CameraManipulator::handleKeyUp( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter & us)
{
	switch( ea.getKey() )
	{
	case osgGA::GUIEventAdapter::KEY_Space:
	{
		flushMouseEventStack();
		_thrown = false;
		_distance = 1.0f;
		home(ea,us);
		us.requestRedraw();
		us.requestContinuousUpdate(false);

		stop();
		break;
	}
	case osgGA::GUIEventAdapter::KEY_Up:
	case osgGA::GUIEventAdapter::KEY_Down:
		decelerateForwardRate = true;
		break;

	case osgGA::GUIEventAdapter::KEY_Right:
	case osgGA::GUIEventAdapter::KEY_Left:
		decelerateSideRate = true;
		break;

	case osgGA::GUIEventAdapter::KEY_Page_Up:
	case osgGA::GUIEventAdapter::KEY_Page_Down:
		decelerateVerticalRate = true;
		break;
	}

	return true;
}
コード例 #10
0
ファイル: stats.cpp プロジェクト: Thoronador/openmw
bool StatsHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
{
    if (ea.getHandled()) return false;

    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::KEYDOWN):
        {
            if (ea.getKey()== _key)
            {
                osgViewer::View* myview = dynamic_cast<osgViewer::View*>(&aa);
                if (!myview) return false;

                osgViewer::ViewerBase* viewer = myview->getViewerBase();

                toggle(viewer);

                aa.requestRedraw();
                return true;
            }
            break;
        }
        case osgGA::GUIEventAdapter::RESIZE:
        {
            setWindowSize(ea.getWindowWidth(), ea.getWindowHeight());
            break;
        }
        default:
            break;
    }
    return false;
}
コード例 #11
0
ファイル: GISManipulator.cpp プロジェクト: hjanetzek/SFCGAL
bool GISManipulator::handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )
{
    osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();

    osg::Vec3d eye, center, up;
    getTransformation( eye, center, up );
    double altitude = eye[2];

    if ( sm == osgGA::GUIEventAdapter::SCROLL_UP ) {
        altitude /= 1.41;
    }
    else if ( sm == osgGA::GUIEventAdapter::SCROLL_DOWN ) {
        altitude *= 1.41;
    }
    else {
        return false;
    }

    eye[2] = altitude;
    center[2] = eye[2] - 1.0;
    setTransformation( eye, center, up );

    us.requestRedraw();
    us.requestContinuousUpdate( isAnimating() );
    return true;
}
コード例 #12
0
ファイル: CameraManipulator.cpp プロジェクト: Cecko/3dsoftviz
bool Vwr::CameraManipulator::handleScroll(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
	addMouseEvent(ea);
	if (calcMovement()) us.requestRedraw();
	us.requestContinuousUpdate(false);
	_thrown = false;
	return true;
}
コード例 #13
0
bool CameraManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::FRAME):
        {
			return handleFrame(ea, us);
        }
        default:
            break;
    }

    if (ea.getHandled()) return false;

    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::PUSH):
        {
			return handlePush(ea, us);
        }
        case(osgGA::GUIEventAdapter::RELEASE):
        {
            return handleRelease(ea, us);
        }
        case(osgGA::GUIEventAdapter::DRAG):
        case(osgGA::GUIEventAdapter::SCROLL):
        {
			return handleScroll(ea, us);
        }
        case(osgGA::GUIEventAdapter::MOVE):
        {
            return false;
        }
		case(osgGA::GUIEventAdapter::KEYDOWN):
		{
			return handleKeyDown(ea, us);
		}
		case(osgGA::GUIEventAdapter::KEYUP):
		{
			return handleKeyUp( ea, us );
		}
        case(osgGA::GUIEventAdapter::FRAME):
		{
            if (_thrown)
            {
                if (calcMovement()) us.requestRedraw();
            }

            return false;
		}
        default:
            return false;
    }
}
コード例 #14
0
bool ThirdPersonCameraManipulator::handleMousePush( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{

	/// At the moment, OSG doesn't have support for extra mouse buttons, but I plan to add that later, at which point you'll be able to zoom with the forwards and backwards buttons (if you have them)
	switch(ea.getButton())
	{
#ifdef SUPPORTS_EXTRA_MOUSE_BUTTONS
	case osgGA::GUIEventAdapter::FORWARD_MOUSE_BUTTON :
		zoom(_zoomFactor);
		aa.requestRedraw();
		return true;
	case osgGA::GUIEventAdapter::BACKWARD_MOUSE_BUTTON :
		zoom(-_zoomFactor);
		aa.requestRedraw();
		return true;
#endif
	default:
		return false;
	}

	return false;
}
コード例 #15
0
ファイル: ViewerEventHandlers.cpp プロジェクト: yueying/osg
bool LODScaleHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
    osg::Camera* camera = view ? view->getCamera() : 0;
    if (!camera) return false;

    if (ea.getHandled()) return false;

    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::KEYUP):
        {
            if (ea.getKey() == _keyEventIncreaseLODScale)
            {
                camera->setLODScale(camera->getLODScale()*1.1);
                OSG_NOTICE<<"LODScale = "<<camera->getLODScale()<<std::endl;

                aa.requestRedraw();
                return true;
            }

            else if (ea.getKey() == _keyEventDecreaseLODScale)
            {
                camera->setLODScale(camera->getLODScale()/1.1);
                OSG_NOTICE<<"LODScale = "<<camera->getLODScale()<<std::endl;

                aa.requestRedraw();
                return true;
            }

            break;
        }
    default:
        break;
    }

    return false;
}
コード例 #16
0
bool OrbitCameraManipulator::handleMouseDrag( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	addMouseEvent( ea );

	m_pointer_push_drag = true;
	if( performMovement( ea, aa ) )
	{
		aa.requestRedraw();
	}

	aa.requestContinuousUpdate( false );
	_thrown = false;

	return true;
}
コード例 #17
0
ファイル: CameraManipulator.cpp プロジェクト: Cecko/3dsoftviz
bool Vwr::CameraManipulator::handleFrame(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
	double current_frame_time = ea.getTime();

	_delta_frame_time = current_frame_time - _last_frame_time;
	_last_frame_time = current_frame_time;

	if (_thrown && _allowThrow)
	{
		if (calcMovement()) us.requestRedraw();
	}

	frame(ea,us);

	return false;
}
コード例 #18
0
bool OrbitCameraManipulator::performAnimationMovement( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	double f = (ea.getTime() - m_animation_data->_startTime) / m_animation_data->_animationTime;
    if( f >= 1. )
    {
        f = 1.;
        m_animation_data->_isAnimating = false;
        if( !_thrown )
            aa.requestContinuousUpdate( false );
    }

    applyAnimationStep( f, m_animation_data->_phase );

    m_animation_data->_phase = f;
    aa.requestRedraw();

    return m_animation_data->_isAnimating;
}
コード例 #19
0
ファイル: ViewerEventHandlers.cpp プロジェクト: yueying/osg
bool ToggleSyncToVBlankHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
    if (!view) return false;

    osgViewer::ViewerBase* viewer = view->getViewerBase();

    if (viewer == NULL)
    {
        return false;
    }

    if (ea.getHandled()) return false;

    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::KEYUP):
        {
            if (ea.getKey() == _keyEventToggleSyncToVBlank)
            {
                // Increase resolution
                osgViewer::Viewer::Windows    windows;

                viewer->getWindows(windows);
                for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
                    itr != windows.end();
                    ++itr)
                {
                    (*itr)->setSyncToVBlank( !(*itr)->getSyncToVBlank() );
                }

                aa.requestRedraw();
                return true;
            }

            break;
        }
    default:
        break;
    }

    return false;
}
コード例 #20
0
bool ViewerManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    using namespace osgGA;

	if (ea.getEventType()==GUIEventAdapter::FRAME)
	{
		spinApp &spin = spinApp::Instance();
		
		// update from NodeTrackerManipulator:
		if (spin.userNode.valid())
		{
			// if the userNode's nodepath has changed, we must call setTrackNode
			// again to force NodeTrackerManipulator to store the proper nodePath
			if (spin.userNode->nodepathUpdate)
			{
				setTrackNode(spin.userNode->getAttachmentNode());
				spin.userNode->nodepathUpdate = false;
			}
			
			// update camera from NodeTrackerManipulator:
			if (_thrown) aa.requestRedraw();
		}
	}
	
	else if ((ea.getEventType()==GUIEventAdapter::MOVE)||
			(ea.getEventType()==GUIEventAdapter::DRAG)||
			(ea.getEventType()==GUIEventAdapter::PUSH)||
			(ea.getEventType()==GUIEventAdapter::RELEASE)||
			(ea.getEventType()==GUIEventAdapter::DOUBLECLICK)||
			(ea.getEventType()==GUIEventAdapter::SCROLL))
	{
		osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
		if (view) handleMouse(view,ea);
	}
	
	
	else if (ea.getEventType()==GUIEventAdapter::KEYUP)
	{
		handleKeypress(ea);
	}
	
	return false;
}
コード例 #21
0
// 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;
}
コード例 #22
0
/// Handles GUIEventAdapter::FRAME event.
bool OrbitCameraManipulator::handleFrame( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
	double current_frame_time = ea.getTime();

	_delta_frame_time = current_frame_time - _last_frame_time;
	_last_frame_time = current_frame_time;

	if( _thrown && performMovement( ea, aa ) )
	{
		aa.requestRedraw();
	}

	if( m_animation_data && m_animation_data->_isAnimating )
	{
		if( m_animation_data->_startTime < 0 )
		{
			// animation has been started from some location without acces to a GUIEventAdapter object, so no start time could be set. Do it now.
			m_animation_data->start( current_frame_time );
		}
		performAnimationMovement( ea, aa );
	}

	return false;
}
コード例 #23
0
    virtual bool 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;
       switch (ea.getEventType())
       {
           // Pick start.
       case (osgGA::GUIEventAdapter::PUSH):
           {
               // Get the LocalToWorld matrix for this node and set it for the projector.
              osg::NodePath nodePathToRoot;
              computeNodePathToRoot(*this,nodePathToRoot);
              osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
              _projector->setLocalToWorld(localToWorld);

              //设置点移动平面,点即鼠标与物体交点(世界坐标系),法线为//视线方向
			  //osg::Plane::Plane  ( const Vec3_type &  norm,  const Vec3_type &  point) norm:法线;point:交点

              osg::Plane* pplnPTPush= new osg::Plane( pointer.getEyeDir(),
				  pointer.getLocalIntersectPoint()/** _projector->getLocalToWorld()*/);
              _projector->setPlane( *pplnPTPush);

              if (_projector->project(pointer, _startProjectedPoint))
              {
                  // Generate the motion command.
                  osg::ref_ptr<TranslateInPlaneCommand> cmd = new TranslateInPlaneCommand(_projector->getPlane());

                  cmd->setStage(MotionCommand::START);
                  cmd->setReferencePoint(_startProjectedPoint);
                  cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());

                  // Dispatch command.
                  if (_commandManager)
                  {
                     _commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
                     _commandManager->dispatch(*cmd);
                  }
              //在该点处添加一个球 
              osg::ref_ptr< osg::Shape> sphere = 
				  new osg::Sphere( _startProjectedPoint* _projector->getLocalToWorld(), 0.08f);
              osg::ref_ptr<osg::ShapeDrawable> sphereDrawable = new osg::ShapeDrawable(sphere);
              osg::ref_ptr<osg::Geode> sphereGeode = new osg::Geode();
              sphereGeode->addDrawable(sphereDrawable);

              g_pRoot->addChild( sphereGeode);

                  // Set color to pick color.
                  setMaterialColor(_pickColor,*this);
                  getOrCreateStateSet()->setAttributeAndModes(_polygonOffset.get(), osg::StateAttribute::ON);

                  aa.requestRedraw();
              }
              return true; 
           }

           // Pick move.
       case (osgGA::GUIEventAdapter::DRAG):
           {
              osg::Vec3d projectedPoint;
              if (_projector->project(pointer, projectedPoint))
              {
                  // Generate the motion command.
                  osg::ref_ptr<TranslateInPlaneCommand> cmd = new TranslateInPlaneCommand(_projector->getPlane());

                  cmd->setStage(MotionCommand::MOVE);
                  cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
                  cmd->setTranslation(projectedPoint - _startProjectedPoint);
                  cmd->setReferencePoint(_startProjectedPoint);

                  // Dispatch command.
                  if (_commandManager)
                  {
                     _commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
                     _commandManager->dispatch(*cmd);
                  }

				  osg::ref_ptr< osg::Shape> sphere =
					  new osg::Sphere( projectedPoint* _projector->getLocalToWorld(), 0.08f);
              osg::ref_ptr<osg::ShapeDrawable> sphereDrawable = new osg::ShapeDrawable(sphere);
              osg::ref_ptr<osg::Geode> sphereGeode = new osg::Geode();
              sphereGeode->addDrawable(sphereDrawable);

              g_pRoot->addChild( sphereGeode);

                  aa.requestRedraw();
              }
              return true; 
           }

           // Pick finish.
       case (osgGA::GUIEventAdapter::RELEASE):
           {

               osg::ref_ptr<TranslateInPlaneCommand> cmd = new TranslateInPlaneCommand(_projector->getPlane());

               cmd->setStage(MotionCommand::FINISH);
               cmd->setReferencePoint(_startProjectedPoint);
               cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());

              // Dispatch command.
              if (_commandManager)
              {
                  _commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
                  _commandManager->dispatch(*cmd);
              }
              // Reset color.
              setMaterialColor(_color,*this);
              getOrCreateStateSet()->removeAttribute(_polygonOffset.get());

              aa.requestRedraw();
              return true;
           }
       default:
           return false;
       }
    }
コード例 #24
0
ファイル: Translate1DDragger.cpp プロジェクト: yueying/osg
bool Translate1DDragger::handle(const PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    // Check if the dragger node is in the nodepath.
    if (_checkForNodeInNodePath)
    {
        if (!pointer.contains(this)) return false;
    }

    switch (ea.getEventType())
    {
    // Pick start.
    case (osgGA::GUIEventAdapter::PUSH):
    {
        // Get the LocalToWorld matrix for this node and set it for the projector.
        osg::NodePath nodePathToRoot;
        computeNodePathToRoot(*this,nodePathToRoot);
        osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
        _projector->setLocalToWorld(localToWorld);

        if (_projector->project(pointer, _startProjectedPoint))
        {
            // Generate the motion command.
            osg::ref_ptr<TranslateInLineCommand> cmd = new TranslateInLineCommand(_projector->getLineStart(),
                    _projector->getLineEnd());
            cmd->setStage(MotionCommand::START);
            cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());

            // Dispatch command.
            dispatch(*cmd);

            // Set color to pick color.
            setMaterialColor(_pickColor,*this);

            aa.requestRedraw();
        }
        return true;
    }

    // Pick move.
    case (osgGA::GUIEventAdapter::DRAG):
    {
        osg::Vec3d projectedPoint;
        if (_projector->project(pointer, projectedPoint))
        {
            // Generate the motion command.
            osg::ref_ptr<TranslateInLineCommand> cmd = new TranslateInLineCommand(_projector->getLineStart(),
                    _projector->getLineEnd());
            cmd->setStage(MotionCommand::MOVE);
            cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
            cmd->setTranslation(projectedPoint - _startProjectedPoint);

            // Dispatch command.
            dispatch(*cmd);

            aa.requestRedraw();
        }
        return true;
    }

    // Pick finish.
    case (osgGA::GUIEventAdapter::RELEASE):
    {
        osg::Vec3d projectedPoint;
        if (_projector->project(pointer, projectedPoint))
        {
            osg::ref_ptr<TranslateInLineCommand> cmd = new TranslateInLineCommand(_projector->getLineStart(),
                    _projector->getLineEnd());

            cmd->setStage(MotionCommand::FINISH);
            cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());

            // Dispatch command.
            dispatch(*cmd);

            // Reset color.
            setMaterialColor(_color,*this);

            aa.requestRedraw();
        }

        return true;
    }
    default:
        return false;
    }
}
コード例 #25
0
ファイル: Draggers.cpp プロジェクト: InterAtlas-ML/osgearth
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;
    if (!_mapNode.valid()) return false;

    if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            _dragging = true;

            //Check for and handle vertical dragging if necessary
            bool pressedAlt = _modKeyMask && (ea.getModKeyMask() & _modKeyMask) > 0;
            _elevationDragging = (_defaultMode == Dragger::DRAGMODE_VERTICAL && !pressedAlt) || (_defaultMode == Dragger::DRAGMODE_HORIZONTAL && pressedAlt);

            if (_elevationDragging)
            {
              _pointer.reset();

              // set movement range
              // TODO: values 0.0 and 300000.0 are rather experimental
              GeoPoint posStart(_position.getSRS(), _position.x(), _position.y(), 0.0, ALTMODE_ABSOLUTE);
              osg::Vec3d posStartXYZ;
              posStart.toWorld(posStartXYZ);

              GeoPoint posEnd(_position.getSRS(), _position.x(), _position.y(), 300000.0, ALTMODE_ABSOLUTE);
              osg::Vec3d posEndXYZ;
              posEnd.toWorld(posEndXYZ);

              _projector->setLine(posStartXYZ, posEndXYZ);

              // set camera
              osgUtil::LineSegmentIntersector::Intersections intersections;
              osg::Node::NodeMask intersectionMask = 0xffffffff;
              osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
              if (view->computeIntersections(ea.getX(),ea.getY(),intersections, intersectionMask))
              {
                  for (osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); hitr != intersections.end(); ++hitr)
                  {
                      _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint());
                  }

                  bool draggerFound = false;
                  for (osgManipulator::PointerInfo::IntersectionList::iterator piit = _pointer._hitList.begin(); piit != _pointer._hitList.end(); ++piit)
                  {
                      for (osg::NodePath::iterator itr = piit->first.begin(); itr != piit->first.end(); ++itr)
                      {
                          Dragger* dragger = dynamic_cast<Dragger*>(*itr);
                          if (dragger==this)
                          {
                            draggerFound = true;
                              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());

                              break;
                          }
                      }

                      if (draggerFound)
                        break;
                  }
              }
            }

            aa.requestRedraw();
            return true;
        }
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
    {
        _elevationDragging = false;

        if ( _dragging )
        {
            _dragging = false;
            firePositionChanged();
        }

        aa.requestRedraw();
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
    {
        if (_elevationDragging) 
        {
            _pointer._hitIter = _pointer._hitList.begin();
            _pointer.setMousePosition(ea.getX(), ea.getY());

            if (_projector->project(_pointer, _startProjectedPoint)) 
            {
                //Get the absolute mapPoint that they've drug it to.
                GeoPoint projectedPos;
                projectedPos.fromWorld(_position.getSRS(), _startProjectedPoint);

                // make sure point is not dragged down below
                // TODO: think of a better solution / HeightAboveTerrain performance issues?
                if (projectedPos.z() >= _verticalMinimum)
                {
                    //If the current position is relative, we need to convert the absolute world point to relative.
                    //If the point is absolute then just emit the absolute point.
                    if (_position.altitudeMode() == ALTMODE_RELATIVE)
                    {
                        projectedPos.transformZ(ALTMODE_RELATIVE, getMapNode()->getTerrain());
                    }

                    setPosition( projectedPos );
                    aa.requestRedraw();
                }
            }

            return true;
        }
        
        if (_dragging)
        {
            osg::Vec3d world;
            if ( getMapNode() && getMapNode()->getTerrain()->getWorldCoordsUnderMouse(view, ea.getX(), ea.getY(), world) )
            {
                //Get the absolute mapPoint that they've drug it to.
                GeoPoint mapPoint;
                mapPoint.fromWorld( getMapNode()->getMapSRS(), world );
                //_mapNode->getMap()->worldPointToMapPoint(world, mapPoint);

                //If the current position is relative, we need to convert the absolute world point to relative.
                //If the point is absolute then just emit the absolute point.
                if (_position.altitudeMode() == ALTMODE_RELATIVE)
                {
                    mapPoint.alt() = _position.alt();
                    mapPoint.altitudeMode() = ALTMODE_RELATIVE;
                }

                setPosition( mapPoint );
                aa.requestRedraw();
                return true;
            }
        }
    }   
    else if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            setHover( true );
        }
        else
        {
            setHover( false );
        }        
        aa.requestRedraw();
    }
    return false;
}
コード例 #26
0
ファイル: Scale1DDragger.cpp プロジェクト: yueying/osg
bool Scale1DDragger::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;

    switch (ea.getEventType())
    {
        // Pick start.
        case (osgGA::GUIEventAdapter::PUSH):
            {
                // Get the LocalToWorld matrix for this node and set it for the projector.
                osg::NodePath nodePathToRoot;
                computeNodePathToRoot(*this,nodePathToRoot);
                osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
                _projector->setLocalToWorld(localToWorld);

                if (_projector->project(pointer, _startProjectedPoint))
                {
                    _scaleCenter = 0.0;
                    if (_scaleMode == SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT)
                    {
                        if ( pointer.contains(_leftHandleNode.get()) )
                            _scaleCenter = _projector->getLineEnd()[0];
                        else if ( pointer.contains( _rightHandleNode.get()) )
                            _scaleCenter = _projector->getLineStart()[0];
                    }

                    // Generate the motion command.
                    osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();
                    cmd->setStage(MotionCommand::START);
                    cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());

                    // Dispatch command.
                    dispatch(*cmd);

                    // Set color to pick color.
                    setMaterialColor(_pickColor,*this);

                    aa.requestRedraw();
                }
                return true;
            }

        // Pick move.
        case (osgGA::GUIEventAdapter::DRAG):
            {
                osg::Vec3d projectedPoint;
                if (_projector->project(pointer, projectedPoint))
                {
                    // Generate the motion command.
                    osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();

                    // Compute scale.
                    double scale = computeScale(_startProjectedPoint,projectedPoint,_scaleCenter);
                    if (scale < getMinScale()) scale = getMinScale();

                    // Snap the referencePoint to the line start or line end depending on which is closer.
                    double referencePoint = _startProjectedPoint[0];
                    if (fabs(_projector->getLineStart()[0] - referencePoint) <
                        fabs(_projector->getLineEnd()[0]   - referencePoint))
                        referencePoint = _projector->getLineStart()[0];
                    else
                        referencePoint = _projector->getLineEnd()[0];

                    cmd->setStage(MotionCommand::MOVE);
                    cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
                    cmd->setScale(scale);
                    cmd->setScaleCenter(_scaleCenter);
                    cmd->setReferencePoint(referencePoint);
                    cmd->setMinScale(getMinScale());

                    // Dispatch command.
                    dispatch(*cmd);

                    aa.requestRedraw();
                }
                return true;
            }

        // Pick finish.
        case (osgGA::GUIEventAdapter::RELEASE):
            {
                osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();

                cmd->setStage(MotionCommand::FINISH);
                cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());

                // Dispatch command.
                dispatch(*cmd);

                // Reset color.
                setMaterialColor(_color,*this);

                aa.requestRedraw();

                return true;
            }
        default:
            return false;
    }
}
コード例 #27
0
bool ElevationDragger::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    bool ret = true;
    if (ea.getHandled()) {
        ret = false;
    }
    else
    {
        bool handled = false;
        if (_elevationMode)
        {
            if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
            {
                ret = osgEarth::Dragger::handle(ea, aa);
                if (ret) 
                {
                    bool pressedAlt = ((ea.getModKeyMask() & _modKeyMask) > 0);
                    if (pressedAlt)
                    {
                        _pointer.reset();

                        // set movement range
                        // TODO: values 0.0 and 300000.0 are rather experimental
                        GeoPoint posStart(_position.getSRS(), _position.x(), _position.y(), 0.0, ALTMODE_ABSOLUTE);
                        osg::Vec3d posStartXYZ;
                        posStart.toWorld(posStartXYZ);

                        GeoPoint posEnd(_position.getSRS(), _position.x(), _position.y(), 300000.0, ALTMODE_ABSOLUTE);
                        osg::Vec3d posEndXYZ;
                        posEnd.toWorld(posEndXYZ);

                        _projector->setLine(posStartXYZ, posEndXYZ);

                        // set camera
                        osgUtil::LineSegmentIntersector::Intersections intersections;
                        osg::Node::NodeMask intersectionMask = 0xffffffff;
                        osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
                        if (view->computeIntersections(ea.getX(),ea.getY(),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)
                            {
                                ElevationDragger* dragger = dynamic_cast<ElevationDragger*>(*itr);
                                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());
                                }
                            }
                        }

                        _elevationDragging = true;
                    }
                }
                handled = true;
            }
            else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
            {
                _elevationDragging = false;
            }
            else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG) 
            {
                if (_elevationDragging) 
                {
                    _pointer._hitIter = _pointer._hitList.begin();
                    _pointer.setMousePosition(ea.getX(), ea.getY());

                    if (_projector->project(_pointer, _startProjectedPoint)) 
                    {
                        //Get the absolute mapPoint that they've drug it to.
                        GeoPoint projectedPos;
                        projectedPos.fromWorld(_position.getSRS(), _startProjectedPoint);

                        // make sure point is not dragged down below
                        // TODO: think of a better solution / HeightAboveTerrain performance issues?
                        if (projectedPos.z() > 0)
                        {
                            //If the current position is relative, we need to convert the absolute world point to relative.
                            //If the point is absolute then just emit the absolute point.
                            if (_position.altitudeMode() == ALTMODE_RELATIVE)
                            {
                                projectedPos.alt() = _position.alt();
                                projectedPos.altitudeMode() = ALTMODE_RELATIVE;
                            }

                            setPosition( projectedPos );
                            aa.requestRedraw();
                        }
                    }

                    handled = true;
                }
            }
        }
        
        if (!handled) {
            ret = osgEarth::Dragger::handle(ea, aa);
        }
    }
    return ret;
}
コード例 #28
0
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;
    if (!_mapNode.valid()) return false;

    if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            _dragging = true;
            aa.requestRedraw();
            return true;
        }
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
    {
        _dragging = false;
        aa.requestRedraw();
    }
    else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
    {
        if (_dragging)
        {
            osg::Vec3d world;
            if ( _mapNode->getTerrain()->getWorldCoordsUnderMouse(view, ea.getX(), ea.getY(), world) )
            {
                //Get the absolute mapPoint that they've drug it to.
                GeoPoint mapPoint;
                mapPoint.fromWorld( _mapNode->getMapSRS(), world );
                //_mapNode->getMap()->worldPointToMapPoint(world, mapPoint);

                //If the current position is relative, we need to convert the absolute world point to relative.
                //If the point is absolute then just emit the absolute point.
                if (_position.altitudeMode() == ALTMODE_RELATIVE)
                {
                    mapPoint.alt() = _position.alt();
                    mapPoint.altitudeMode() = ALTMODE_RELATIVE;
                }
                setPosition( mapPoint );
                aa.requestRedraw();
                return true;
            }
        }
    }   
    else if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE)
    {
        Picker picker( view, this );
        Picker::Hits hits;

        if ( picker.pick( ea.getX(), ea.getY(), hits ) )
        {
            setHover( true );
        }
        else
        {
            setHover( false );
        }        
        aa.requestRedraw();
    }
    return false;
}
コード例 #29
0
bool RotateCylinderDragger::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;

    switch (ea.getEventType())
    {
        // Pick start.
        case (osgGA::GUIEventAdapter::PUSH):
            {
                // Get the LocalToWorld matrix for this node and set it for the projector.
                osg::NodePath nodePathToRoot;
                computeNodePathToRoot(*this,nodePathToRoot);
                osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
                _projector->setLocalToWorld(localToWorld);

                _startLocalToWorld = _projector->getLocalToWorld();
                _startWorldToLocal = _projector->getWorldToLocal();

                if (_projector->isPointInFront(pointer, _startLocalToWorld))
                    _projector->setFront(true);
                else
                    _projector->setFront(false);

                osg::Vec3d projectedPoint;
                if (_projector->project(pointer, projectedPoint))
                {
                    // Generate the motion command.
                    osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
                    cmd->setStage(MotionCommand::START);
                    cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);

                    // Dispatch command.
                    dispatch(*cmd);

                    // Set color to pick color.
                    setMaterialColor(_pickColor,*this);

                    _prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
                    _prevRotation = osg::Quat();

                    aa.requestRedraw();
                }
                return true;
            }

        // Pick move.
        case (osgGA::GUIEventAdapter::DRAG):
            {
                // Get the LocalToWorld matrix for this node and set it for the projector.
                osg::Matrix localToWorld = osg::Matrix(_prevRotation) * _startLocalToWorld;
                _projector->setLocalToWorld(localToWorld);

                osg::Vec3d projectedPoint;
                if (_projector->project(pointer, projectedPoint))
                {
                    osg::Vec3d prevProjectedPoint = _prevWorldProjPt * _projector->getWorldToLocal();
                    osg::Quat  deltaRotation = _projector->getRotation(prevProjectedPoint,
                                                                      projectedPoint);
                    osg::Quat rotation = deltaRotation * _prevRotation;

                    // Generate the motion command.
                    osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
                    cmd->setStage(MotionCommand::MOVE);
                    cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
                    cmd->setRotation(rotation);

                    // Dispatch command.
                    dispatch(*cmd);

                    _prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
                    _prevRotation = rotation;
                    aa.requestRedraw();
                }
                return true;
            }

        // Pick finish.
        case (osgGA::GUIEventAdapter::RELEASE):
            {
                osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();

                cmd->setStage(MotionCommand::FINISH);
                cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);

                // Dispatch command.
                dispatch(*cmd);

                // Reset color.
                setMaterialColor(_color,*this);

                aa.requestRedraw();

                return true;
            }
        default:
            return false;
    }
}
コード例 #30
0
bool AnimationPathManipulator::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us)
{
    if( !valid() ) return false;

    switch( ea.getEventType() )
    {
    case GUIEventAdapter::FRAME:
        if( _isPaused )
        {
            handleFrame( _pauseTime );
        }
        else
        {
            handleFrame( ea.getTime() );
        }
        return false;
    case GUIEventAdapter::KEYDOWN:
            if (ea.getKey()==' ')
            {
                _isPaused = false;
                _timeScale = 1.0;
                
                home(ea,us);
                us.requestRedraw();
                us.requestContinuousUpdate(false);
                
                return true;
            } 
            else if (ea.getKey()=='>')
            {
                double time = _isPaused ? _pauseTime : ea.getTime();
                double animationTime = (time+_timeOffset)*_timeScale;

                _timeScale *= 1.1;

                osg::notify(osg::NOTICE)<<"Animation speed = "<<_timeScale*100<<"%"<<std::endl;

                // adjust timeOffset so the current animationTime does change.
                _timeOffset = animationTime/_timeScale - time;
                
                return true;
            } 
            else if (ea.getKey()=='<')
            {
                double time = _isPaused ? _pauseTime : ea.getTime();
                double animationTime = (time+_timeOffset)*_timeScale;

                _timeScale /= 1.1;
                
                osg::notify(osg::NOTICE)<<"Animation speed = "<<_timeScale*100<<"%"<<std::endl;

                // adjust timeOffset so the current animationTime does change.
                _timeOffset = animationTime/_timeScale - time;
                
                return true;
            } 
            else if(ea.getKey() == 'p')
            {
                if( _isPaused )
                {
                    _isPaused = false;
                    _timeOffset -= ea.getTime() - _pauseTime;
                }
                else
                {
                    _isPaused = true;
                    _pauseTime = ea.getTime();
                }
                us.requestRedraw();
                us.requestContinuousUpdate(false);
                return true;
            }
                
        break;
        default:
            break;
    }
    return false;
}