void DesktopDeviceNavigationTool::display(GLContextData& contextData) const
	{
	if(factory->showScreenCenter&&isActive())
		{
		Color bgColor=getBackgroundColor();
		Color fgColor;
		for(int i=0;i<3;++i)
			fgColor[i]=1.0f-bgColor[i];
		fgColor[3]=bgColor[3];
		ONTransform screenT=getMainScreen()->getScreenTransformation();
		Point screenCenter=screenT.transform(Point(getMainScreen()->getWidth()*Scalar(0.5),getMainScreen()->getHeight()*Scalar(0.5),Scalar(0)));
		Vector x=screenT.transform(Vector(getMainScreen()->getWidth()*Scalar(0.5),Scalar(0),Scalar(0)));
		Vector y=screenT.transform(Vector(Scalar(0),getMainScreen()->getHeight()*Scalar(0.5),Scalar(0)));
		glPushAttrib(GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT|GL_LINE_BIT);
		glDisable(GL_LIGHTING);
		glDepthFunc(GL_LEQUAL);
		glLineWidth(3.0f);
		glColor(bgColor);
		glBegin(GL_LINES);
		glVertex(screenCenter-x);
		glVertex(screenCenter+x);
		glVertex(screenCenter-y);
		glVertex(screenCenter+y);
		glEnd();
		glLineWidth(1.0f);
		glColor(fgColor);
		glBegin(GL_LINES);
		glVertex(screenCenter-x);
		glVertex(screenCenter+x);
		glVertex(screenCenter-y);
		glVertex(screenCenter+y);
		glEnd();
		glPopAttrib();
		}
	}
Example #2
0
Point FPSNavigationTool::calcMousePosition(void) const
	{
	if(mouseAdapter!=0)
		{
		/* Return the mouse position directly: */
		return Point(mouseAdapter->getMousePosition()[0],mouseAdapter->getMousePosition()[1],Scalar(0));
		}
	else
		{
		/* Get pointer to input device: */
		InputDevice* device=input.getDevice(0);

		/* Calculate ray equation: */
		Ray ray(device->getPosition(),device->getRayDirection());
		
		/* Intersect the ray with the main screen: */
		ONTransform screenT=getMainScreen()->getScreenTransformation();
		Vector screenNormal=screenT.getDirection(2);
		Scalar screenOffset=screenT.getOrigin()*screenNormal;
		Scalar lambda=(screenOffset-ray.getOrigin()*screenNormal)/(ray.getDirection()*screenNormal);
		
		/* Return the intersection point in screen coordinates: */
		return screenT.inverseTransform(ray(lambda));
		}
	}
Example #3
0
Point MouseNavigationTool::calcScreenPos(void) const
{
    /* Get pointer to input device: */
    InputDevice* device=input.getDevice(0);

    /* Calculate ray equation: */
    Point start=device->getPosition();
    Vector direction=device->getRayDirection();

    /* Find the screen currently containing the input device: */
    const VRScreen* screen;
    if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0)
        screen=mouseAdapter->getWindow()->getVRScreen();
    else
        screen=getMainScreen();

    /* Intersect ray with the screen: */
    ONTransform screenT=screen->getScreenTransformation();
    Vector normal=screenT.getDirection(2);
    Scalar d=normal*screenT.getOrigin();
    Scalar divisor=normal*direction;
    if(divisor==Scalar(0))
        return Point::origin;

    Scalar lambda=(d-start*normal)/divisor;
    if(lambda<Scalar(0))
        return Point::origin;

    return start+direction*lambda;
}
Point MouseDialogNavigationTool::calcScreenPos(void)
	{
	/* Calculate the ray equation: */
	Ray ray=getDeviceRay(0);
	
	/* Find the screen currently containing the input device: */
	const VRScreen* screen;
	if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0)
		screen=mouseAdapter->getWindow()->getVRScreen();
	else
		screen=getMainScreen();
	
	/* Intersect ray with the screen: */
	ONTransform screenT=screen->getScreenTransformation();
	Vector normal=screenT.getDirection(2);
	Scalar d=normal*screenT.getOrigin();
	Scalar divisor=normal*ray.getDirection();
	if(divisor==Scalar(0))
		return Point::origin;
	
	Scalar lambda=(d-ray.getOrigin()*normal)/divisor;
	if(lambda<Scalar(0))
		return Point::origin;
	
	return ray(lambda);
	}
