void SixDofWithScaleNavigationTool::buttonCallback(int buttonSlotIndex,InputDevice::ButtonCallbackData* cbData)
	{
	switch(buttonSlotIndex)
		{
		case 0:
			if(cbData->newButtonState) // Button has just been pressed
				{
				if(navigationMode==IDLE&&activate())
					{
					/* Decide whether to go to moving or scaling mode: */
					if(Geometry::sqrDist(getButtonDevicePosition(0),getButtonDevicePosition(1))<=factory->scaleDeviceDistance2) // Want to scale
						{
						/* Determine the scaling center and initial scale: */
						scalingCenter=getButtonDevicePosition(1);
						Vector scaleDirection=getButtonDeviceTransformation(1).transform(factory->deviceScaleDirection);
						initialScale=getButtonDevicePosition(0)*scaleDirection;
						
						/* Initialize the navigation transformations: */
						preScale=NavTrackerState::translateFromOriginTo(scalingCenter);
						postScale=NavTrackerState::translateToOriginFrom(scalingCenter);
						postScale*=getNavigationTransformation();
						
						/* Go from MOVING to SCALING mode: */
						navigationMode=SCALING;
						}
					else // Want to move
						{
						/* Initialize the navigation transformations: */
						preScale=Geometry::invert(getDeviceTransformation(0));
						preScale*=getNavigationTransformation();
						
						/* Go from IDLE to MOVING mode: */
						navigationMode=MOVING;
						}
					}
				}
			else // Button has just been released
				{
				/* Deactivate this tool: */
				deactivate();
				
				/* Go from MOVING or SCALING to IDLE mode: */
				navigationMode=IDLE;
				}
			
			break;
		
		case 1:
			/* Pass the button event to the virtual input device: */
			buttonDevice->setButtonState(0,cbData->newButtonState);
			
			break;
		}
	}
void TrackballNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		/* Calculate new interaction position: */
		Point dragPosition=calcTrackballPosition();
		
		/* Calculate incremental transformation from old to new point: */
		Vector v1=lastDragPosition-getDisplayCenter();
		Vector v2=dragPosition-getDisplayCenter();
		Vector axis=Geometry::cross(v1,v2);
		Scalar axisLen=Geometry::mag(axis);
		if(axisLen!=Scalar(0))
			{
			/* Calculate rotation angle: */
			axis/=axisLen;
			Scalar angle=Math::acos((v1*v2)/(Geometry::mag(v1)*Geometry::mag(v2)))*factory->rotateFactor;
			
			/* Compose new navigation transformation: */
			NavTrackerState navigation=NavTrackerState::rotateAround(getDisplayCenter(),NavTrackerState::Rotation::rotateAxis(axis,angle));
			navigation*=getNavigationTransformation();
			
			/* Update Vrui's navigation transformation: */
			setNavigationTransformation(navigation);
			}
		
		lastDragPosition=dragPosition;
		}
	}
void SixAxisNavigationTool::valuatorCallback(int valuatorSlotIndex,InputDevice::ValuatorCallbackData* cbData)
	{
	/* Check if the valuator became active or inactive: */
	if(cbData->oldValuatorValue==0.0&&cbData->newValuatorValue!=0.0)
		{
		/* Activate the axis: */
		++numActiveAxes;
		
		/* Try activating navigation if it is not already active: */
		if(!isActive()&&activate())
			{
			/* Initialize transient navigation state: */
			navTransform=getNavigationTransformation();
			}
		}
	if(cbData->oldValuatorValue!=0.0&&cbData->newValuatorValue==0.0)
		{
		/* Deactivate the axis: */
		--numActiveAxes;
		if(numActiveAxes==0)
			{
			/* Deactivate navigation: */
			deactivate();
			}
		}
	}
void ValuatorFlyTurnNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		/* Get the current state of the input device: */
		const TrackerState& ts=getDeviceTransformation(0);
		
		/* Check whether to change the super acceleration factor: */
		if(Math::abs(currentValues[0])==Scalar(1))
			superAcceleration*=Math::pow(factory->superAccelerationFactor,getFrameTime());
		
		/* Calculate the current flying velocity: */
		Vector v=factory->flyDirectionDeviceCoordinates?ts.transform(factory->flyDirection):factory->flyDirection;
		v*=-currentValues[0]*factory->flyFactor*superAcceleration*getFrameTime();
		
		/* Calculate the current angular velocity: */
		Vector w=factory->rotationAxisDeviceCoordinates?ts.transform(factory->rotationAxis):factory->rotationAxis;
		w*=currentValues[1]*factory->rotationFactor*getFrameTime();
		
		/* Compose the new navigation transformation: */
		Point p=factory->rotationCenterDeviceCoordinates?ts.transform(factory->rotationCenter):factory->rotationCenter;
		NavTransform t=NavTransform::translate(v);
		t*=NavTransform::translateFromOriginTo(p);
		t*=NavTransform::rotate(NavTransform::Rotation::rotateScaledAxis(w));
		t*=NavTransform::translateToOriginFrom(p);
		t*=getNavigationTransformation();
		
		/* Update Vrui's navigation transformation: */
		setNavigationTransformation(t);
		}
	}
