void WalkNavigationTool::buttonCallback(int,int buttonIndex,InputDevice::ButtonCallbackData* cbData)
	{
	if(cbData->newButtonState) // Button has just been pressed
		{
		/* Act depending on this tool's current state: */
		if(isActive())
			{
			/* Deactivate this tool: */
			deactivate();
			}
		else
			{
			/* Try activating this tool: */
			if(activate())
				{
				/* Store the center point for this navigation sequence: */
				if(factory->centerOnActivation)
					centerPoint=factory->floorPlane.project(getMainViewer()->getHeadPosition());
				
				/* Initialize the navigation transformation: */
				preScale=Vrui::getNavigationTransformation();
				translation=Vector::zero;
				rotation=Scalar(0);
				}
			}
		}
	}
Example #2
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;
				}
			}
		}
	}
FlyNavigationTool::FlyNavigationTool(const ToolFactory* factory,const ToolInputAssignment& inputAssignment)
	:NavigationTool(factory,inputAssignment),
	 viewer(0)
	{
	/* Retrieve the viewer associated with this menu tool: */
	#if 0
	int viewerIndex=configFile.retrieveValue<int>("./viewerIndex");
	viewer=getViewer(viewerIndex);
	#else
	viewer=getMainViewer();
	#endif
	}
Example #4
0
void FPSNavigationTool::stopNavigating(void)
	{
	if(mouseAdapter!=0)
		{
		/* Disable mouse warping on the controlling window: */
		mouseAdapter->setMousePosition(mouseAdapter->getWindow(),oldMousePos);
		mouseAdapter->getWindow()->setCursorPos(oldMousePos);
		mouseAdapter->getWindow()->showCursor();
		}
	
	/* Reset the navigation transformation to only retain position and yaw angle: */
	ONTransform::Rotation rot=navFrame;
	rot*=ONTransform::Rotation::rotateY(angles[0]);

	/* 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);
	}
Example #5
0
RayInputDeviceTool::RayInputDeviceTool(const ToolFactory* sFactory,const ToolInputAssignment& inputAssignment)
	:InputDeviceTool(sFactory,inputAssignment),
	 viewer(0),
	 dragger(getGlyphRenderer()->getGlyphSize(),factory->rotateFactor)
	{
	/* Retrieve the viewer associated with this tool: */
	#if 0
	int viewerIndex=configFile.retrieveValue<int>("./viewerIndex");
	viewer=getViewer(viewerIndex);
	#else
	viewer=getMainViewer();
	#endif
	}
Example #6
0
RayScreenMenuTool::RayScreenMenuTool(const ToolFactory* factory,const ToolInputAssignment& inputAssignment)
	:MenuTool(factory,inputAssignment),
	 viewer(0),
	 insideWidget(false),widgetActive(false),
	 dragging(false),draggedWidget(0)
	{
	/* Retrieve the viewer associated with this menu tool: */
	#if 0
	int viewerIndex=configFile.retrieveValue<int>("./viewerIndex");
	viewer=getViewer(viewerIndex);
	#else
	viewer=getMainViewer();
	#endif
	}
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();
	}
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;
    }
}
void SixAxisSurfaceNavigationTool::initNavState(void)
	{
	/* Set up a physical navigation frame around the main viewer's current head position: */
	headPos=getMainViewer()->getHeadPosition();
	calcPhysicalFrame(headPos);
	
	/* Calculate the initial environment-aligned surface frame in navigation coordinates: */
	surfaceFrame=getInverseNavigationTransformation()*physicalFrame;
	NavTransform newSurfaceFrame=surfaceFrame;
	
	/* Align the initial frame with the application's surface: */
	AlignmentData ad(surfaceFrame,newSurfaceFrame,factory->probeSize,factory->maxClimb);
	align(ad,angles[0],angles[1],angles[2]);
	
	/* If flying is allowed and the initial surface frame was above the surface, lift it back up: */
	Scalar z=newSurfaceFrame.inverseTransform(surfaceFrame.getOrigin())[2];
	if(!factory->canFly||z<factory->probeSize)
		z=factory->probeSize;
	newSurfaceFrame*=NavTransform::translate(Vector(Scalar(0),Scalar(0),z));
	
	/* Apply the initial navigation state: */
	surfaceFrame=newSurfaceFrame;
	applyNavState();
	}
Example #10
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 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);
			}
		}
	}