Example #5
0
void FPSNavigationTool::initialize(void)
	{
	/* Get a pointer to the input device's controlling adapter: */
	mouseAdapter=dynamic_cast<InputDeviceAdapterMouse*>(getInputDeviceManager()->findInputDeviceAdapter(input.getDevice(0)));
	
	/* Initialize the navigation frame and current position/orientation: */
	ONTransform st=getMainScreen()->getScreenTransformation();
	navFrame=st.getRotation();
	}
Example #6
0
Point MouseNavigationTool::calcScreenCenter(void) const
{
    /* Determine the screen containing the input device and the screen's center: */
    const VRScreen* screen;
    Point centerPos;
    if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0)
    {
        screen=mouseAdapter->getWindow()->getVRScreen();
        mouseAdapter->getWindow()->getWindowCenterPos(centerPos.getComponents());
    }
    else
    {
        screen=getMainScreen();
        centerPos[0]=getMainScreen()->getWidth()*Scalar(0.5);
        centerPos[1]=getMainScreen()->getHeight()*Scalar(0.5);
    }
    centerPos[2]=Scalar(0);

    /* Calculate the center position in physical coordinates: */
    return screen->getScreenTransformation().transform(centerPos);
}
void MouseDialogNavigationTool::startRotating(void)
	{
	/* Calculate the rotation center: */
	screenCenter=calcScreenCenter();
	
	/* Calculate initial rotation position: */
	lastRotationPos=calcScreenPos();
	
	/* Calculate the rotation offset vector: */
	rotateOffset=getMainScreen()->getScreenTransformation().transform(Vector(0,0,factory->rotatePlaneOffset));
	
	preScale=NavTrackerState::translateFromOriginTo(screenCenter);
	rotation=NavTrackerState::identity;
	postScale=NavTrackerState::translateToOriginFrom(screenCenter);
	postScale*=getNavigationTransformation();
	}
