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 GrapheinClient::GrapheinTool::frame(void)
{
    if(client==0)
        return;

    if(active)
    {
        /* Update the current dragging point: */
        const Vrui::NavTransform& invNav=Vrui::getInverseNavigationTransformation();
        currentPoint=invNav.transform(getButtonDevicePosition(0));

        /* Check if the dragging point is far enough away from the most recent curve vertex: */
        if(Geometry::sqrDist(currentPoint,lastPoint)>=Math::sqr(Vrui::getUiSize()*invNav.getScaling()))
        {
            CurveMap::Iterator cIt=client->localCurves.findEntry(currentCurveId);
            if(!cIt.isFinished())
            {
                /* Add the dragging point to the curve: */
                cIt->getDest()->vertices.push_back(currentPoint);

                /* Send a vertex appending message: */
                {
                    Threads::Mutex::Lock messageLock(client->messageMutex);
                    writeMessage(APPEND_POINT,client->message);
                    client->message.write<Card>(currentCurveId);
                    write(currentPoint,client->message);
                }
            }

            /* Remember the last added point: */
            lastPoint=currentPoint;
        }
    }
}
Esempio n. 3
0
void SketchingTool::buttonCallback(int,InputDevice::ButtonCallbackData* cbData)
	{
	/* Check if the button has just been pressed: */
	if(cbData->newButtonState)
		{
		/* Activate the tool: */
		active=true;
		
		/* Start a new curve: */
		currentCurve=new Curve;
		currentCurve->lineWidth=newLineWidth;
		currentCurve->color=newColor;
		curves.push_back(currentCurve);
		
		/* Append the curve's first control point: */
		Curve::ControlPoint cp;
		const NavTransform& invNav=getInverseNavigationTransformation();
		cp.pos=lastPoint=invNav.transform(getButtonDevicePosition(0));
		cp.t=getApplicationTime();
		currentCurve->controlPoints.push_back(cp);
		}
	else
		{
		/* Append the final control point to the curve: */
		Curve::ControlPoint cp;
		cp.pos=currentPoint;
		cp.t=getApplicationTime();
		currentCurve->controlPoints.push_back(cp);
		
		/* Deactivate the tool: */
		active=false;
		currentCurve=0;
		}
	}
void GrapheinClient::GrapheinTool::buttonCallback(int,Vrui::InputDevice::ButtonCallbackData* cbData)
{
    if(client==0)
        return;

    /* Check if the button has just been pressed: */
    if(cbData->newButtonState)
    {
        /* Activate the tool: */
        active=true;

        /* Start a new curve: */
        currentCurveId=client->nextLocalCurveId;
        ++client->nextLocalCurveId;
        Curve* newCurve=new Curve;
        newCurve->lineWidth=newLineWidth;
        newCurve->color=newColor;
        const Vrui::NavTransform& invNav=Vrui::getInverseNavigationTransformation();
        lastPoint=invNav.transform(getButtonDevicePosition(0));
        newCurve->vertices.push_back(lastPoint);
        client->localCurves.setEntry(CurveMap::Entry(currentCurveId,newCurve));

        /* Send a curve creation message: */
        {
            Threads::Mutex::Lock messageLock(client->messageMutex);
            writeMessage(ADD_CURVE,client->message);
            client->message.write<Card>(currentCurveId);
            newCurve->write(client->message);
        }
    }
    else
    {
        /* Retrieve the current curve: */
        CurveMap::Iterator cIt=client->localCurves.findEntry(currentCurveId);
        if(!cIt.isFinished())
        {
            if(currentPoint!=lastPoint)
            {
                /* Add the final dragging point to the curve: */
                cIt->getDest()->vertices.push_back(currentPoint);

                /* Send a vertex appending message: */
                {
                    Threads::Mutex::Lock messageLock(client->messageMutex);
                    writeMessage(APPEND_POINT,client->message);
                    client->message.write<Card>(currentCurveId);
                    write(currentPoint,client->message);
                }
            }
        }

        /* Deactivate the tool: */
        active=false;
    }
}
Esempio n. 5
0
void JediTool::frame(void)
	{
	if(active)
		{
		/* Update the light saber billboard: */
		origin=getButtonDevicePosition(0);
		axis=getButtonDeviceRayDirection(0);
		
		/* Scale the lightsaber during activation: */
		length=factory->lightsaberLength;
		double activeTime=getApplicationTime()-activationTime;
		if(activeTime<1.5)
			{
			length*=activeTime/1.5;
			
			/* Request another frame: */
			scheduleUpdate(getNextAnimationTime());
			}
		}
	}