void TwoRayTransformTool::frame(void)
	{
	/* Check if the device is currently dragging a ray: */
	if(active)
		{
		/* Calculate the device's ray equation in navigational coordinates: */
		rays[numRays]=sourceDevice->getRay();
		rays[numRays].transform(getInverseNavigationTransformation());
		
		/* Check if there are two rays (one final and one intermediate): */
		if(numRays==1)
			{
			/* Calculate the "intersection" point between the two rays: */
			Geometry::Matrix<Scalar,3,3> a;
			Geometry::ComponentArray<Scalar,3> b;
			Vector bin=rays[0].getDirection()^rays[1].getDirection();
			for(int i=0;i<3;++i)
				{
				a(i,0)=rays[0].getDirection()[i];
				a(i,1)=-rays[1].getDirection()[i];
				a(i,2)=bin[i];
				b[i]=rays[1].getOrigin()[i]-rays[0].getOrigin()[i];
				}
			Geometry::ComponentArray<Scalar,3> x=b/a;
			intersection=Geometry::mid(rays[0](x[0]),rays[1](x[1]));
			}
		}
	if(numRays>=(active?1:2))
		{
		/* Set the transformed device's position and orientation: */
		transformedDevice->setDeviceRay(sourceDevice->getDeviceRayDirection(),Scalar(0));
		transformedDevice->setTransformation(ONTransform(getNavigationTransformation().transform(intersection)-Point::origin,sourceDevice->getTransformation().getRotation()));
		}
	}
void MouseDialogNavigationTool::startPanning(void)
	{
	/* Calculate initial motion position: */
	motionStart=calcScreenPos();
	
	preScale=getNavigationTransformation();
	}
MouseDialogNavigationTool::MouseDialogNavigationTool(const ToolFactory* factory,const ToolInputAssignment& inputAssignment)
	:NavigationTool(factory,inputAssignment),
	 mouseAdapter(0),
	 navigationDialogPopup(0),
	 navigationMode(ROTATING),
	 spinning(false),
	 showScreenCenter(false)
	{
	/* Find the mouse input device adapter controlling the input device: */
	mouseAdapter=dynamic_cast<InputDeviceAdapterMouse*>(getInputDeviceManager()->findInputDeviceAdapter(getDevice(0)));
	
	/* Create the tool's GUI: */
	navigationDialogPopup=new GLMotif::PopupWindow("NavigationDialogPopup",getWidgetManager(),"Mouse Navigation Dialog");
	
	GLMotif::RowColumn* navigationDialog=new GLMotif::RowColumn("NavigationDialog",navigationDialogPopup,false);
	
	GLMotif::RadioBox* navigationModes=new GLMotif::RadioBox("NavigationModes",navigationDialog,false);
	navigationModes->setOrientation(GLMotif::RowColumn::VERTICAL);
	navigationModes->setPacking(GLMotif::RowColumn::PACK_GRID);
	navigationModes->setSelectionMode(GLMotif::RadioBox::ALWAYS_ONE);
	
	navigationModes->addToggle("Rotate");
	navigationModes->addToggle("Pan");
	navigationModes->addToggle("Dolly");
	navigationModes->addToggle("Scale");
	
	switch(navigationMode)
		{
		case ROTATING:
			navigationModes->setSelectedToggle(0);
			break;
		
		case PANNING:
			navigationModes->setSelectedToggle(1);
			break;
		
		case DOLLYING:
			navigationModes->setSelectedToggle(2);
			break;
		
		case SCALING:
			navigationModes->setSelectedToggle(3);
			break;
		}
	navigationModes->getValueChangedCallbacks().add(this,&MouseDialogNavigationTool::navigationModesValueChangedCallback);
	navigationModes->manageChild();
	
	GLMotif::ToggleButton* showScreenCenterToggle=new GLMotif::ToggleButton("ShowScreenCenterToggle",navigationDialog,"Show Screen Center");
	showScreenCenterToggle->setToggle(showScreenCenter);
	showScreenCenterToggle->getValueChangedCallbacks().add(this,&MouseDialogNavigationTool::showScreenCenterToggleValueChangedCallback);
	
	navigationDialog->manageChild();
	
	/* Pop up the navigation dialog: */
	popupPrimaryWidget(navigationDialogPopup,getNavigationTransformation().transform(getDisplayCenter()));
	}
Exemplo n.º 8
0
void MouseNavigationTool::startPanning(void)
	{
	/* Calculate initial motion position: */
	motionStart=calcScreenPos();
	
	preScale=getNavigationTransformation();
	
	/* Go to panning mode: */
	navigationMode=PANNING;
	}