Example #12
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 WalkNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	if(isActive())
		{
		/* Get the current head position and viewing direction: */
		Point headPos=getMainViewer()->getHeadPosition();
		Vector viewDir=getMainViewer()->getViewDirection();
		
		/* Project head position and viewing direction onto floor plane: */
		headPos=factory->floorPlane.project(headPos);
		viewDir=factory->floorPlane.project(viewDir);
		viewDir.normalize();
		
		/* Calculate the movement direction and speed: */
		Vector moveDir=centerPoint-headPos;
		Scalar moveDirLen=moveDir.mag();
		Scalar speed=Scalar(0);
		if(moveDirLen>=factory->outerRadius)
			speed=factory->moveSpeed;
		else if(moveDirLen>factory->innerRadius)
			speed=factory->moveSpeed*(moveDirLen-factory->innerRadius)/(factory->outerRadius-factory->innerRadius);
		moveDir*=speed/moveDirLen;
		
		/* Calculate the rotation speed: */
		Scalar viewAngleCos=viewDir*factory->centerViewDirection;
		Scalar viewAngle;
		if(viewAngleCos>Scalar(1)-Math::Constants<Scalar>::epsilon)
			viewAngle=Scalar(0);
		else if(viewAngleCos<Scalar(-1)+Math::Constants<Scalar>::epsilon)
			viewAngle=Math::Constants<Scalar>::pi;
		else
			viewAngle=Math::acos(viewAngleCos);
		Scalar rotateAngle=Scalar(0);
		if(viewAngle>=factory->outerAngle)
			rotateAngle=factory->rotateSpeed;
		else if(viewAngle>factory->innerAngle)
			rotateAngle=factory->rotateSpeed*(viewAngle-factory->innerAngle)/(factory->outerAngle-factory->innerAngle);
		Vector x=Geometry::cross(factory->centerViewDirection,factory->floorPlane.getNormal());
		if(viewDir*x<Scalar(0))
			rotateAngle=-rotateAngle;
		
		/* Accumulate the transformation: */
		rotation+=rotateAngle*getFrameTime();
		if(rotation<-Math::Constants<Scalar>::pi)
			rotation+=Scalar(2)*Math::Constants<Scalar>::pi;
		else if(rotation>=Math::Constants<Scalar>::pi)
			rotation-=Scalar(2)*Math::Constants<Scalar>::pi;
		NavTransform::Rotation rot=NavTransform::Rotation::rotateAxis(factory->floorPlane.getNormal(),rotation);
		translation+=rot.inverseTransform(moveDir*getFrameTime());
		
		/* Set the navigation transformation: */
		NavTransform nav=NavTransform::identity;
		nav*=Vrui::NavTransform::translateFromOriginTo(centerPoint);
		nav*=Vrui::NavTransform::rotate(rot);
		nav*=Vrui::NavTransform::translateToOriginFrom(centerPoint);
		nav*=Vrui::NavTransform::translate(translation);
		nav*=preScale;
		setNavigationTransformation(nav);
		}
	}
