InputDeviceFeatureSet WidgetTool::getForwardedFeatures(const InputDeviceFeature& sourceFeature) { /* Paranoia: Check if the source feature belongs to this tool: */ if(input.findFeature(sourceFeature)!=0) Misc::throwStdErr("WidgetTool::getForwardedFeatures: Source feature is not part of tool's input assignment"); /* Return the forwarded feature: */ InputDeviceFeatureSet result; result.push_back(InputDeviceFeature(buttonDevice,InputDevice::BUTTON,0)); return result; }
InputDeviceFeatureSet TransformTool::getForwardedFeatures(const InputDeviceFeature& sourceFeature) { /* Find the input assignment slot for the given feature: */ int slotIndex=input.findFeature(sourceFeature); /* Check if the source feature belongs to this tool: */ if(slotIndex<0) Misc::throwStdErr("TransformTool::getForwardedFeatures: Source feature is not part of tool's input assignment"); /* Create an empty feature set: */ InputDeviceFeatureSet result; /* Check if the feature is a button or valuator: */ if(sourceFeature.isButton()) { /* Get the slot's button slot index: */ int buttonSlotIndex=input.getButtonSlotIndex(slotIndex); /* Check if the button is part of the forwarded subset: */ if(buttonSlotIndex>=numPrivateButtons) { /* Add the forwarded feature to the result set: */ result.push_back(InputDeviceFeature(transformedDevice,InputDevice::BUTTON,buttonSlotIndex-numPrivateButtons)); } } if(sourceFeature.isValuator()) { /* Get the slot's valuator slot index: */ int valuatorSlotIndex=input.getValuatorSlotIndex(slotIndex); /* Check if the valuator is part of the forwarded subset: */ if(valuatorSlotIndex>=numPrivateValuators) { /* Add the forwarded feature to the result set: */ result.push_back(InputDeviceFeature(transformedDevice,InputDevice::VALUATOR,valuatorSlotIndex-numPrivateValuators)); } } return result; }
InputDeviceFeatureSet RevolverTool::getForwardedFeatures(const InputDeviceFeature& sourceFeature) { /* Find the input assignment slot for the given feature: */ int slotIndex=input.findFeature(sourceFeature); /* Check if the source feature belongs to this tool: */ if(slotIndex<0) Misc::throwStdErr("RevolverTool::getForwardedFeatures: Source feature is not part of tool's input assignment"); /* Create an empty feature set: */ InputDeviceFeatureSet result; /* Check if the feature is a button or valuator: */ if(sourceFeature.isButton()) { /* Get the slot's button slot index: */ int buttonSlotIndex=input.getButtonSlotIndex(slotIndex); /* Check if the button is part of the forwarded subset: */ if(buttonSlotIndex>=1) { /* Add the forwarded feature for the current chamber to the result set: */ int baseButtonIndex=(buttonSlotIndex-1)*factory->numChambers; result.push_back(InputDeviceFeature(transformedDevice,InputDevice::BUTTON,baseButtonIndex+currentChamber)); } } if(sourceFeature.isValuator()) { /* Get the slot's valuator slot index: */ int valuatorSlotIndex=input.getValuatorSlotIndex(slotIndex); /* Add the forwarded feature for the current chamber to the result set: */ int baseValuatorIndex=valuatorSlotIndex*factory->numChambers; result.push_back(InputDeviceFeature(transformedDevice,InputDevice::VALUATOR,baseValuatorIndex+currentChamber)); } return result; }
InputDeviceFeatureSet WandNavigationTool::getForwardedFeatures(const InputDeviceFeature& sourceFeature) { /* Get the source feature's assignment slot index: */ int slotIndex=input.findFeature(sourceFeature); /* Paranoia: Check if the source feature belongs to this tool: */ if(slotIndex<0) Misc::throwStdErr("WandNavigationTool::getForwardedFeatures: Source feature is not part of tool's input assignment"); /* Return the forwarded feature: */ InputDeviceFeatureSet result; if(slotIndex==1) result.push_back(InputDeviceFeature(buttonDevice,InputDevice::BUTTON,0)); return result; }
InputDeviceFeatureSet ButtonToValuatorTool::getForwardedFeatures(const InputDeviceFeature& sourceFeature) { /* Find the input assignment slot for the given feature: */ int slotIndex=input.findFeature(sourceFeature); /* Check if the source feature belongs to this tool: */ if(slotIndex<0) Misc::throwStdErr("ButtonToValuatorTool::getForwardedFeatures: Source feature is not part of tool's input assignment"); /* The only forwarded feature is the valuator slot: */ InputDeviceFeatureSet result; result.push_back(InputDeviceFeature(transformedDevice,InputDevice::VALUATOR,0)); return result; }
InputDeviceFeatureSet ValuatorToButtonTool::getForwardedFeatures(const InputDeviceFeature& sourceFeature) { /* Find the input assignment slot for the given feature: */ int slotIndex=input.findFeature(sourceFeature); /* Check if the source feature belongs to this tool: */ if(slotIndex<0) Misc::throwStdErr("ValuatorToButtonTool::getForwardedFeatures: Source feature is not part of tool's input assignment"); /* Get the slot's valuator slot index: */ int valuatorSlotIndex=input.getValuatorSlotIndex(slotIndex); /* Return the two button slots fed by the source valuator slot: */ InputDeviceFeatureSet result; for(int i=0;i<2;++i) result.push_back(InputDeviceFeature(transformedDevice,InputDevice::BUTTON,valuatorSlotIndex*2+i)); return result; }
InputDeviceAdapterPlayback::InputDeviceAdapterPlayback(InputDeviceManager* sInputDeviceManager,const Misc::ConfigurationFileSection& configFileSection) :InputDeviceAdapter(sInputDeviceManager), inputDeviceDataFile(configFileSection.retrieveString("./inputDeviceDataFileName").c_str(),"rb",Misc::File::LittleEndian), mouseCursorFaker(0), synchronizePlayback(configFileSection.retrieveValue<bool>("./synchronizePlayback",false)), quitWhenDone(configFileSection.retrieveValue<bool>("./quitWhenDone",false)), soundPlayer(0), saveMovie(configFileSection.retrieveValue<bool>("./saveMovie",false)), movieWindowIndex(0),movieWindow(0), firstFrame(true),timeStamp(0.0), done(false) { /* Read file header: */ static const char* fileHeader="Vrui Input Device Data File v2.0\n"; char header[34]; inputDeviceDataFile.read<char>(header,34); bool haveFeatureNames=strncmp(header,fileHeader,34)==0; if(!haveFeatureNames) { /* Old file format doesn't have the header text: */ inputDeviceDataFile.rewind(); } /* Read random seed value: */ unsigned int randomSeed=inputDeviceDataFile.read<unsigned int>(); setRandomSeed(randomSeed); /* Read number of saved input devices: */ numInputDevices=inputDeviceDataFile.read<int>(); inputDevices=new InputDevice*[numInputDevices]; deviceFeatureBaseIndices=new int[numInputDevices]; /* Initialize devices: */ for(int i=0;i<numInputDevices;++i) { /* Read device's name and layout from file: */ std::string name=Misc::readCppString(inputDeviceDataFile); int trackType=inputDeviceDataFile.read<int>(); int numButtons=inputDeviceDataFile.read<int>(); int numValuators=inputDeviceDataFile.read<int>(); Vector deviceRayDirection; inputDeviceDataFile.read<Scalar>(deviceRayDirection.getComponents(),3); /* Create new input device: */ InputDevice* newDevice=inputDeviceManager->createInputDevice(name.c_str(),trackType,numButtons,numValuators,true); newDevice->setDeviceRayDirection(deviceRayDirection); /* Initialize the new device's glyph from the current configuration file section: */ Glyph& deviceGlyph=inputDeviceManager->getInputGraphManager()->getInputDeviceGlyph(newDevice); char deviceGlyphTypeTag[20]; snprintf(deviceGlyphTypeTag,sizeof(deviceGlyphTypeTag),"./device%dGlyphType",i); char deviceGlyphMaterialTag[20]; snprintf(deviceGlyphMaterialTag,sizeof(deviceGlyphMaterialTag),"./device%dGlyphMaterial",i); deviceGlyph.configure(configFileSection,deviceGlyphTypeTag,deviceGlyphMaterialTag); /* Store the input device: */ inputDevices[i]=newDevice; /* Read or create the device's feature names: */ deviceFeatureBaseIndices[i]=int(deviceFeatureNames.size()); if(haveFeatureNames) { /* Read feature names from file: */ for(int j=0;j<newDevice->getNumFeatures();++j) deviceFeatureNames.push_back(Misc::readCppString(inputDeviceDataFile)); } else { /* Create default feature names: */ for(int j=0;j<newDevice->getNumFeatures();++j) deviceFeatureNames.push_back(getDefaultFeatureName(InputDeviceFeature(newDevice,j))); } } /* Check if the user wants to use a fake mouse cursor: */ int fakeMouseCursorDevice=configFileSection.retrieveValue<int>("./fakeMouseCursorDevice",-1); if(fakeMouseCursorDevice>=0) { /* Read the cursor file name and nominal size: */ std::string mouseCursorImageFileName=configFileSection.retrieveString("./mouseCursorImageFileName",DEFAULTMOUSECURSORIMAGEFILENAME); unsigned int mouseCursorNominalSize=configFileSection.retrieveValue<unsigned int>("./mouseCursorNominalSize",24); /* Create the mouse cursor faker: */ mouseCursorFaker=new MouseCursorFaker(inputDevices[fakeMouseCursorDevice],mouseCursorImageFileName.c_str(),mouseCursorNominalSize); mouseCursorFaker->setCursorSize(configFileSection.retrieveValue<Size>("./mouseCursorSize",mouseCursorFaker->getCursorSize())); mouseCursorFaker->setCursorHotspot(configFileSection.retrieveValue<Vector>("./mouseCursorHotspot",mouseCursorFaker->getCursorHotspot())); } /* Read time stamp of first data frame: */ try { nextTimeStamp=inputDeviceDataFile.read<double>(); /* Request an update for the next frame: */ requestUpdate(); } catch(Misc::File::ReadError) { done=true; nextTimeStamp=Math::Constants<double>::max; if(quitWhenDone) { /* Request exiting the program: */ shutdown(); } } /* Check if the user wants to play back a commentary sound track: */ std::string soundFileName=configFileSection.retrieveString("./soundFileName",""); if(soundFileName!="") { try { /* Create a sound player for the given sound file name: */ soundPlayer=new Sound::SoundPlayer(soundFileName.c_str()); } catch(std::runtime_error error) { /* Print a message, but carry on: */ std::cerr<<"InputDeviceAdapterPlayback: Disabling sound playback due to exception "<<error.what()<<std::endl; } } /* Check if the user wants to save a movie: */ if(saveMovie) { /* Read the movie image file name template: */ movieFileNameTemplate=configFileSection.retrieveString("./movieFileNameTemplate"); /* Check if the name template has the correct format: */ int numConversions=0; bool hasIntConversion=false; for(std::string::const_iterator mfntIt=movieFileNameTemplate.begin();mfntIt!=movieFileNameTemplate.end();++mfntIt) { if(*mfntIt=='%') { ++mfntIt; if(*mfntIt!='%') { ++numConversions; /* Skip width modifiers: */ while(isdigit(*mfntIt)) ++mfntIt; /* Check for integer conversion: */ if(*mfntIt=='d') hasIntConversion=true; } } else if(*mfntIt=='/') // Only accept conversions in the file name part hasIntConversion=false; } if(numConversions!=1||!hasIntConversion) Misc::throwStdErr("InputDeviceAdapterPlayback::InputDeviceAdapterPlayback: movie file name template \"%s\" does not have exactly one %%d conversion",movieFileNameTemplate.c_str()); /* Get the index of the window from which to save the frames: */ movieWindowIndex=configFileSection.retrieveValue<int>("./movieWindowIndex",movieWindowIndex); /* Get the intended frame rate for the movie: */ double frameRate=configFileSection.retrieveValue<double>("./movieFrameRate",30.0); movieFrameTimeInterval=1.0/frameRate; /* Calculate the first time at which to save a frame: */ nextMovieFrameTime=nextTimeStamp+movieFrameTimeInterval*0.5; nextMovieFrameCounter=0; } }