void SixDofWithScaleNavigationTool::frame(void)
	{
	/* Act depending on this tool's current state: */
	switch(navigationMode)
		{
		case IDLE:
			/* Do nothing */
			break;
		
		case MOVING:
			{
			/* Compose the new navigation transformation: */
			NavTrackerState navigation=getButtonDeviceTransformation(0);
			navigation*=preScale;
			
			/* Update Vrui's navigation transformation: */
			setNavigationTransformation(navigation);
			break;
			}
		
		case SCALING:
			{
			/* Compose the new navigation transformation: */
			NavTrackerState navigation=preScale;
			Vector scaleDirection=getButtonDeviceTransformation(1).transform(factory->deviceScaleDirection);
			Scalar currentScale=Math::exp((getButtonDevicePosition(0)*scaleDirection-initialScale)/factory->scaleFactor);
			navigation*=NavTrackerState::scale(currentScale);
			navigation*=postScale;
			
			/* Update Vrui's navigation transformation: */
			setNavigationTransformation(navigation);
			break;
			}
		}
	
	/* Update the virtual input device: */
	InputDevice* device=getButtonDevice(1);
	buttonDevice->setTransformation(device->getTransformation());
	buttonDevice->setDeviceRayDirection(device->getDeviceRayDirection());
	}
Esempio n. 7
0
void SketchingTool::frame(void)
	{
	if(active)
		{
		/* Get the current dragging point: */
		const NavTransform& invNav=getInverseNavigationTransformation();
		currentPoint=invNav.transform(getButtonDevicePosition(0));
		
		/* Check if the dragging point is far enough away from the most recent curve vertex: */
		if(Geometry::sqrDist(currentPoint,lastPoint)>=Math::sqr(factory->detailSize*invNav.getScaling()))
			{
			/* Append the current dragging point to the curve: */
			Curve::ControlPoint cp;
			cp.pos=currentPoint;
			cp.t=getApplicationTime();
			currentCurve->controlPoints.push_back(cp);
			
			/* Remember the last added point: */
			lastPoint=currentPoint;
			}
		}
	}
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;
		}
	}
void MultiDeviceNavigationTool::frame(void)
	{
	/* Do nothing if the tool is inactive: */
	if(isActive())
		{
		/* Calculate the centroid of all devices whose buttons were pressed in the last frame: */
		int numLastDevices=0;
		Point::AffineCombiner centroidC;
		for(int i=0;i<input.getNumButtonSlots();++i)
			if(lastDeviceButtonStates[i])
				{
				++numLastDevices;
				centroidC.addPoint(getButtonDevicePosition(i));
				}
		
		if(numLastDevices>0)
			{
			Point currentCentroid=centroidC.getPoint();
			
			/* Calculate the average rotation vector and scaling factor of all devices whose buttons were pressed in the last frame: */
			Vector rotation=Vector::zero;
			Scalar scaling(1);
			int numActiveDevices=0;
			for(int i=0;i<input.getNumButtonSlots();++i)
				if(lastDeviceButtonStates[i])
					{
					/* Calculate the previous vector to centroid: */
					Vector lastDist=lastDevicePositions[i]-lastCentroid;
					Scalar lastLen=Geometry::mag(lastDist);
					
					/* Calculate the new vector to centroid: */
					Vector currentDist=getButtonDevicePosition(i)-currentCentroid;
					Scalar currentLen=Geometry::mag(currentDist);
					
					if(lastLen>configuration.minRotationScalingDistance&&currentLen>configuration.minRotationScalingDistance)
						{
						/* Calculate the rotation axis and angle: */
						Vector rot=lastDist^currentDist;
						Scalar rotLen=Geometry::mag(rot);
						if(rotLen>Scalar(0))
							{
							Scalar angle=Math::asin(rotLen/(lastLen*currentLen));
							rot*=angle/rotLen;
							
							/* Accumulate the rotation vector: */
							rotation+=rot;
							}
						
						/* Calculate the scaling factor: */
						Scalar scal=currentLen/lastLen;
						
						/* Accumulate the scaling factor: */
						scaling*=scal;
						
						++numActiveDevices;
						}
					}
			
			/* Navigate: */
			NavTransform t=NavTransform::translate((currentCentroid-lastCentroid)*configuration.translationFactor);
			if(numActiveDevices>0)
				{
				/* Average and scale rotation and scaling: */
				rotation*=configuration.rotationFactor/Scalar(numActiveDevices);
				scaling=Math::pow(scaling,configuration.scalingFactor/Scalar(numActiveDevices));
				
				/* Apply rotation and scaling: */
				t*=NavTransform::translateFromOriginTo(currentCentroid);
				t*=NavTransform::rotate(Rotation::rotateScaledAxis(rotation));
				t*=NavTransform::scale(scaling);
				t*=NavTransform::translateToOriginFrom(currentCentroid);
				}
			concatenateNavigationTransformationLeft(t);
			}
		
		/* Update button states and device positions for next frame: */
		Point::AffineCombiner newLastCentroidC;
		for(int i=0;i<input.getNumButtonSlots();++i)
			{
			lastDeviceButtonStates[i]=getButtonState(i);
			lastDevicePositions[i]=getButtonDevicePosition(i);
			if(lastDeviceButtonStates[i])
				newLastCentroidC.addPoint(lastDevicePositions[i]);
			}
		lastCentroid=newLastCentroidC.getPoint();
		}
	}