Exemplo n.º 9
0
void ScaleBar::pointerButtonDown(GLMotif::Event& event)
	{
	Scalar newScale=currentScale;
	
	/* Check if the event happened in the left or right corner: */
	float relEventPos=(event.getWidgetPoint().getPoint()[0]-getInterior().origin[0])/getInterior().size[0];
	if(relEventPos<=0.333f)
		{
		/* Calculate the next smaller quasi-binary scale factor: */
		newScale=Scalar(getSmallerQuasiBinary(currentScale));
		}
	else if(relEventPos>=0.667f)
		{
		/* Calculate the next bigger quasi-binary scale factor: */
		newScale=Scalar(getBiggerQuasiBinary(currentScale));
		}
	
	if(newScale!=currentScale&&activateNavigationTool(reinterpret_cast<const Tool*>(this)))
		{
		/* Adjust the navigation transformation: */
		Scalar newNavScale;
		const Geometry::LinearUnit& unit=getCoordinateManager()->getUnit();
		if(unit.isImperial())
			{
			/* Calculate scale factor through imperial units: */
			newNavScale=getInchFactor()*newScale/unit.getInchFactor();
			}
		else
			{
			/* Calculate scale factor through metric units: */
			newNavScale=getMeterFactor()*newScale/unit.getMeterFactor();
			}
		
		/* Get the current navigation transformation and calculate the display center position in navigation coordinates: */
		const NavTransform& nav=getNavigationTransformation();
		Point center=nav.inverseTransform(getDisplayCenter());
		
		/* Create the new navigation transformation: */
		NavTransform newNav=NavTransform(nav.getTranslation(),nav.getRotation(),newNavScale);
		newNav.leftMultiply(NavTransform::translate(getDisplayCenter()-newNav.transform(center)));
		setNavigationTransformation(newNav);
		
		deactivateNavigationTool(reinterpret_cast<const Tool*>(this));
		currentScale=newScale;
		
		/* Update the scale bar: */
		calcSize(newNav);
		
		/* Resize the widget so that the clicked point stays in the same place: */
		GLMotif::Vector newSize=calcNaturalSize();
		GLfloat newInteriorWidth=newSize[0]-2.0f*getBorderWidth();
		GLfloat newOrigin=event.getWidgetPoint().getPoint()[0]-newInteriorWidth*relEventPos-getBorderWidth();
		resize(GLMotif::Box(GLMotif::Vector(newOrigin,0.0f,0.0f),newSize));
		}
	}
void MouseDialogNavigationTool::startScaling(void)
	{
	/* Calculate the scaling center: */
	screenCenter=calcScreenCenter();
	
	/* Calculate initial motion position: */
	motionStart=calcScreenPos();
	
	preScale=NavTrackerState::translateFromOriginTo(screenCenter);
	postScale=NavTrackerState::translateToOriginFrom(screenCenter);
	postScale*=getNavigationTransformation();
	}
void PlaneSnapInputDeviceTool::buttonCallback(int,InputDevice::ButtonCallbackData* cbData)
	{
	if(cbData->newButtonState) // Button has just been pressed
		{
		/* Try activating the tool: */
		if(interactionDevice->isRayDevice())
			{
			/* Pick a virtual input device using ray selection: */
			activate(calcInteractionRay());
			}
		else
			{
			/* Pick a virtual input device using point selection: */
			activate(getInteractionPosition());
			}
		
		/* Check if the tool was activated: */
		if(isActive())
			{
			/* Check if there are currently three selected points: */
			if(numSelectedPoints==3)
				{
				/* Snap the selected virtual input device to the plane defined by the three selected points: */
				Vector y=Geometry::cross(selectedPoints[1]-selectedPoints[0],selectedPoints[2]-selectedPoints[0]);
				Scalar offset=(selectedPoints[0]*y+selectedPoints[1]*y+selectedPoints[2]*y)/Scalar(3);
				Vector x=Geometry::normal(y);
				Point devicePos=getInverseNavigationTransformation().transform(getGrabbedDevice()->getPosition());
				Scalar lambda=(offset-devicePos*y)/Geometry::sqr(y);
				devicePos+=y*lambda;
				NavTransform dt=NavTransform(devicePos-Point::origin,NavTransform::Rotation::fromBaseVectors(x,y),Scalar(1));
				dt.leftMultiply(getNavigationTransformation());
				getGrabbedDevice()->setTransformation(TrackerState(dt.getTranslation(),dt.getRotation()));
				}
			
			/* Deactivate the tool again: */
			deactivate();
			}
		else
			{
			/* Start dragging another selection point: */
			if(numSelectedPoints==3)
				numSelectedPoints=0;
			draggingPoint=true;
			++numSelectedPoints;
			}
		}
	else // Button has just been released
		{
		/* Stop dragging a selection point: */
		draggingPoint=false;
		}
	}
void MouseDialogNavigationTool::startDollying(void)
	{
	/* Calculate the dollying direction: */
	if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0)
		dollyDirection=mouseAdapter->getWindow()->getViewer()->getHeadPosition()-calcScreenCenter();
	else
		dollyDirection=getMainViewer()->getHeadPosition()-calcScreenCenter();
	dollyDirection.normalize();
	
	/* Calculate initial motion position: */
	motionStart=calcScreenPos();
	
	preScale=getNavigationTransformation();
	}
