void SixAxisTransformTool::frame(void)
{
    /* Assemble translation from translation vectors and current valuator values: */
    Vector translation=Vector::zero;
    for(int i=0; i<3; ++i)
        translation+=translations[i]*Scalar(getValuatorState(i));
    translation*=getCurrentFrameTime();

    /* Assemble rotation from scaled rotation axes and current valuator values: */
    Vector rotation=Vector::zero;
    for(int i=0; i<3; ++i)
        rotation+=config.rotations[i]*Scalar(getValuatorState(3+i));
    rotation*=getCurrentFrameTime();

    /* Calculate an incremental transformation for the virtual input device: */
    ONTransform deltaT=ONTransform::translate(translation);
    Point pos=transformedDevice->getPosition();
    deltaT*=ONTransform::translateFromOriginTo(pos);
    deltaT*=ONTransform::rotate(ONTransform::Rotation::rotateScaledAxis(rotation));
    deltaT*=ONTransform::translateToOriginFrom(pos);

    /* Update the virtual input device's transformation: */
    deltaT*=transformedDevice->getTransformation();
    deltaT.renormalize();
    transformedDevice->setTransformation(deltaT);

    /* Request another frame if the input device has moved: */
    if(translation!=Vector::zero||rotation!=Vector::zero)
    {
        /* Request another frame: */
        scheduleUpdate(getApplicationTime()+1.0/125.0);
    }
}
void SixAxisNavigationTool::frame(void)
	{
	if(isActive())
		{
		/* Assemble translation from translation vectors and current valuator values: */
		Vector translation=Vector::zero;
		for(int i=0;i<3;++i)
			translation+=translations[i]*Scalar(getValuatorState(i));
		translation*=getCurrentFrameTime();
		
		/* Assemble rotation from scaled rotation axes and current valuator values: */
		Vector rotation=Vector::zero;
		for(int i=0;i<3;++i)
			rotation+=rotations[i]*Scalar(getValuatorState(3+i));
		rotation*=getCurrentFrameTime();
		
		/* Calculate incremental zoom factor: */
		Scalar zoom=config.zoomFactor*Scalar(getValuatorState(6))*getCurrentFrameTime();
		
		/* Apply proper navigation mode: */
		if(config.invertNavigation)
			{
			translation=-translation;
			rotation=-rotation;
			zoom=-zoom;
			}
		
		/* Calculate an incremental transformation based on the translation and rotation: */
		NavTrackerState deltaT=NavTrackerState::translateFromOriginTo(config.followDisplayCenter?getDisplayCenter():config.navigationCenter);
		deltaT*=NavTrackerState::translate(translation);
		deltaT*=NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(rotation));
		deltaT*=NavTrackerState::scale(Math::exp(-zoom));
		deltaT*=NavTrackerState::translateToOriginFrom(config.followDisplayCenter?getDisplayCenter():config.navigationCenter);
		
		/* Update the accumulated transformation: */
		navTransform.leftMultiply(deltaT);
		navTransform.renormalize();
		
		/* Update the navigation transformation: */
		setNavigationTransformation(navTransform);
		
		/* Request another frame: */
		scheduleUpdate(getApplicationTime()+1.0/125.0);
		}
	}
Exemplo n.º 3
0
 void
 Time::show
 ()
 {
     getLog()->trace
     (
        "CurrentTime: {}, LastTime: {}, DeltaTime: {}" ,
        getCurrentFrameTime(),
        getLastFrameTime(),
        getFrameTimeDelta()
     );
 }
Exemplo n.º 4
0
void FPSNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		/* Calculate the change in mouse position: */
		Point mousePos=calcMousePosition();
		if(mousePos[0]!=lastMousePos[0]||mousePos[1]!=lastMousePos[1]||moveVelocity[0]!=Scalar(0)||moveVelocity[2]!=Scalar(0))
			{
			angles[0]+=(mousePos[0]-lastMousePos[0])/factory->rotateFactor;
			angles[0]=Math::wrapRad(angles[0]);
			angles[1]+=(mousePos[1]-lastMousePos[1])/factory->rotateFactor;
			if(angles[1]<Math::rad(Scalar(-90)))
				angles[1]=Math::rad(Scalar(-90));
			else if(angles[1]>Math::rad(Scalar(90)))
				angles[1]=Math::rad(Scalar(90));
			
			/* Calculate the new orientation and move by the current velocity: */
			ONTransform::Rotation yawT=ONTransform::Rotation::rotateY(angles[0]);
			ONTransform::Rotation rot=navFrame;
			rot*=ONTransform::Rotation::rotateX(angles[1]);
			rot*=yawT;
			pos+=yawT.inverseTransform(moveVelocity*getCurrentFrameTime());
			
			/* Set the new navigation transformation: */
			NavTransform nav=NavTransform::translateFromOriginTo(getMainViewer()->getHeadPosition());
			nav*=NavTransform::rotate(rot);
			nav*=NavTransform::translateToOriginFrom(getMainViewer()->getHeadPosition());
			nav*=NavTransform::translateFromOriginTo(pos);
			nav*=preScale;
			setNavigationTransformation(nav);
			
			if(mousePos[0]!=lastMousePos[0]||mousePos[1]!=lastMousePos[1])
				{
				if(mouseAdapter!=0)
					{
					/* Warp the cursor back to the center of the window: */
					mouseAdapter->getWindow()->setCursorPos(lastMousePos.getComponents());
					}
				else
					lastMousePos=mousePos;
				}
			}
		}
	}