Example #14
0
void ViewerConfiguration::buildViewerConfigurationControls(void)
	{
	/* Build the graphical user interface: */
	const GLMotif::StyleSheet& ss=*getUiStyleSheet();
	
	dialogWindow=new GLMotif::PopupWindow("ViewerConfigurationDialog",getWidgetManager(),"Viewer Configuration");
	dialogWindow->setHideButton(true);
	dialogWindow->setResizableFlags(true,false);
	
	GLMotif::RowColumn* viewerConfiguration=new GLMotif::RowColumn("ViewerConfiguration",dialogWindow,false);
	viewerConfiguration->setOrientation(GLMotif::RowColumn::VERTICAL);
	viewerConfiguration->setPacking(GLMotif::RowColumn::PACK_TIGHT);
	viewerConfiguration->setNumMinorWidgets(2);
	
	/* Create a drop-down menu to select a viewer: */
	new GLMotif::Label("ViewerLabel",viewerConfiguration,"Viewer");
	viewerMenu=new GLMotif::DropdownBox("ViewerMenu",viewerConfiguration);
	int mainViewerIndex=0;
	for(int viewerIndex=0;viewerIndex<getNumViewers();++viewerIndex)
		{
		Viewer* viewer=getViewer(viewerIndex);
		viewerMenu->addItem(viewer->getName());
		if(viewer==getMainViewer())
			mainViewerIndex=viewerIndex;
		}
	viewerMenu->setSelectedItem(mainViewerIndex);
	viewerMenu->getValueChangedCallbacks().add(this,&ViewerConfiguration::viewerMenuCallback);
	
	/* Calculate an appropriate slider range and granularity: */
	Scalar sliderRange=Scalar(18)*factory->configUnit.getInchFactor(); // Slider range is at least 18"
	Scalar sliderRangeFactor=Math::pow(Scalar(10),Math::floor(Math::log10(sliderRange)));
	sliderRange=Math::ceil(sliderRange/sliderRangeFactor)*sliderRangeFactor;
	Scalar sliderStep=Scalar(0.01)*factory->configUnit.getInchFactor(); // Slider granularity is at most 0.01"
	int sliderStepDigits=int(Math::floor(Math::log10(sliderStep)));
	Scalar sliderStepFactor=Math::pow(Scalar(10),Scalar(sliderStepDigits));
	sliderStep=Math::floor(sliderStep/sliderStepFactor)*sliderStepFactor;
	sliderStepDigits=sliderStepDigits<0?-sliderStepDigits:0;
	
	/* Create three sliders to set the mono eye position: */
	new GLMotif::Label("MonoEyePosLabel",viewerConfiguration,"Mono Eye");
	
	GLMotif::RowColumn* monoEyePosBox=new GLMotif::RowColumn("MonoEyePosBox",viewerConfiguration,false);
	monoEyePosBox->setPacking(GLMotif::RowColumn::PACK_GRID);
	for(int i=0;i<3;++i)
		{
		char epsName[14]="EyePosSlider ";
		epsName[12]=char(i+'0');
		eyePosSliders[0][i]=new GLMotif::TextFieldSlider(epsName,monoEyePosBox,7,ss.fontHeight*10.0f);
		eyePosSliders[0][i]->getTextField()->setFieldWidth(6);
		eyePosSliders[0][i]->getTextField()->setPrecision(sliderStepDigits);
		eyePosSliders[0][i]->getTextField()->setFloatFormat(GLMotif::TextField::FIXED);
		eyePosSliders[0][i]->setSliderMapping(GLMotif::TextFieldSlider::LINEAR);
		eyePosSliders[0][i]->setValueType(GLMotif::TextFieldSlider::FLOAT);
		eyePosSliders[0][i]->setValueRange(-sliderRange,sliderRange,sliderStep);
		eyePosSliders[0][i]->getValueChangedCallbacks().add(this,&ViewerConfiguration::eyePosSliderCallback,i);
		}
	monoEyePosBox->manageChild();
	
	/* Create a slider to set the eye separation distance: */
	new GLMotif::Label("EyeDistLabel",viewerConfiguration,"Eye Distance");
	
	eyeDistanceSlider=new GLMotif::TextFieldSlider("EyeDistanceSlider",viewerConfiguration,7,ss.fontHeight*10.0f);
	eyeDistanceSlider->getTextField()->setFieldWidth(6);
	eyeDistanceSlider->getTextField()->setPrecision(sliderStepDigits);
	eyeDistanceSlider->getTextField()->setFloatFormat(GLMotif::TextField::FIXED);
	eyeDistanceSlider->setSliderMapping(GLMotif::TextFieldSlider::LINEAR);
	eyeDistanceSlider->setValueType(GLMotif::TextFieldSlider::FLOAT);
	eyeDistanceSlider->setValueRange(sliderStep*Scalar(10),sliderRange,sliderStep);
	eyeDistanceSlider->getValueChangedCallbacks().add(this,&ViewerConfiguration::eyeDistanceSliderCallback);
	
	/* Create two triples of sliders to set the left and right eye positions: */
	for(int eyeIndex=1;eyeIndex<3;++eyeIndex)
		{
		/* Create a separator: */
		new GLMotif::Blind(eyeIndex==1?"Blind1":"Blind2",viewerConfiguration);
		new GLMotif::Separator(eyeIndex==1?"Separator1":"Separator2",viewerConfiguration,GLMotif::Separator::HORIZONTAL,ss.fontHeight,GLMotif::Separator::LOWERED);
		
		/* Create three sliders to set the left or right eye position: */
		new GLMotif::Label(eyeIndex==1?"LeftEyePosLabel":"RightEyePosLabel",viewerConfiguration,eyeIndex==1?"Left Eye":"Right Eye");
		
		GLMotif::RowColumn* eyePosBox=new GLMotif::RowColumn(eyeIndex==1?"LeftEyePosBox":"RightEyePosBox",viewerConfiguration,false);
		eyePosBox->setPacking(GLMotif::RowColumn::PACK_GRID);
		for(int i=0;i<3;++i)
			{
			char epsName[14]="EyePosSlider ";
			epsName[12]=char(eyeIndex*3+i+'0');
			eyePosSliders[eyeIndex][i]=new GLMotif::TextFieldSlider(epsName,eyePosBox,7,ss.fontHeight*10.0f);
			eyePosSliders[eyeIndex][i]->getTextField()->setFieldWidth(6);
			eyePosSliders[eyeIndex][i]->getTextField()->setPrecision(sliderStepDigits);
			eyePosSliders[eyeIndex][i]->getTextField()->setFloatFormat(GLMotif::TextField::FIXED);
			eyePosSliders[eyeIndex][i]->setSliderMapping(GLMotif::TextFieldSlider::LINEAR);
			eyePosSliders[eyeIndex][i]->setValueType(GLMotif::TextFieldSlider::FLOAT);
			eyePosSliders[eyeIndex][i]->setValueRange(-sliderRange,sliderRange,sliderStep);
			eyePosSliders[eyeIndex][i]->getValueChangedCallbacks().add(this,&ViewerConfiguration::eyePosSliderCallback,eyeIndex*3+i);
			}
		eyePosBox->manageChild();
		}
	
	viewerConfiguration->manageChild();
	
	/* Initialize vislet state and GUI: */
	setViewer(getViewer(mainViewerIndex));
	}