Exemplo n.º 13
0
ScaleBar::ScaleBar(const char* sName,GLMotif::WidgetManager* sManager)
	:GLMotif::Widget(sName,0,false),manager(sManager),
	 targetLength(getDisplaySize()*Scalar(0.2)),
	 currentMantissa(1),currentExponent(0),currentNavLength(1),currentScale(1),
	 lengthLabel(0),scaleLabel(0),
	 currentPhysLength(0)
	{
	/* Set widget parameters: */
	setBorderWidth(0.0f);
	setBorderType(GLMotif::Widget::PLAIN);
	
	/* Set default background and foreground colors: */
	Color bgColor=Vrui::getBackgroundColor();
	bgColor[3]=0.0f;
	Color fgColor;
	for(int i=0;i<3;++i)
		fgColor[i]=1.0f-bgColor[i];
	fgColor[3]=1.0f;
	setBorderColor(bgColor);
	setBackgroundColor(bgColor);
	setForegroundColor(fgColor);
	
	/* Create the initial scale bar length label: */
	if(getCoordinateManager()->getUnit().unit!=Geometry::LinearUnit::UNKNOWN)
		{
		char labelText[10];
		snprintf(labelText,sizeof(labelText),"1 %s",getCoordinateManager()->getUnit().getAbbreviation());
		lengthLabel=new GLLabel(labelText,*getUiFont());
		}
	else
		lengthLabel=new GLLabel("1",*getUiFont());
	lengthLabel->setBackground(bgColor);
	lengthLabel->setForeground(fgColor);
	scaleLabel=new GLLabel("1:1",*getUiFont());
	scaleLabel->setBackground(bgColor);
	scaleLabel->setForeground(fgColor);
	
	/* Calculate the initial navigation-space scale bar length: */
	calcSize(getNavigationTransformation());
	
	/* Resize the widget: */
	GLMotif::Vector newSize=calcNaturalSize();
	GLMotif::Vector newOrigin=GLMotif::Vector(0.0f,0.0f,0.0f);
	newOrigin[0]=-newSize[0]*0.5f;
	resize(GLMotif::Box(newOrigin,newSize));
	
	/* Register a navigation change callback with the Vrui kernel: */
	getNavigationTransformationChangedCallbacks().add(this,&ScaleBar::navigationChangedCallback);
	}
Exemplo n.º 14
0
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();
	}
Exemplo n.º 15
0
void HelicopterNavigationTool::buttonCallback(int,int buttonIndex,InputDevice::ButtonCallbackData* cbData)
{
    /* Process based on which button was pressed: */
    if(buttonIndex==0)
    {
        if(cbData->newButtonState)
        {
            /* Act depending on this tool's current state: */
            if(isActive())
            {
                /* Go back to original transformation: */
                NavTransform nav=pre;
                nav*=NavTransform::translateToOriginFrom(currentPosition);
                nav*=post;
                setNavigationTransformation(nav);

                /* Deactivate this tool: */
                deactivate();
            }
            else
            {
                /* Try activating this tool: */
                if(activate())
                {
                    /* Initialize the navigation: */
                    Vector x=Geometry::cross(getForwardDirection(),getUpDirection());
                    Vector y=Geometry::cross(getUpDirection(),x);
                    pre=NavTransform::translateFromOriginTo(getMainViewer()->getHeadPosition());
                    pre*=NavTransform::rotate(Rotation::fromBaseVectors(x,y));

                    post=Geometry::invert(pre);
                    post*=getNavigationTransformation();

                    currentPosition=Point::origin;
                    currentOrientation=Rotation::identity;
                    currentVelocity=Vector::zero;
                    lastFrameTime=getApplicationTime();
                }
            }
        }
    }
    else
    {
        /* Store the new state of the button: */
        buttons[buttonIndex-1]=cbData->newButtonState;
    }
}
Exemplo n.º 16
0
void SixDofNavigationTool::buttonCallback(int,int,InputDevice::ButtonCallbackData* cbData)
	{
	if(cbData->newButtonState) // Button has just been pressed
		{
		/* Try activating this tool: */
		if(activate())
			{
			/* Initialize the navigation transformations: */
			preScale=Geometry::invert(getDeviceTransformation(0));
			preScale*=getNavigationTransformation();
			}
		}
	else // Button has just been released
		{
		/* Deactivate this tool: */
		deactivate();
		}
	}