void ValuatorFlyNavigationTool::frame(void)
{
    /* Act depending on this tool's current state: */
    if(isActive())
    {
        /* Get the current state of the input device: */
        const TrackerState& ts=input.getDevice(0)->getTransformation();

        /* Calculate the current flying velocity: */
        Vector v=ts.transform(factory->flyDirection);
        v*=currentValue*factory->flyFactor*getCurrentFrameTime();

        /* Compose the new navigation transformation: */
        NavTransform t=NavTransform::translate(v);
        t*=getNavigationTransformation();

        /* Update Vrui's navigation transformation: */
        setNavigationTransformation(t);
    }
}
void SixAxisSurfaceNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		/* Use the average frame time as simulation time: */
		Scalar dt=getCurrentFrameTime();
		
		/* Update rotation angles based on current rotation valuator states: */
		for(int i=0;i<3;++i)
			angles[i]=wrapAngle(angles[i]+getValuatorState(i+3)*factory->rotateFactors[i]*dt);
		if(angles[1]<Math::rad(Scalar(-90)))
			angles[1]=Math::rad(Scalar(-90));
		else if(angles[1]>Math::rad(Scalar(90)))
			angles[1]=Math::rad(Scalar(90));
		if(!factory->canRoll||factory->bankTurns)
			{
			Scalar targetRoll=factory->bankTurns?getValuatorState(3)*factory->rotateFactors[2]:Scalar(0);
			Scalar t=Math::exp(-factory->levelSpeed*dt);
			angles[2]=angles[2]*t+targetRoll*(Scalar(1)-t);
			if(Math::abs(angles[2]-targetRoll)<Scalar(1.0e-3))
				angles[2]=targetRoll;
			}
		
		/* Calculate the new head position: */
		Point newHeadPos=getMainViewer()->getHeadPosition();
		
		/* Create a physical navigation frame around the new foot position: */
		calcPhysicalFrame(newHeadPos);
		
		/* Calculate movement from head position change: */
		Vector move=newHeadPos-headPos;
		headPos=newHeadPos;
		
		/* Add movement velocity based on the current translation valuator states: */
		for(int i=0;i<3;++i)
			move[i]+=getValuatorState(i)*factory->translateFactors[i]*dt;
		
		/* Transform the movement vector from physical space to the physical navigation frame: */
		move=physicalFrame.inverseTransform(move);
		
		/* Rotate by the current azimuth and elevation angles: */
		move=Rotation::rotateX(-angles[1]).transform(move);
		move=Rotation::rotateZ(-angles[0]).transform(move);
		
		/* Move the surface frame: */
		NavTransform newSurfaceFrame=surfaceFrame;
		newSurfaceFrame*=NavTransform::translate(move);
		
		/* Re-align the surface frame with the surface: */
		Point initialOrigin=newSurfaceFrame.getOrigin();
		Rotation initialOrientation=newSurfaceFrame.getRotation();
		AlignmentData ad(surfaceFrame,newSurfaceFrame,factory->probeSize,factory->maxClimb);
		align(ad);
		
		if(!factory->fixAzimuth)
			{
			/* Have the azimuth angle track changes in the surface frame's rotation: */
			Rotation rot=Geometry::invert(initialOrientation)*newSurfaceFrame.getRotation();
			rot.leftMultiply(Rotation::rotateFromTo(rot.getDirection(2),Vector(0,0,1)));
			Vector x=rot.getDirection(0);
			angles[0]=wrapAngle(angles[0]+Math::atan2(x[1],x[0]));
			}
		
		/* If flying is allowed and the initial surface frame was above the surface, lift it back up: */
		Scalar z=newSurfaceFrame.inverseTransform(initialOrigin)[2];
		if(!factory->canFly||z<factory->probeSize)
			z=factory->probeSize;
		newSurfaceFrame*=NavTransform::translate(Vector(Scalar(0),Scalar(0),z));
		
		/* Apply the newly aligned surface frame: */
		surfaceFrame=newSurfaceFrame;
		applyNavState();
		
		/* Deactivate the tool if it is done: */
		if(numActiveAxes==0&&Math::abs(angles[2])<Math::Constants<Scalar>::epsilon)
			deactivate();
		else
			{
			/* Request another frame: */
			scheduleUpdate(getApplicationTime()+1.0/125.0);
			}
		}
	}