ONTransform getMouseScreenTransform(InputDeviceAdapterMouse* mouseAdapter,Scalar viewport[4])
{
    /* Check if the mouse adapter is valid: */
    VRScreen* screen=0;
    if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0)
    {
        /* Use the window associated with the mouse adapter: */
        VRWindow* window=mouseAdapter->getWindow();
        screen=window->getVRScreen();
        window->getScreenViewport(viewport);
    }
    else
    {
        /* Use the main screen: */
        screen=getMainScreen();
        screen->getViewport(viewport);
    }

    /* Return the screen's transformation: */
    return screen->getScreenTransformation();
}
DesktopDeviceNavigationToolFactory::DesktopDeviceNavigationToolFactory(ToolManager& toolManager)
	:ToolFactory("DesktopDeviceNavigationTool",toolManager),
	 numButtons(0),buttonToggleFlags(0),buttonAxisShiftMasks(0),
	 numRotationAxes(0),rotationAxes(0),
	 rotateFactor(Scalar(1)),
	 numTranslationAxes(0),translationAxes(0),
	 translateFactor(getInchFactor()),
	 invertNavigation(false),
	 numZoomAxes(0),zoomAxes(0),
	 zoomFactor(Scalar(1)),
	 homeButtonIndex(-1),
	 showScreenCenter(false)
	{
	/* Load class settings: */
	typedef std::vector<int> IndexList;
	typedef std::vector<AxisDescriptor> AxisDescriptorList;
	Misc::ConfigurationFileSection cfs=toolManager.getToolClassSection(getClassName());
	
	/* Read number of buttons on raw device: */
	numButtons=cfs.retrieveValue<int>("./numButtons");
	buttonToggleFlags=new bool[numButtons];
	buttonAxisShiftMasks=new int[numButtons];
	for(int i=0;i<numButtons;++i)
		{
		buttonToggleFlags[i]=false;
		buttonAxisShiftMasks[i]=0x0;
		}
	
	/* Read list of toggle button indices: */
	IndexList toggleButtonIndices=cfs.retrieveValue<IndexList>("./toggleButtonIndices",IndexList());
	for(IndexList::const_iterator tbiIt=toggleButtonIndices.begin();tbiIt!=toggleButtonIndices.end();++tbiIt)
		{
		if(*tbiIt>=0&&*tbiIt<numButtons)
			buttonToggleFlags[*tbiIt]=true;
		else
			Misc::throwStdErr("DesktopDeviceNavigationTool: Toggle button index out of valid range");
		}
	
	/* Read list of axis shift button indices: */
	IndexList axisShiftButtonIndices=cfs.retrieveValue<IndexList>("./axisShiftButtonIndices",IndexList());
	int nextButtonMask=0x1;
	for(IndexList::const_iterator asbiIt=axisShiftButtonIndices.begin();asbiIt!=axisShiftButtonIndices.end();++asbiIt)
		{
		if(*asbiIt>=0&&*asbiIt<numButtons)
			{
			buttonAxisShiftMasks[*asbiIt]=nextButtonMask;
			nextButtonMask<<=1;
			}
		else
			Misc::throwStdErr("DesktopDeviceNavigationTool: Axis shift button index out of valid range");
		}
	
	/* Read number of valuators on raw device: */
	numValuators=cfs.retrieveValue<int>("./numValuators");
	
	/* Read list of rotational axis descriptors: */
	AxisDescriptorList rotationalAxisDescriptors=cfs.retrieveValue<AxisDescriptorList>("./rotationalAxes");
	numRotationAxes=rotationalAxisDescriptors.size();
	rotationAxes=new AxisDescriptor[numRotationAxes];
	for(int i=0;i<numRotationAxes;++i)
		rotationAxes[i]=rotationalAxisDescriptors[i];
	rotateFactor=cfs.retrieveValue<Scalar>("./rotateFactor",rotateFactor);
	
	/* Read list of translational axis descriptors: */
	AxisDescriptorList translationalAxisDescriptors=cfs.retrieveValue<AxisDescriptorList>("./translationalAxes");
	numTranslationAxes=translationalAxisDescriptors.size();
	translationAxes=new AxisDescriptor[numTranslationAxes];
	for(int i=0;i<numTranslationAxes;++i)
		translationAxes[i]=translationalAxisDescriptors[i];
	translateFactor=cfs.retrieveValue<Scalar>("./translateFactor",translateFactor);
	
	/* Get navigation button index: */
	navigationButtonIndex=cfs.retrieveValue<int>("./navigationButtonIndex",numButtons-1);
	
	/* Read navigation mode flag: */
	invertNavigation=cfs.retrieveValue<bool>("./invertNavigation",invertNavigation);
	
	/* Read list of zoom axis descriptors: */
	AxisDescriptorList zoomAxisDescriptors=cfs.retrieveValue<AxisDescriptorList>("./zoomAxes");
	numZoomAxes=zoomAxisDescriptors.size();
	zoomAxes=new AxisDescriptor[numZoomAxes];
	for(int i=0;i<numZoomAxes;++i)
		zoomAxes[i]=zoomAxisDescriptors[i];
	zoomFactor=cfs.retrieveValue<Scalar>("./zoomFactor",zoomFactor);
	
	/* Read the navigation center: */
	navigationCenter=getMainScreen()->getScreenTransformation().transform(Point(getMainScreen()->getWidth()*Scalar(0.5),getMainScreen()->getHeight()*Scalar(0.5),Scalar(0)));
	navigationCenter=cfs.retrieveValue<Point>("./navigationCenter",navigationCenter);
	
	/* Get home button index: */
	homeButtonIndex=cfs.retrieveValue<int>("./homeButtonIndex",homeButtonIndex);
	
	/* Configure device glyph for virtual DesktopDevice device: */
	deviceGlyph.configure(cfs,"./deviceGlyphType","./deviceGlyphMaterial");
	
	showScreenCenter=cfs.retrieveValue<bool>("./showScreenCenter",showScreenCenter);
	
	/* Initialize tool layout: */
	layout.setNumDevices(1);
	layout.setNumButtons(0,numButtons);
	layout.setNumValuators(0,numValuators);
	
	/* Insert class into class hierarchy: */
	ToolFactory* toolFactory=toolManager.loadClass("NavigationTool");
	toolFactory->addChildClass(this);
	addParentClass(toolFactory);
	
	/* Set tool class' factory pointer: */
	DesktopDeviceNavigationTool::factory=this;
	}