void DesktopDeviceNavigationTool::setButtonState(int buttonIndex,bool newButtonState)
	{
	if(buttonIndex==factory->homeButtonIndex)
		{
		if(newButtonState)
			{
			/* Reset the virtual input device to its home position: */
			virtualDevice->setTransformation(homePosition);
			}
		}
	else if(buttonIndex==factory->navigationButtonIndex)
		{
		/* Set navigation state: */
		if(newButtonState)
			{
			/* Try activating this tool: */
			if(activate())
				{
				/* Initialize the navigation transformation: */
				postScale=getNavigationTransformation();
				}
			}
		else
			{
			/* Deactivate this tool: */
			deactivate();
			}
		}
	else if(factory->buttonAxisShiftMasks[buttonIndex]!=0x0)
		{
		/* Update the current axis shift mask: */
		if(newButtonState)
			axisIndexBase|=factory->buttonAxisShiftMasks[buttonIndex];
		else
			axisIndexBase&=~factory->buttonAxisShiftMasks[buttonIndex];
		}
	else
		{
		/* Pass the button event through to the virtual input device: */
		virtualDevice->setButtonState(buttonIndex,newButtonState);
		}
	}
Exemplo n.º 18
0
void SceneGraphViewer::display(GLContextData& contextData) const
	{
	/* Save OpenGL state: */
	glPushAttrib(GL_ENABLE_BIT|GL_LIGHTING_BIT|GL_TEXTURE_BIT);
	
	/* Go to navigational coordinates: */
	glPushMatrix();
	glLoadIdentity();
	glMultMatrix(getDisplayState(contextData).modelviewNavigational);
	
	/* Create a render state to traverse the scene graph: */
	SceneGraph::GLRenderState renderState(contextData,getHeadPosition(),getNavigationTransformation().inverseTransform(getUpDirection()));
	
	/* Traverse the scene graph: */
	root->glRenderAction(renderState);
	
	/* Restore OpenGL state: */
	glPopMatrix();
	glPopAttrib();
	}
Exemplo n.º 19
0
void FlyNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		/* Get the current state of the input device: */
		const TrackerState& ts=getDeviceTransformation(0);
		
		/* Calculate the current flying velocity: */
		Vector v=ts.transform(factory->flyDirection);
		v*=-factory->flyFactor*getFrameTime();
		
		/* Compose the new navigation transformation: */
		NavTransform t=NavTransform::translate(v);
		t*=getNavigationTransformation();
		
		/* Update Vrui's navigation transformation: */
		setNavigationTransformation(t);
		}
	}
void MouseDialogNavigationTool::startRotating(void)
	{
	/* Calculate the rotation center: */
	screenCenter=calcScreenCenter();
	
	/* Calculate initial rotation position: */
	lastRotationPos=calcScreenPos();
	
	/* Get the transformation of the screen currently containing the input device: */
	Scalar viewport[4];
	ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport);
	
	/* Calculate the rotation offset vector: */
	rotateOffset=screenT.transform(Vector(0,0,factory->rotatePlaneOffset));
	
	preScale=NavTrackerState::translateFromOriginTo(screenCenter);
	rotation=NavTrackerState::identity;
	postScale=NavTrackerState::translateToOriginFrom(screenCenter);
	postScale*=getNavigationTransformation();
	}
void ValuatorScalingNavigationTool::valuatorCallback(int,int,InputDevice::ValuatorCallbackData* cbData)
	{
	currentValue=Scalar(cbData->newValuatorValue);
	if(Math::abs(currentValue)>factory->valuatorThreshold)
		{
		/* Try activating this tool: */
		if(!isActive()&&activate())
			{
			/* Initialize the navigation transformations: */
			scalingCenter=getDevicePosition(0);
			preScale=NavTrackerState::translateFromOriginTo(scalingCenter);
			postScale=NavTrackerState::translateToOriginFrom(scalingCenter);
			postScale*=getNavigationTransformation();
			currentScale=Scalar(1);
			}
		}
	else
		{
		/* Deactivate this tool: */
		deactivate();
		}
	}
Exemplo n.º 22
0
void TwoRayTransformTool::display(GLContextData& contextData) const
	{
	if(numRays>0)
		{
		/* Draw the selection rays: */
		glPushAttrib(GL_ENABLE_BIT|GL_LINE_BIT);
		glDisable(GL_LIGHTING);
		glColor3f(1.0f,0.0f,0.0f);
		glLineWidth(3.0f);
		glBegin(GL_LINES);
		for(int i=0;i<(active?numRays+1:numRays);++i)
			{
			Ray tr=rays[i];
			tr.transform(getNavigationTransformation());
			glVertex(tr.getOrigin());
			glVertex(tr(getDisplaySize()*Scalar(5)));
			}
		glEnd();
		glPopAttrib();
		
		}
	}
void ValuatorTurnNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		/* Get the current state of the input device: */
		const TrackerState& ts=getButtonDeviceTransformation(0);
		
		/* Calculate the current flying velocity: */
		Vector v=Vector::zero;
		if(buttonState)
			{
			v=ts.transform(factory->flyDirection);
			v*=-factory->flyFactor*getFrameTime();
			}
		
		/* Calculate the current angular velocities: */
		Vector w0=factory->rotationAxis0;
		w0*=currentValues[0]*factory->rotationFactor*getFrameTime();
		Vector w1=factory->rotationAxis1;
		w1*=currentValues[1]*factory->rotationFactor*getFrameTime();
		
		/* Compose the new navigation transformation: */
		Point p=ts.transform(factory->rotationCenter);
		NavTransform t=NavTransform::translate(v);
		t*=NavTransform::translateFromOriginTo(p);
		t*=NavTransform::rotate(NavTransform::Rotation::rotateScaledAxis(w0));
		t*=NavTransform::rotate(NavTransform::Rotation::rotateScaledAxis(w1));
		t*=NavTransform::translateToOriginFrom(p);
		t*=getNavigationTransformation();
		
		/* Update Vrui's navigation transformation: */
		setNavigationTransformation(t);
		
		/* Request another frame: */
		scheduleUpdate(getApplicationTime()+1.0/125.0);
		}
	}
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=getValuatorDeviceTransformation(0);
		
		/* Calculate the current flying velocity: */
		Vector v=ts.transform(factory->flyDirection);
		v*=-currentValue*factory->flyFactor*getFrameTime();
		
		/* Compose the new navigation transformation: */
		NavTransform t=NavTransform::translate(v);
		t*=getNavigationTransformation();
		
		/* Update Vrui's navigation transformation: */
		setNavigationTransformation(t);
		
		/* Request another frame: */
		scheduleUpdate(getApplicationTime()+1.0/125.0);
		}
	}
Exemplo n.º 25
0
void ViewpointFileNavigationTool::display(GLContextData& contextData) const
	{
	if(!viewpoints.empty()&&showKeyframes)
		{
		/* Display the next keyframe viewpoint in navigational coordinates: */
		glPushAttrib(GL_ENABLE_BIT|GL_LINE_BIT);
		glDisable(GL_LIGHTING);
		glLineWidth(3.0f);
		glPushMatrix();
		glMultMatrix(getNavigationTransformation());
		
		glBegin(GL_LINES);
		glColor3f(1.0f,0.0f,0.0f);
		glVertex(viewpoints[nextViewpointIndex].center);
		glVertex(viewpoints[nextViewpointIndex].center+viewpoints[nextViewpointIndex].forward*Math::exp(viewpoints[nextViewpointIndex].size)*Scalar(0.25));
		glColor3f(0.0f,1.0f,0.0f);
		glVertex(viewpoints[nextViewpointIndex].center);
		glVertex(viewpoints[nextViewpointIndex].center+viewpoints[nextViewpointIndex].up*Math::exp(viewpoints[nextViewpointIndex].size)*Scalar(0.25));
		glEnd();
		
		glPopMatrix();
		glPopAttrib();
		}
	}
Exemplo n.º 26
0
void FPSNavigationTool::startNavigating(void)
	{
	/* Initialize the navigation state: */
	if(mouseAdapter!=0)
		{
		/* Get the current cursor position in the controlling window: */
		for(int i=0;i<2;++i)
			oldMousePos[i]=mouseAdapter->getMousePosition()[i];
		
		/* Enable mouse warping on the controlling window: */
		mouseAdapter->getWindow()->hideCursor();
		mouseAdapter->getWindow()->getWindowCenterPos(lastMousePos.getComponents());
		lastMousePos[2]=Scalar(0);
		mouseAdapter->getWindow()->setCursorPosWithAdjust(lastMousePos.getComponents());
		mouseAdapter->setMousePosition(mouseAdapter->getWindow(),lastMousePos.getComponents());
		
		/* Update the navigation frame on the off chance that the controlling window changed: */
		ONTransform st=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation();
		navFrame=st.getRotation();
		pos=mouseAdapter->getWindow()->getViewer()->getHeadPosition();
		}
	else
		{
		pos=getMainViewer()->getHeadPosition();
		lastMousePos=calcMousePosition();
		}
	angles[0]=angles[1]=Scalar(0);
	moveVelocity=Vector::zero;

	/* Calculate the prescale transformation: */
	preScale=NavTransform::translateToOriginFrom(pos);
	preScale*=NavTransform::translateFromOriginTo(pos);
	preScale*=NavTransform::rotate(Geometry::invert(navFrame));
	preScale*=NavTransform::translateToOriginFrom(pos);
	preScale*=getNavigationTransformation();
	}