Example #15
0
void WalkNavigationTool::frame(void)
{
    /* Act depending on this tool's current state: */
    if(isActive())
    {
        /* Calculate azimuth angle change based on the current viewing direction: */
        Vector viewDir=getMainViewer()->getViewDirection();
        viewDir-=getUpDirection()*((viewDir*getUpDirection())/Geometry::sqr(getUpDirection()));
        Scalar viewDir2=Geometry::sqr(viewDir);
        if(viewDir2!=Scalar(0))
        {
            /* Calculate the rotation speed: */
            Scalar viewAngleCos=(viewDir*factory->centerViewDirection)/Math::sqrt(viewDir2);
            Scalar viewAngle;
            if(viewAngleCos>Scalar(1)-Math::Constants<Scalar>::epsilon)
                viewAngle=Scalar(0);
            else if(viewAngleCos<Scalar(-1)+Math::Constants<Scalar>::epsilon)
                viewAngle=Math::Constants<Scalar>::pi;
            else
                viewAngle=Math::acos(viewAngleCos);
            Scalar rotateSpeed=Scalar(0);
            if(viewAngle>=factory->outerAngle)
                rotateSpeed=factory->rotateSpeed;
            else if(viewAngle>factory->innerAngle)
                rotateSpeed=factory->rotateSpeed*(viewAngle-factory->innerAngle)/(factory->outerAngle-factory->innerAngle);
            Vector x=factory->centerViewDirection^getUpDirection();
            if(viewDir*x<Scalar(0))
                rotateSpeed=-rotateSpeed;

            /* Update the accumulated rotation angle: */
            azimuth+=rotateSpeed*getFrameTime();
            if(azimuth<-Math::Constants<Scalar>::pi)
                azimuth+=Scalar(2)*Math::Constants<Scalar>::pi;
            else if(azimuth>=Math::Constants<Scalar>::pi)
                azimuth-=Scalar(2)*Math::Constants<Scalar>::pi;
        }

        /* Calculate the movement direction and speed: */
        Point footPos=projectToFloor(getMainViewer()->getHeadPosition());
        Vector moveDir=centerPoint-footPos;
        Scalar moveDirLen=moveDir.mag();
        Scalar speed=Scalar(0);
        if(moveDirLen>=factory->outerRadius)
            speed=factory->moveSpeed;
        else if(moveDirLen>factory->innerRadius)
            speed=factory->moveSpeed*(moveDirLen-factory->innerRadius)/(factory->outerRadius-factory->innerRadius);
        moveDir*=speed/moveDirLen;

        /* Accumulate the transformation: */
        NavTransform::Rotation rot=NavTransform::Rotation::rotateAxis(getUpDirection(),azimuth);
        translation+=rot.inverseTransform(moveDir*getFrameTime());

        /* Set the navigation transformation: */
        NavTransform nav=NavTransform::identity;
        nav*=Vrui::NavTransform::translateFromOriginTo(centerPoint);
        nav*=Vrui::NavTransform::rotate(rot);
        nav*=Vrui::NavTransform::translateToOriginFrom(centerPoint);
        nav*=Vrui::NavTransform::translate(translation);
        nav*=preScale;
        setNavigationTransformation(nav);

        if(speed!=Scalar(0))
        {
            /* Request another frame: */
            scheduleUpdate(getApplicationTime()+1.0/125.0);
        }
    }
}