Example #10
0
void MouseNavigationTool::display(GLContextData& contextData) const
{
    bool gotoScreenCoords=factory->showMouseCursor||(factory->showScreenCenter&&navigationMode!=IDLE&&navigationMode!=WIDGETING);
    const VRScreen* screen=0;
    ONTransform screenT;
    if(gotoScreenCoords)
    {
        /* Get a pointer to the screen the mouse is on: */
        if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0)
            screen=mouseAdapter->getWindow()->getVRScreen();
        else
            screen=getMainScreen();
        screenT=screen->getScreenTransformation();

        /* Save and set up OpenGL state: */
        glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT|GL_LINE_BIT|GL_TEXTURE_BIT);
        glDisable(GL_LIGHTING);

        /* Go to screen coordinates: */
        glPushMatrix();
        glMultMatrix(screenT);
    }

    if(factory->showScreenCenter&&navigationMode!=IDLE&&navigationMode!=WIDGETING)
    {
        /* Determine the screen containing the input device and find its center: */
        Scalar centerPos[2];
        if(mouseAdapter!=0)
            mouseAdapter->getWindow()->getWindowCenterPos(centerPos);
        else
        {
            centerPos[0]=getMainScreen()->getWidth()*Scalar(0.5);
            centerPos[1]=getMainScreen()->getHeight()*Scalar(0.5);
        }

        /* Calculate the endpoints of the screen's crosshair lines in screen coordinates: */
        Point l=Point(Scalar(0),centerPos[1],Scalar(0));
        Point r=Point(screen->getWidth(),centerPos[1],Scalar(0));
        Point b=Point(centerPos[0],Scalar(0),Scalar(0));
        Point t=Point(centerPos[0],screen->getHeight(),Scalar(0));

        /* Determine the crosshair colors: */
        Color bgColor=getBackgroundColor();
        Color fgColor;
        for(int i=0; i<3; ++i)
            fgColor[i]=1.0f-bgColor[i];
        fgColor[3]=bgColor[3];

        /* Draw the screen crosshairs: */
        glDepthFunc(GL_LEQUAL);
        glLineWidth(3.0f);
        glColor(bgColor);
        glBegin(GL_LINES);
        glVertex(l);
        glVertex(r);
        glVertex(b);
        glVertex(t);
        glEnd();
        glLineWidth(1.0f);
        glColor(fgColor);
        glBegin(GL_LINES);
        glVertex(l);
        glVertex(r);
        glVertex(b);
        glVertex(t);
        glEnd();
    }

    if(factory->showMouseCursor)
    {
        /* Get the data item: */
        DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this);

        /* Calculate the mouse position: */
        Point mousePos=screenT.inverseTransform(currentPos);
        for(int i=0; i<2; ++i)
            mousePos[i]-=factory->mouseCursorHotspot[i]*factory->mouseCursorSize[i];

        /* Draw the mouse cursor: */
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D,dataItem->textureObjectId);
        glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
        glEnable(GL_ALPHA_TEST);
        glAlphaFunc(GL_GEQUAL,0.5f);
        glBegin(GL_QUADS);
        glTexCoord(mouseCursorTexCoordBox.getVertex(0));
        glVertex(mousePos[0],mousePos[1]);
        glTexCoord(mouseCursorTexCoordBox.getVertex(1));
        glVertex(mousePos[0]+factory->mouseCursorSize[0],mousePos[1]);
        glTexCoord(mouseCursorTexCoordBox.getVertex(3));
        glVertex(mousePos[0]+factory->mouseCursorSize[0],mousePos[1]+factory->mouseCursorSize[1]);
        glTexCoord(mouseCursorTexCoordBox.getVertex(2));
        glVertex(mousePos[0],mousePos[1]+factory->mouseCursorSize[1]);
        glEnd();
        glBindTexture(GL_TEXTURE_2D,0);
    }

    if(gotoScreenCoords)
    {
        /* Go back to physical coordinates: */
        glPopMatrix();

        /* Restore OpenGL state: */
        glPopAttrib();
    }
}
Example #11
0
void MouseNavigationTool::frame(void)
{
    /* Update the current mouse position: */
    currentPos=calcScreenPos();

    /* Act depending on this tool's current state: */
    switch(navigationMode)
    {
    case IDLE:
        /* Do nothing */
        break;

    case WIDGETING:
    {
        /* Deliver the event: */
        GLMotif::Event event(true);
        event.setWorldLocation(calcSelectionRay());
        getWidgetManager()->pointerMotion(event);

        if(draggedWidget!=0)
        {
            /* Update the dragged widget's transformation: */
            NavTrackerState current=NavTrackerState::translateFromOriginTo(calcScreenPos());
            current*=preScale;
            getWidgetManager()->setPrimaryWidgetTransformation(draggedWidget,GLMotif::WidgetManager::Transformation(current));
        }
        break;
    }

    case ROTATING:
    {
        /* Calculate the rotation position: */
        Vector offset=(lastRotationPos-screenCenter)+rotateOffset;

        /* Calculate mouse displacement vector: */
        Point rotationPos=currentPos;
        Vector delta=rotationPos-lastRotationPos;
        lastRotationPos=rotationPos;

        /* Calculate incremental rotation: */
        Vector axis=Geometry::cross(offset,delta);
        Scalar angle=Geometry::mag(delta)/factory->rotateFactor;
        if(angle!=Scalar(0))
            rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateAxis(axis,angle)));

        NavTrackerState t=preScale;
        t*=rotation;
        t*=postScale;
        setNavigationTransformation(t);
        break;
    }

    case SPINNING:
    {
        /* Calculate incremental rotation: */
        rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(spinAngularVelocity*getCurrentFrameTime())));

        NavTrackerState t=preScale;
        t*=rotation;
        t*=postScale;
        setNavigationTransformation(t);
        break;
    }

    case PANNING:
    {
        /* Update the navigation transformation: */
        NavTrackerState t=NavTrackerState::translate(currentPos-motionStart);
        t*=preScale;
        setNavigationTransformation(t);
        break;
    }

    case DOLLYING:
    {
        /* Calculate the current dollying direction: */
        Vector dollyingDirection;
        if(mouseAdapter!=0)
            dollyingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenDollyingDirection);
        else
            dollyingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenDollyingDirection);

        /* Update the navigation transformation: */
        Scalar dollyDist=((currentPos-motionStart)*dollyingDirection)/factory->dollyFactor;
        NavTrackerState t=NavTrackerState::translate(dollyDirection*dollyDist);
        t*=preScale;
        setNavigationTransformation(t);
        break;
    }

    case SCALING:
    {
        /* Calculate the current scaling direction: */
        Vector scalingDirection;
        if(mouseAdapter!=0)
            scalingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenScalingDirection);
        else
            scalingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenScalingDirection);

        /* Update the navigation transformation: */
        Scalar scale=((currentPos-motionStart)*scalingDirection)/factory->scaleFactor;
        NavTrackerState t=preScale;
        t*=NavTrackerState::scale(Math::exp(scale));
        t*=postScale;
        setNavigationTransformation(t);
        break;
    }

    case DOLLYING_WHEEL:
    {
        /* Update the navigation transformation: */
        Scalar scale=currentValue;
        currentWheelScale+=factory->wheelDollyFactor*scale;
        NavTrackerState t=NavTrackerState::translate(dollyDirection*currentWheelScale);
        t*=preScale;
        setNavigationTransformation(t);
        break;
    }

    case SCALING_WHEEL:
    {
        /* Update the navigation transformation: */
        Scalar scale=currentValue;
        currentWheelScale*=Math::pow(factory->wheelScaleFactor,scale);
        NavTrackerState t=preScale;
        t*=NavTrackerState::scale(currentWheelScale);
        t*=postScale;
        setNavigationTransformation(t);
        break;
    }
    }
}
void MouseDialogNavigationTool::display(GLContextData& contextData) const
	{
	if(showScreenCenter)
		{
		/* Save and set up OpenGL state: */
		glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT|GL_LINE_BIT|GL_TEXTURE_BIT);
		glDisable(GL_LIGHTING);
		
		/* Get a pointer to the screen the mouse is on: */
		const VRScreen* screen;
		if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0)
			screen=mouseAdapter->getWindow()->getVRScreen();
		else
			screen=getMainScreen();
		ONTransform screenT=screen->getScreenTransformation();
		
		/* Go to screen coordinates: */
		glPushMatrix();
		glMultMatrix(screenT);
		
		/* Determine the screen containing the input device and find its center: */
		Scalar centerPos[2];
		if(mouseAdapter!=0)
			mouseAdapter->getWindow()->getWindowCenterPos(centerPos);
		else
			{
			centerPos[0]=getMainScreen()->getWidth()*Scalar(0.5);
			centerPos[1]=getMainScreen()->getHeight()*Scalar(0.5);
			}
		
		/* Calculate the endpoints of the screen's crosshair lines in screen coordinates: */
		Point l=Point(Scalar(0),centerPos[1],Scalar(0));
		Point r=Point(screen->getWidth(),centerPos[1],Scalar(0));
		Point b=Point(centerPos[0],Scalar(0),Scalar(0));
		Point t=Point(centerPos[0],screen->getHeight(),Scalar(0));
		
		/* Determine the crosshair colors: */
		Color bgColor=getBackgroundColor();
		Color fgColor;
		for(int i=0;i<3;++i)
			fgColor[i]=1.0f-bgColor[i];
		fgColor[3]=bgColor[3];
		
		/* Draw the screen crosshairs: */
		glDepthFunc(GL_LEQUAL);
		glLineWidth(3.0f);
		glColor(bgColor);
		glBegin(GL_LINES);
		glVertex(l);
		glVertex(r);
		glVertex(b);
		glVertex(t);
		glEnd();
		glLineWidth(1.0f);
		glColor(fgColor);
		glBegin(GL_LINES);
		glVertex(l);
		glVertex(r);
		glVertex(b);
		glVertex(t);
		glEnd();
		
		/* Go back to physical coordinates: */
		glPopMatrix();
		
		/* Restore OpenGL state: */
		glPopAttrib();
		}
	}