void ComeHitherNavigationTool::buttonCallback(int,int,InputDevice::ButtonCallbackData* cbData)
	{
	if(cbData->newButtonState) // Button has just been pressed
		{
		if(isActive()) // Tool is already active
			{
			/* Snap to the target transformation immediately: */
			setNavigationTransformation(targetNav);
			
			/* Deactivate this tool: */
			deactivate();
			}
		else // Tool is not yet active
			{
			/* Try activating this tool: */
			if(activate())
				{
				/* Get the start navigation transformation: */
				startNav=getNavigationTransformation();
				startTime=getApplicationTime();
				
				/* Get the target transformation: */
				NavTransform device=getDeviceTransformation(0);
				device.leftMultiply(getInverseNavigationTransformation());
				Point center=device.getOrigin();
				Vector forward=device.getDirection(1);
				Vector up=device.getDirection(2);
				
				/* Compute the navigation transformation for the target transformation: */
				targetNav=NavTransform::identity;
				targetNav*=NavTransform::translateFromOriginTo(getDisplayCenter());
				targetNav*=NavTransform::rotate(Rotation::fromBaseVectors(Geometry::cross(getForwardDirection(),getUpDirection()),getForwardDirection()));
				targetNav*=NavTransform::scale(startNav.getScaling());
				targetNav*=NavTransform::rotate(Geometry::invert(Rotation::fromBaseVectors(Geometry::cross(forward,up),forward)));
				targetNav*=NavTransform::translateToOriginFrom(center);
				
				/* Compute the linear and angular velocities for the movement: */
				NavTransform delta=startNav;
				delta.doInvert();
				delta.leftMultiply(targetNav);
				Vector linearDist=delta.getTranslation();
				double linearMag=Geometry::mag(linearDist);
				Vector angularDist=delta.getRotation().getScaledAxis();
				double angularMag=Geometry::mag(angularDist);
				if(linearMag<=factory->linearSnapThreshold&&angularMag<=factory->angularSnapThreshold)
					{
					/* Snap to the target transformation immediately: */
					setNavigationTransformation(targetNav);
					
					/* Deactivate this tool: */
					deactivate();
					}
				else
					{
					/* Compute the total transition time: */
					double transitionTime=linearMag/factory->maxLinearVelocity;
					if(transitionTime<angularMag/factory->maxAngularVelocity)
						transitionTime=angularMag/factory->maxAngularVelocity;
					endTime=startTime+transitionTime;
					
					/* Compute the effective linear and angular velocities: */
					linearVelocity=linearDist/Scalar(transitionTime);
					angularVelocity=angularDist/Scalar(transitionTime);
					}
				}
			}
		}
	}
Exemplo n.º 28
0
void ClipPlaneManager::clipRay(bool physical,Ray& ray,Scalar& lambdaMax) const
	{
	/* Calculate the ray interval inside all clipping planes: */
	Scalar lambda1=Scalar(0);
	Scalar lambda2=lambdaMax;
	for(const ClipPlaneListItem* cpPtr=firstClipPlane;cpPtr!=0;cpPtr=cpPtr->succ)
		if(cpPtr->isEnabled())
			{
			/* Get the clipping plane's plane equation in the same coordinate system as the ray's: */
			Plane plane=cpPtr->getPlane();
			if(physical&&!cpPtr->physical)
				{
				/* Transform the clipping plane to physical space: */
				plane.transform(getNavigationTransformation());
				}
			else if(!physical&&cpPtr->physical)
				{
				/* Transform the clipping plane to navigational space: */
				plane.transform(getInverseNavigationTransformation());
				}
			
			/* Intersect the plane and the ray: */
			Scalar divisor=plane.getNormal()*ray.getDirection();
			if(divisor!=Scalar(0))
				{
				Scalar lambda=(plane.getOffset()-plane.getNormal()*ray.getOrigin())/divisor;
				
				/* Check if the ray enters or exits the clipping plane's half-space: */
				if(divisor<Scalar(0))
					{
					/* Ray exits: */
					if(lambda2>lambda)
						lambda2=lambda;
					}
				else
					{
					/* Ray enters: */
					if(lambda1<lambda)
						lambda1=lambda;
					}
				}
			}
	
	/* Adjust the ray: */
	if(lambda1<lambda2)
		{
		if(lambda1>Scalar(0))
			{
			/* Adjust the ray's origin: */
			ray.setOrigin(ray(lambda1));
			lambda2-=lambda1;
			}
		
		/* Adjust the maximum ray intercept: */
		lambdaMax=lambda2;
		}
	else
		{
		/* Invalidate the ray: */
		lambdaMax=Scalar(0);
		}
	}
Exemplo n.º 29
0
void MouseNavigationTool::valuatorCallback(int,InputDevice::ValuatorCallbackData* cbData)
	{
	currentValue=Scalar(cbData->newValuatorValue);
	if(currentValue!=Scalar(0))
		{
		/* Act depending on this tool's current state: */
		switch(navigationMode)
			{
			case IDLE:
			case SPINNING:
				/* Try activating this tool: */
				if(navigationMode==SPINNING||activate())
					{
					if(dolly)
						{
						/* Calculate the dollying direction: */
						if(mouseAdapter!=0)
							dollyDirection=mouseAdapter->getWindow()->getViewer()->getHeadPosition()-calcScreenCenter();
						else
							dollyDirection=getMainViewer()->getHeadPosition()-calcScreenCenter();
						dollyDirection.normalize();
						
						/* Initialize the wheel dollying factor: */
						currentWheelScale=Scalar(1);
						
						preScale=getNavigationTransformation();
						
						/* Go to wheel dollying mode: */
						navigationMode=DOLLYING_WHEEL;
						}
					else
						{
						/* Calculate the scaling center: */
						screenCenter=calcScreenCenter();
						
						/* Initialize the wheel scaling factor: */
						currentWheelScale=Scalar(1);
						
						preScale=NavTrackerState::translateFromOriginTo(screenCenter);
						postScale=NavTrackerState::translateToOriginFrom(screenCenter);
						postScale*=getNavigationTransformation();
						
						/* Go to wheel scaling mode: */
						navigationMode=SCALING_WHEEL;
						}
					}
				break;
			
			default:
				/* This can definitely happen; just ignore the event */
				break;
			}
		}
	else
		{
		/* Act depending on this tool's current state: */
		switch(navigationMode)
			{
			case DOLLYING_WHEEL:
			case SCALING_WHEEL:
				/* Deactivate this tool: */
				deactivate();
				
				/* Go to idle mode: */
				navigationMode=IDLE;
				break;
			
			default:
				/* This can definitely happen; just ignore the event */
				break;
			}
		}
	}
