void PCWand::deviceThreadMethod(void) { /* Process messages until killed: */ while(true) { /* Wait for next message: */ unsigned char byte=(unsigned char)devicePort.getChar(); /* Parse message: */ if(byte>='0'&&byte<='1') { /* It's a valuator value packet; skip the next byte and read the value: */ int valuatorIndex=byte-'0'; devicePort.getChar(); unsigned char valueByte=(unsigned char)devicePort.getChar(); float value=(float(valueByte)*2.0f)/255.f-1.0f; deviceValuatorStates[valuatorIndex]=value; /* Set the valuator value in the device manager: */ { Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); if(reportEvents) setValuatorState(valuatorIndex,value); } } else if(byte>=216&&byte<=218) { /* It's a button press packet: */ int buttonIndex=byte-216; deviceButtonStates[buttonIndex]=true; /* Set the button state in the device manager: */ { Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); if(reportEvents) setButtonState(buttonIndex,true); } } else if(byte>=248&&byte<=250) { /* It's a button release packet: */ int buttonIndex=byte-248; deviceButtonStates[buttonIndex]=false; /* Set the button state in the device manager: */ { Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); if(reportEvents) setButtonState(buttonIndex,false); } } } }
void PCWand::stop(void) { /* Stop reporting events to the device manager: */ { Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); reportEvents=false; } }
PCWand::~PCWand(void) { /* Stop device thread (dedicated PC cannot be disabled): */ { Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); stopDeviceThread(); } }
void PCWand::start(void) { /* Set device manager's button and valuator values to current device values: */ { Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); for(int i=0; i<numButtons; ++i) setButtonState(i,deviceButtonStates[i]); for(int i=0; i<numValuators; ++i) setValuatorState(i,deviceValuatorStates[i]); /* Start reporting events to the device manager: */ reportEvents=true; } }
void RazerHydraDevice::start(void) { /* Set device manager's device states to current device values: */ Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); for(int i=0;i<7*2;++i) setButtonState(i,deviceButtonStates[i]); for(int i=0;i<3*2;++i) setValuatorState(i,deviceValuatorStates[i]); for(int i=0;i<2;++i) setTrackerState(i,deviceTrackerStates[i]); /* Start reporting events to the device manager: */ reportEvents=true; }
void RazerHydraDevice::deviceThreadMethod(void) { typedef PositionOrientation::Vector Vector; typedef PositionOrientation::Rotation Rotation; /* Reset first measurement flag: */ notFirstMeasurement=false; while(keepRunning) { /* Wait for the next update message: */ RazerHydra::SensorState sensorStates[2]; hydra->pollSensors(sensorStates); /* Update the device tracker state structures: */ { Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); timer.elapse(); for(int sensor=0;sensor<2;++sensor) { /* Copy the sensor's button and valuator states: */ for(int i=0;i<7;++i) deviceButtonStates[sensor*7+i]=sensorStates[sensor].buttonStates[i]; for(int i=0;i<3;++i) deviceValuatorStates[sensor*3+i]=sensorStates[sensor].valuatorStates[i]; /* Copy the sensor's position and orientation: */ Vector t=Vector(sensorStates[sensor].position); Rotation r=sensorStates[sensor].orientation; deviceTrackerStates[sensor].positionOrientation=PositionOrientation(t,r); /* Calculate linear and angular velocities: */ if(notFirstMeasurement) { /* Estimate velocities by dividing position/orientation differences by elapsed time since last measurement: */ double time=timer.getTime(); deviceTrackerStates[sensor].linearVelocity=(t-oldPositionOrientations[sensor].getTranslation())/TrackerState::LinearVelocity::Scalar(time); Rotation dR=r*Geometry::invert(oldPositionOrientations[sensor].getRotation()); deviceTrackerStates[sensor].angularVelocity=dR.getScaledAxis()/TrackerState::AngularVelocity::Scalar(time); } else { /* Force initial velocities to zero: */ deviceTrackerStates[sensor].linearVelocity=TrackerState::LinearVelocity::zero; deviceTrackerStates[sensor].angularVelocity=TrackerState::AngularVelocity::zero; notFirstMeasurement=true; } oldPositionOrientations[sensor]=deviceTrackerStates[sensor].positionOrientation; } /* Update device state in device manager: */ if(reportEvents) { for(int i=0;i<7*2;++i) setButtonState(i,deviceButtonStates[i]); for(int i=0;i<3*2;++i) setValuatorState(i,deviceValuatorStates[i]); for(int i=0;i<2;++i) setTrackerState(i,deviceTrackerStates[i]); } } } }
void RazerHydraDevice::stop(void) { /* Stop reporting events to the device manager: */ Threads::Mutex::Lock deviceValuesLock(deviceValuesMutex); reportEvents=false; }