void MouseDialogNavigationTool::frame(void)
	{
	/* Update the current mouse position: */
	currentPos=calcScreenPos();
	
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		if(spinning)
			{
			/* Calculate incremental rotation: */
			rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(spinAngularVelocity*getFrameTime())));
			
			NavTrackerState t=preScale;
			t*=rotation;
			t*=postScale;
			setNavigationTransformation(t);
			}
		else
			{
			switch(navigationMode)
				{
				case ROTATING:
					{
					/* Calculate the rotation position: */
					Vector offset=(lastRotationPos-screenCenter)+rotateOffset;
					
					/* Calculate mouse displacement vector: */
					Point rotationPos=currentPos;
					Vector delta=rotationPos-lastRotationPos;
					lastRotationPos=rotationPos;
					
					/* Calculate incremental rotation: */
					Vector axis=Geometry::cross(offset,delta);
					Scalar angle=Geometry::mag(delta)/factory->rotateFactor;
					if(angle!=Scalar(0))
						rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateAxis(axis,angle)));
					
					NavTrackerState t=preScale;
					t*=rotation;
					t*=postScale;
					setNavigationTransformation(t);
					break;
					}
				
				case PANNING:
					{
					/* Update the navigation transformation: */
					NavTrackerState t=NavTrackerState::translate(currentPos-motionStart);
					t*=preScale;
					setNavigationTransformation(t);
					break;
					}
				
				case DOLLYING:
					{
					/* Calculate the current dollying direction: */
					Vector dollyingDirection;
					if(mouseAdapter!=0)
						dollyingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenDollyingDirection);
					else
						dollyingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenDollyingDirection);
					
					/* Update the navigation transformation: */
					Scalar dollyDist=((currentPos-motionStart)*dollyingDirection)/factory->dollyFactor;
					NavTrackerState t=NavTrackerState::translate(dollyDirection*dollyDist);
					t*=preScale;
					setNavigationTransformation(t);
					break;
					}
				
				case SCALING:
					{
					/* Calculate the current scaling direction: */
					Vector scalingDirection;
					if(mouseAdapter!=0)
						scalingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenScalingDirection);
					else
						scalingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenScalingDirection);
					
					/* Update the navigation transformation: */
					Scalar scale=((currentPos-motionStart)*scalingDirection)/factory->scaleFactor;
					NavTrackerState t=preScale;
					t*=NavTrackerState::scale(Math::exp(scale));
					t*=postScale;
					setNavigationTransformation(t);
					break;
					}
				}
			}
		}
	}