void WandNavigationTool::buttonCallback(int buttonSlotIndex,InputDevice::ButtonCallbackData* cbData)
	{
	/* Process based on which button was pressed: */
	switch(buttonSlotIndex)
		{
		case 0:
			if(cbData->newButtonState) // Button has just been pressed
				{
				/* Act depending on this tool's current state: */
				switch(navigationMode)
					{
					case IDLE:
						/* Try activating this tool: */
						if(activate())
							{
							/* Initialize the navigation transformations: */
							preScale=Geometry::invert(getButtonDeviceTransformation(0));
							preScale*=getNavigationTransformation();
							
							/* Go from IDLE to MOVING mode: */
							navigationMode=MOVING;
							}
						break;
					
					case PASSTHROUGH:
						/* Remember that the main button is pressed: */
						navigationMode=PASSTHROUGH_MOVING;
						break;
					
					case SCALING_PAUSED:
						/* Determine the scaling center and direction: */
						scalingCenter=getButtonDevicePosition(0);
						scalingDirection=getButtonDeviceRayDirection(0);
						initialScale=scalingCenter*scalingDirection;
						
						/* Initialize the transformation parts: */
						preScale=NavTrackerState::translateFromOriginTo(scalingCenter);
						postScale=NavTrackerState::translateToOriginFrom(scalingCenter);
						postScale*=getNavigationTransformation();
						
						/* Go from SCALING_PAUSED to SCALING mode: */
						navigationMode=SCALING;
						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 PASSTHROUGH_MOVING:
						/* Remember that the main button is released: */
						navigationMode=PASSTHROUGH;
						break;
					
					case SCALING:
						/* Pause scaling until button is pressed again: */
						
						/* Go from SCALING to SCALING_PAUSED mode: */
						navigationMode=SCALING_PAUSED;
						break;
					
					case MOVING:
						/* Deactivate this tool: */
						deactivate();
						
						/* Go from MOVING to IDLE mode: */
						navigationMode=IDLE;
						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:
						/* Pass the button event to the virtual input device: */
						buttonDevice->setButtonState(0,true);
						
						/* Go to pass-through mode: */
						navigationMode=PASSTHROUGH;
						break;
					
					case MOVING:
						/* Determine the scaling center and direction: */
						scalingCenter=getButtonDevicePosition(0);
						scalingDirection=getButtonDeviceRayDirection(0);
						initialScale=scalingCenter*scalingDirection;
						
						/* Initialize the transformation parts: */
						preScale=NavTrackerState::translateFromOriginTo(scalingCenter);
						postScale=NavTrackerState::translateToOriginFrom(scalingCenter);
						postScale*=getNavigationTransformation();
						
						/* Go from MOVING to SCALING mode: */
						navigationMode=SCALING;
						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 PASSTHROUGH:
						/* Pass the button event to the virtual input device: */
						buttonDevice->setButtonState(0,false);
						
						/* Go to idle mode: */
						navigationMode=IDLE;
						break;
					
					case PASSTHROUGH_MOVING:
						/* Pass the button event to the virtual input device: */
						buttonDevice->setButtonState(0,false);
						
						/* Try activating this tool: */
						if(activate())
							{
							/* Initialize the navigation transformations: */
							preScale=Geometry::invert(getButtonDeviceTransformation(0));
							preScale*=getNavigationTransformation();
							
							/* Go to MOVING mode: */
							navigationMode=MOVING;
							}
						else
							{
							/* Go to idle mode: */
							navigationMode=IDLE;
							}
						break;
					
					case SCALING:
						/* Initialize the transformation parts: */
						preScale=Geometry::invert(getButtonDeviceTransformation(0));
						preScale*=getNavigationTransformation();
						
						/* Go from SCALING to MOVING mode: */
						navigationMode=MOVING;
						break;
					
					case SCALING_PAUSED:
						/* Deactivate this tool: */
						deactivate();
						
						/* Go from SCALING_PAUSED to IDLE mode: */
						navigationMode=IDLE;
						break;
					
					default:
						/* This shouldn't happen; just ignore the event */
						break;
					}
				}
			break;
		}
	}