Exemplo n.º 7
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;
    }
    }
}
Exemplo n.º 8
0
void MouseNavigationTool::buttonCallback(int,int buttonIndex,InputDevice::ButtonCallbackData* cbData)
{
    /* Process based on which button was pressed: */
    switch(buttonIndex)
    {
    case 0:
        if(cbData->newButtonState) // Button has just been pressed
        {
            /* Act depending on this tool's current state: */
            switch(navigationMode)
            {
            case IDLE:
            case SPINNING:
                if(factory->interactWithWidgets)
                {
                    /* Check if the mouse pointer is over a GLMotif widget: */
                    GLMotif::Event event(false);
                    event.setWorldLocation(calcSelectionRay());
                    if(getWidgetManager()->pointerButtonDown(event))
                    {
                        if(navigationMode==SPINNING)
                        {
                            /* Deactivate this tool: */
                            deactivate();
                        }

                        /* Go to widget interaction mode: */
                        navigationMode=WIDGETING;

                        /* Drag the entire root widget if the event's target widget is a title bar: */
                        if(dynamic_cast<GLMotif::TitleBar*>(event.getTargetWidget())!=0)
                        {
                            /* Start dragging: */
                            draggedWidget=event.getTargetWidget();

                            /* Calculate the dragging transformation: */
                            NavTrackerState initialTracker=NavTrackerState::translateFromOriginTo(calcScreenPos());
                            preScale=Geometry::invert(initialTracker);
                            GLMotif::WidgetManager::Transformation initialWidget=getWidgetManager()->calcWidgetTransformation(draggedWidget);
                            preScale*=NavTrackerState(initialWidget);
                        }
                        else
                            draggedWidget=0;
                    }
                    else
                    {
                        /* Try activating this tool: */
                        if(navigationMode==SPINNING||activate())
                            startRotating();
                    }
                }
                else
                {
                    /* Try activating this tool: */
                    if(navigationMode==SPINNING||activate())
                        startRotating();
                }
                break;

            case PANNING:
                if(dolly)
                    startDollying();
                else
                    startScaling();
                break;

            default:
                /* This shouldn't happen; just ignore the event */
                break;
            }
        }
        else // Button has just been released
        {
            /* Act depending on this tool's current state: */
            switch(navigationMode)
            {
            case WIDGETING:
            {
                /* Deliver the event: */
                GLMotif::Event event(true);
                event.setWorldLocation(calcSelectionRay());
                getWidgetManager()->pointerButtonUp(event);

                /* Deactivate this tool: */
                navigationMode=IDLE;
                draggedWidget=0;
                break;
            }

            case ROTATING:
            {
                /* Check if the input device is still moving: */
                Point currentPos=calcScreenPos();
                Vector delta=currentPos-lastRotationPos;
                if(Geometry::mag(delta)>factory->spinThreshold)
                {
                    /* Calculate spinning angular velocity: */
                    Vector offset=(lastRotationPos-screenCenter)+rotateOffset;
                    Vector axis=Geometry::cross(offset,delta);
                    Scalar angularVelocity=Geometry::mag(delta)/(factory->rotateFactor*getCurrentFrameTime());
                    spinAngularVelocity=axis*(Scalar(0.5)*angularVelocity/axis.mag());

                    /* Go to spinning mode: */
                    navigationMode=SPINNING;
                }
                else
                {
                    /* Deactivate this tool: */
                    deactivate();

                    /* Go to idle mode: */
                    navigationMode=IDLE;
                }
                break;
            }

            case DOLLYING:
            case SCALING:
                startPanning();
                break;

            default:
                /* This shouldn't happen; just ignore the event */
                break;
            }
        }
        break;

    case 1:
        if(cbData->newButtonState) // Button has just been pressed
        {
            /* Act depending on this tool's current state: */
            switch(navigationMode)
            {
            case IDLE:
            case SPINNING:
                /* Try activating this tool: */
                if(navigationMode==SPINNING||activate())
                    startPanning();
                break;

            case ROTATING:
                if(dolly)
                    startDollying();
                else
                    startScaling();
                break;

            default:
                /* This shouldn't happen; just ignore the event */
                break;
            }
        }
        else // Button has just been released
        {
            /* Act depending on this tool's current state: */
            switch(navigationMode)
            {
            case PANNING:
                /* Deactivate this tool: */
                deactivate();

                /* Go to idle mode: */
                navigationMode=IDLE;
                break;

            case DOLLYING:
            case SCALING:
                startRotating();
                break;

            default:
                /* This shouldn't happen; just ignore the event */
                break;
            }
        }
        break;

    case 2:
        /* Set the dolly flag: */
        dolly=cbData->newButtonState;
        if(factory->invertDolly)
            dolly=!dolly;
        if(dolly) // Dollying has just been enabled
        {
            /* Act depending on this tool's current state: */
            switch(navigationMode)
            {
            case SCALING:
                startDollying();
                break;

            default:
                /* Nothing to do */
                break;
            }
        }
        else
        {
            /* Act depending on this tool's current state: */
            switch(navigationMode)
            {
            case DOLLYING:
                startScaling();
                break;

            default:
                /* Nothing to do */
                break;
            }
        }
        break;
    }
}