Пример #1
0
void ArtDTrack::processAsciiData(void)
	{
	while(true)
		{
		/* Wait for the next data message from the DTrack daemon: */
		char messageBuffer[4096];
		size_t messageSize=dataSocket.receiveMessage(messageBuffer,sizeof(messageBuffer)-1);
		
		/* Newline-terminate the message: */
		messageBuffer[messageSize]='\n';
		
		/* Parse the received message: */
		char* mPtr=messageBuffer;
		char* mEnd=messageBuffer+messageSize;
		while(mPtr<mEnd)
			{
			/* Find the end of the current line: */
			char* lineEnd;
			for(lineEnd=mPtr;*lineEnd!='\n';++lineEnd)
				;
			
			/* Skip whitespace: */
			while(mPtr<lineEnd&&isspace(*mPtr))
				++mPtr;
			
			/* Get the line identifier: */
			char* idStart=mPtr;
			while(mPtr<lineEnd&&!isspace(*mPtr))
				++mPtr;
			
			/* Determine the type of the line: */
			int lineType=-1;
			if(mPtr-idStart==2&&strncasecmp(idStart,"6d",2)==0)
				lineType=0;
			else if(mPtr-idStart==3&&strncasecmp(idStart,"6df",3)==0)
				lineType=1;
			else if(mPtr-idStart==4&&strncasecmp(idStart,"6df2",4)==0)
				lineType=2;
			else if(mPtr-idStart==4&&strncasecmp(idStart,"6dmt",4)==0)
				lineType=3;
			else if(mPtr-idStart==2&&strncasecmp(idStart,"3d",2)==0)
				lineType=4;
			
			/* Process the line: */
			if(lineType>=0)
				{
				if(lineType==2)
					{
					/* Skip the number of defined flysticks: */
					readInt(mPtr);
					}
				
				/* Read the number of reported bodies: */
				int numBodies=readInt(mPtr);
				
				/* Parse each body: */
				for(int body=0;body<numBodies;++body)
					{
					/* Find the first opening bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!='[')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Read the body's ID: */
					int id=readInt(mPtr);
					Device* device=deviceIdToIndex[id]>=0?&devices[deviceIdToIndex[id]]:0;
					
					/* Skip the quality value: */
					float(readFloat(mPtr));
					
					if(lineType==1||lineType==3)
						{
						/* Read the button bit flag: */
						unsigned int bits=readUint(mPtr);
						
						if(device!=0)
							{
							/* Set the button states: */
							for(int i=0;i<32&&i<device->numButtons;++i)
								{
								setButtonState(device->firstButtonIndex+i,(bits&0x1)!=0x0);
								bits>>=1;
								}
							}
						}
					
					int numButtons=0;
					int numValuators=0;
					if(lineType==2)
						{
						/* Read the number of buttons and valuators: */
						numButtons=readInt(mPtr);
						numValuators=readInt(mPtr);
						}
					
					/* Find the first closing bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!=']')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Find the second opening bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!='[')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Read the body's position: */
					Vector pos;
					for(int i=0;i<3;++i)
						pos[i]=VScalar(readFloat(mPtr));
					
					Rotation orient=Rotation::identity;
					if(lineType==0||lineType==1)
						{
						/* Read the body's orientation angles: */
						VScalar angles[3];
						for(int i=0;i<3;++i)
							angles[i]=VScalar(readFloat(mPtr));
						
						/* Calculate the body's orientation quaternion: */
						orient*=Rotation::rotateX(Math::rad(angles[0]));
						orient*=Rotation::rotateY(Math::rad(angles[1]));
						orient*=Rotation::rotateZ(Math::rad(angles[2]));
						}
					
					/* Find the second closing bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!=']')
						break; // Ignore the rest of the line
					++mPtr;
					
					if(lineType!=4)
						{
						/* Find the third opening bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!='[')
							break; // Ignore the rest of the line
						++mPtr;
						}
					
					if(lineType==2||lineType==3)
						{
						/* Read the body's orientation matrix (yuck!): */
						Geometry::Matrix<VScalar,3,3> matrix;
						for(int j=0;j<3;++j)
							for(int i=0;i<3;++i)
								matrix(i,j)=VScalar(readFloat(mPtr));
						
						/* Calculate the body's orientation quaternion: */
						orient=Rotation::fromMatrix(matrix);
						
						/* Find the third closing bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!=']')
							break; // Ignore the rest of the line
						++mPtr;
						}
					else if(lineType!=4)
						{
						/* Ignore the body's orientation matrix: */
						while(mPtr<lineEnd&&*mPtr!=']')
							++mPtr;
						if(*mPtr!=']') // Ignore the rest of the line
							break;
						}
					
					if(lineType==2)
						{
						/* Find the fourth opening bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!='[')
							break; // Ignore the rest of the line
						++mPtr;
						
						/* Read the flystick's button bits: */
						for(int bitIndex=0;bitIndex<numButtons;bitIndex+=32)
							{
							/* Read the next button bit mask: */
							unsigned int bits=readUint(mPtr);
							
							if(device!=0)
								{
								/* Set the device's button values: */
								for(int i=0;i<32;++i)
									{
									/* Set the button state if the button is valid: */
									if(bitIndex+i<device->numButtons)
										setButtonState(device->firstButtonIndex+bitIndex+i,(bits&0x1)!=0x0);
									bits>>=1;
									}
								}
							}
						
						/* Read the flystick's valuator values: */
						for(int i=0;i<numValuators;++i)
							{
							/* Read the next valuator value: */
							float value=float(readFloat(mPtr));
							
							/* Set the valuator value if the valuator is valid: */
							if(device!=0&&i<device->numValuators)
								setValuatorState(device->firstValuatorIndex+i,value);
							}
						
						/* Find the fourth closing bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!=']')
							break; // Ignore the rest of the line
						++mPtr;
						}
					
					/* Check if this body has been configured as a device: */
					if(device!=0)
						{
						/* Set the device's tracker state: */
						trackerStates[deviceIdToIndex[id]].positionOrientation=PositionOrientation(pos,orient);
						}
					}
				}
			
			/* Go to the start of the next line: */
			mPtr=lineEnd+1;
			}
		
		/* Update all tracker states (including those that were not updated): */
		for(int i=0;i<getNumTrackers();++i)
			setTrackerState(i,trackerStates[i]);
		}
Пример #2
0
void ArtDTrack::processAsciiData(void)
	{
	Vrui::VRDeviceState::TrackerState ts;
	ts.linearVelocity=Vrui::VRDeviceState::TrackerState::LinearVelocity::zero;
	ts.angularVelocity=Vrui::VRDeviceState::TrackerState::AngularVelocity::zero;
	
	while(true)
		{
		/* Wait for the next data message from the DTrack daemon: */
		char messageBuffer[4096];
		size_t messageSize=dataSocket.receiveMessage(messageBuffer,sizeof(messageBuffer)-1);
		
		/* Newline-terminate the message as a sentinel: */
		messageBuffer[messageSize]='\n';
		
		/* Parse the received message: */
		const char* mPtr=messageBuffer;
		const char* mEnd=messageBuffer+(messageSize+1);
		while(mPtr!=mEnd)
			{
			/* Skip whitespace, but not the line terminator: */
			while(*mPtr!='\n'&&isspace(*mPtr))
				++mPtr;
			
			/* Get the line's device report format: */
			DeviceReportFormat drf=parseDeviceReportFormat(mPtr,0,&mPtr);
			
			/* Process the line: */
			if(drf!=DRF_NUMFORMATS)
				{
				if(drf==DRF_6DF2)
					{
					/* Skip the number of defined flysticks: */
					readInt(mPtr);
					}
				
				/* Read the number of bodies in this report: */
				int numBodies=readInt(mPtr);
				
				/* Parse all body reports: */
				for(int body=0;body<numBodies;++body)
					{
					/* Check for opening bracket: */
					if(!expectChar('[',mPtr))
						break;
					
					/* Read the body's ID and find the corresponding device structure: */
					int id=readInt(mPtr);
					int deviceIndex=deviceIdToIndex[drf][id];
					Device* device=deviceIndex>=0?&devices[deviceIndex]:0;
					
					/* Read the quality value: */
					float quality=float(readFloat(mPtr));
					
					/* Read button/valuator or finger data depending on report format: */
					int numButtons=0;
					int numValuators=0;
					int numFingers=0;
					
					if(drf==DRF_6DF)
						{
						/* Read the button bit mask: */
						unsigned int buttonBits=readUint(mPtr);
						
						if(device!=0)
							{
							/* Set the device's button states: */
							for(int i=0;i<32&&i<device->numButtons;++i,buttonBits>>=1)
								setButtonState(device->firstButtonIndex+i,(buttonBits&0x1)!=0x0);
							}
						}
					if(drf==DRF_6DF2||drf==DRF_6DMT)
						{
						/* Read the number of buttons: */
						numButtons=readInt(mPtr);
						if(drf==DRF_6DF2)
							{
							/* Read the number of valuators: */
							numValuators=readInt(mPtr);
							}
						}
					if(drf==DRF_GL)
						{
						/* Skip the glove's handedness: */
						readInt(mPtr);
						
						/* Read the number of fingers: */
						numFingers=readInt(mPtr);
						}
					
					/* Check for closing bracket followed by opening bracket: */
					if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
						break;
					
					Vector pos;
					Rotation orient=Rotation::identity;
					
					/* Read the body's 3D position: */
					for(int i=0;i<3;++i)
						pos[i]=VScalar(readFloat(mPtr));
					
					if(drf!=DRF_3D)
						{
						/* Read the body's 3D orientation: */
						if(drf==DRF_6D||drf==DRF_6DF)
							{
							/* Read the body's orientation angles: */
							VScalar angles[3];
							for(int i=0;i<3;++i)
								angles[i]=VScalar(readFloat(mPtr));
							
							/* Convert the orientation angles to a 3D rotation: */
							orient*=Rotation::rotateX(Math::rad(angles[0]));
							orient*=Rotation::rotateY(Math::rad(angles[1]));
							orient*=Rotation::rotateZ(Math::rad(angles[2]));
							}
					
						/* Check for closing bracket followed by opening bracket: */
						if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
							break;
						
						if(drf==DRF_6DF2||drf==DRF_6DMT||drf==DRF_GL)
							{
							/* Read the body's orientation matrix (yuck!): */
							Geometry::Matrix<VScalar,3,3> matrix;
							for(int j=0;j<3;++j)
								for(int i=0;i<3;++i)
									matrix(i,j)=VScalar(readFloat(mPtr));
							
							if(quality>0.0f)
								{
								/* Calculate the body's orientation quaternion (YUCK!): */
								orient=Rotation::fromMatrix(matrix);
								}
							}
						else
							{
							/* Skip the body's orientation matrix: */
							for(int i=0;i<9;++i)
								readFloat(mPtr);
							}
						}
					
					/* Check for closing bracket: */
					if(!expectChar(']',mPtr))
						break;
					
					if(drf==DRF_6DF2)
						{
						/* Check for opening bracket: */
						if(!expectChar('[',mPtr))
							break;
						
						/* Read button states: */
						for(int bitIndex=0;bitIndex<numButtons;bitIndex+=32)
							{
							/* Read the next button bit mask: */
							unsigned int buttonBits=readUint(mPtr);
							
							if(device!=0)
								{
								/* Set the device's button states: */
								for(int i=0;i<32&&bitIndex+i<device->numButtons;++i,buttonBits>>=1)
									setButtonState(device->firstButtonIndex+bitIndex+i,(buttonBits&0x1)!=0x0);
								}
							}
						
						/* Read valuator states: */
						for(int i=0;i<numValuators;++i)
							{
							/* Read the next valuator value: */
							float value=float(readFloat(mPtr));
							
							/* Set the valuator value if the valuator is valid: */
							if(device!=0&&i<device->numValuators)
								setValuatorState(device->firstValuatorIndex+i,value);
							}
						
						/* Check for closing bracket: */
						if(!expectChar(']',mPtr))
							break;
						}
					
					if(drf==DRF_GL)
						{
						/* Skip all finger data for now: */
						bool error=false;
						for(int finger=0;finger<numFingers;++finger)
							{
							/* Check for opening bracket: */
							if(!expectChar('[',mPtr))
								{
								error=true;
								break;
								}
							
							/* Skip finger position: */
							for(int i=0;i<3;++i)
								readFloat(mPtr);
							
							/* Check for closing followed by opening bracket: */
							if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
								{
								error=true;
								break;
								}
							
							/* Skip finger orientation: */
							for(int i=0;i<9;++i)
								readFloat(mPtr);
							
							/* Check for closing followed by opening bracket: */
							if(!expectChar(']',mPtr)||!expectChar('[',mPtr))
								{
								error=true;
								break;
								}
							
							/* Skip finger bending parameters: */
							for(int i=0;i<6;++i)
								readFloat(mPtr);
							
							/* Check for closing bracket: */
							if(!expectChar(']',mPtr))
								{
								error=true;
								break;
								}
							}
						
						/* Stop parsing the packet on syntax error: */
						if(error)
							break;
						}
					
					/* Check if this body has a valid position/orientation and has been configured as a device: */
					if(quality>0.0f&&device!=0)
						{
						/* Set the device's tracker state: */
						ts.positionOrientation=PositionOrientation(pos,orient);
						setTrackerState(deviceIndex,ts);
						}
					}
				}
			
			/* Skip the rest of the line: */
			while(*mPtr!='\n')
				++mPtr;
			
			/* Go to the next line: */
			++mPtr;
			}
		
		/* Tell the VR device manager that the current state has updated completely: */
		updateState();
		}