int main(int argc,char* argv[]) { /* Open the input file: */ IO::FilePtr inputDeviceDataFile(IO::openFile(argv[1])); inputDeviceDataFile->setEndianness(Misc::LittleEndian); /* Read file header: */ int numInputDevices=inputDeviceDataFile->read<int>(); Vrui::InputDevice** inputDevices=new Vrui::InputDevice*[numInputDevices]; /* Initialize devices: */ for(int i=0;i<numInputDevices;++i) { /* Read device's layout from file: */ DeviceFileHeader header; inputDeviceDataFile->read(header.name,sizeof(header.name)); inputDeviceDataFile->read(header.trackType); inputDeviceDataFile->read(header.numButtons); inputDeviceDataFile->read(header.numValuators); inputDeviceDataFile->read(header.deviceRayDirection.getComponents(),3); /* Create new input device: */ Vrui::InputDevice* newDevice=new Vrui::InputDevice; newDevice->set(header.name,header.trackType,header.numButtons,header.numValuators); newDevice->setDeviceRayDirection(header.deviceRayDirection); /* Store the input device: */ inputDevices[i]=newDevice; } /* Read all data frames from the input device data file: */ while(true) { /* Read the next time stamp: */ double timeStamp; try { timeStamp=inputDeviceDataFile->read<double>(); } catch(IO::File::ReadError) { /* At end of file */ break; } std::cout<<"Time stamp: "<<std::fixed<<std::setw(8)<<std::setprecision(3)<<timeStamp; /* Read data for all input devices: */ for(int device=0;device<numInputDevices;++device) { /* Update tracker state: */ if(inputDevices[device]->getTrackType()!=Vrui::InputDevice::TRACK_NONE) { Vrui::TrackerState::Vector translation; inputDeviceDataFile->read(translation.getComponents(),3); Vrui::Scalar quat[4]; inputDeviceDataFile->read(quat,4); inputDevices[device]->setTransformation(Vrui::TrackerState(translation,Vrui::TrackerState::Rotation(quat))); } /* Update button states: */ for(int i=0;i<inputDevices[device]->getNumButtons();++i) { int buttonState=inputDeviceDataFile->read<int>(); inputDevices[device]->setButtonState(i,buttonState); } /* Update valuator states: */ for(int i=0;i<inputDevices[device]->getNumValuators();++i) { double valuatorState=inputDeviceDataFile->read<double>(); inputDevices[device]->setValuator(i,valuatorState); } } std::cout<<std::endl; } return 0; }
int main(int argc,char* argv[]) { /* Open the input file: */ IO::SeekableFilePtr inputDeviceDataFile(IO::openSeekableFile(argv[1])); inputDeviceDataFile->setEndianness(Misc::LittleEndian); /* Read the file header: */ static const char* fileHeader="Vrui Input Device Data File v3.0\n"; char header[34]; inputDeviceDataFile->read<char>(header,34); header[33]='\0'; int fileVersion; if(strncmp(header,fileHeader,29)!=0) { /* Pre-versioning file version: */ fileVersion=1; /* Old file format doesn't have the header text: */ inputDeviceDataFile->setReadPosAbs(0); } else if(strcmp(header+29,"2.0\n")==0) { /* File version without ray direction and velocities: */ fileVersion=2; } else if(strcmp(header+29,"3.0\n")==0) { /* File version with ray direction and velocities: */ fileVersion=3; } else { header[32]='\0'; std::cerr<<"Unsupported input device data file version "<<header+29<<std::endl; return 1; } /* Skip random seed value: */ inputDeviceDataFile->read<unsigned int>(); /* Read file header: */ int numInputDevices=inputDeviceDataFile->read<int>(); Vrui::InputDevice** inputDevices=new Vrui::InputDevice*[numInputDevices]; int* deviceFeatureBaseIndices=new int[numInputDevices]; std::vector<std::string> deviceFeatureNames; /* Initialize devices: */ for(int i=0;i<numInputDevices;++i) { /* Read device's name and layout from file: */ std::string name; if(fileVersion>=2) name=Misc::readCppString(*inputDeviceDataFile); else { /* Read a fixed-size string: */ char nameBuffer[40]; inputDeviceDataFile->read(nameBuffer,sizeof(nameBuffer)); name=nameBuffer; } int trackType=inputDeviceDataFile->read<int>(); int numButtons=inputDeviceDataFile->read<int>(); int numValuators=inputDeviceDataFile->read<int>(); /* Create new input device: */ Vrui::InputDevice* newDevice=new Vrui::InputDevice; newDevice->set(name.c_str(),trackType,numButtons,numValuators); if(fileVersion<3) { Vrui::Vector deviceRayDirection; inputDeviceDataFile->read(deviceRayDirection.getComponents(),3); newDevice->setDeviceRay(deviceRayDirection,Vrui::Scalar(0)); } /* Store the input device: */ inputDevices[i]=newDevice; /* Read or create the device's feature names: */ deviceFeatureBaseIndices[i]=int(deviceFeatureNames.size()); if(fileVersion>=2) { /* 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(Vrui::InputDeviceFeature(newDevice,j))); } } /* Read all data frames from the input device data file: */ while(true) { /* Read the next time stamp: */ double timeStamp; try { timeStamp=inputDeviceDataFile->read<double>(); } catch(IO::File::ReadError) { /* At end of file */ break; } std::cout<<"Time stamp: "<<std::fixed<<std::setw(8)<<std::setprecision(3)<<timeStamp; /* Read data for all input devices: */ for(int device=0;device<numInputDevices;++device) { /* Update tracker state: */ if(inputDevices[device]->getTrackType()!=Vrui::InputDevice::TRACK_NONE) { if(fileVersion>=3) { Vrui::Vector deviceRayDir; inputDeviceDataFile->read(deviceRayDir.getComponents(),3); Vrui::Scalar deviceRayStart=inputDeviceDataFile->read<Vrui::Scalar>(); inputDevices[device]->setDeviceRay(deviceRayDir,deviceRayStart); } Vrui::TrackerState::Vector translation; inputDeviceDataFile->read(translation.getComponents(),3); Vrui::Scalar quat[4]; inputDeviceDataFile->read(quat,4); inputDevices[device]->setTransformation(Vrui::TrackerState(translation,Vrui::TrackerState::Rotation(quat))); if(fileVersion>=3) { Vrui::Vector linearVelocity,angularVelocity; inputDeviceDataFile->read(linearVelocity.getComponents(),3); inputDeviceDataFile->read(angularVelocity.getComponents(),3); inputDevices[device]->setLinearVelocity(linearVelocity); inputDevices[device]->setAngularVelocity(angularVelocity); } } /* Update button states: */ if(fileVersion>=3) { unsigned char buttonBits=0x00U; int numBits=0; for(int i=0;i<inputDevices[device]->getNumButtons();++i) { if(numBits==0) { buttonBits=inputDeviceDataFile->read<unsigned char>(); numBits=8; } inputDevices[device]->setButtonState(i,(buttonBits&0x80U)!=0x00U); buttonBits<<=1; --numBits; } } else { for(int i=0;i<inputDevices[device]->getNumButtons();++i) { int buttonState=inputDeviceDataFile->read<int>(); inputDevices[device]->setButtonState(i,buttonState); } } /* Update valuator states: */ for(int i=0;i<inputDevices[device]->getNumValuators();++i) { double valuatorState=inputDeviceDataFile->read<double>(); inputDevices[device]->setValuator(i,valuatorState); } } std::cout<<std::endl; } return 0; }