oculusVRSensorDevice.cpp
Engine/source/platform/input/oculusVR/oculusVRSensorDevice.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/input/oculusVR/oculusVRSensorDevice.h" 25#include "platform/input/oculusVR/oculusVRSensorData.h" 26#include "platform/input/oculusVR/oculusVRUtil.h" 27#include "platform/platformInput.h" 28#include "console/simBase.h" 29#include "console/engineAPI.h" 30#include "math/mAngAxis.h" 31#include "OVR_CAPI_0_8_0.h" 32 33U32 OculusVRSensorDevice::OVR_SENSORROT[OculusVRConstants::MaxSensors] = {0}; 34U32 OculusVRSensorDevice::OVR_SENSORROTANG[OculusVRConstants::MaxSensors] = {0}; 35U32 OculusVRSensorDevice::OVR_SENSORROTAXISX[OculusVRConstants::MaxSensors] = {0}; 36U32 OculusVRSensorDevice::OVR_SENSORROTAXISY[OculusVRConstants::MaxSensors] = {0}; 37U32 OculusVRSensorDevice::OVR_SENSORACCELERATION[OculusVRConstants::MaxSensors] = {0}; 38U32 OculusVRSensorDevice::OVR_SENSORANGVEL[OculusVRConstants::MaxSensors] = {0}; 39U32 OculusVRSensorDevice::OVR_SENSORMAGNETOMETER[OculusVRConstants::MaxSensors] = {0}; 40U32 OculusVRSensorDevice::OVR_SENSORPOSITION[OculusVRConstants::MaxSensors] = {0}; 41 42OculusVRSensorDevice::OculusVRSensorDevice() 43{ 44 mIsValid = false; 45 mDevice = NULL; 46 mCurrentTrackingCaps = 0; 47 mSupportedTrackingCaps = 0; 48 mPositionTrackingDisabled = false; 49 for(U32 i=0; i<2; ++i) 50 { 51 mDataBuffer[i] = new OculusVRSensorData(); 52 } 53 mPrevData = mDataBuffer[0]; 54} 55 56OculusVRSensorDevice::~OculusVRSensorDevice() 57{ 58 cleanUp(); 59 60 for(U32 i=0; i<2; ++i) 61 { 62 delete mDataBuffer[i]; 63 mDataBuffer[i] = NULL; 64 } 65 mPrevData = NULL; 66} 67 68void OculusVRSensorDevice::cleanUp() 69{ 70 mIsValid = false; 71 72 ovr_ConfigureTracking(mDevice, 0, 0); 73} 74 75void OculusVRSensorDevice::set(ovrHmd sensor, S32 actionCodeIndex) 76{ 77 mIsValid = false; 78 mDevice = sensor; 79 80 mSupportedTrackingCaps = ovr_GetTrackingCaps(sensor); 81 mCurrentTrackingCaps = ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position; 82 83 mCurrentTrackingCaps = mSupportedTrackingCaps & mCurrentTrackingCaps; 84 mYawCorrectionDisabled = !(mCurrentTrackingCaps & ovrTrackingCap_MagYawCorrection); 85 86 mPositionTrackingDisabled = !(mCurrentTrackingCaps & ovrTrackingCap_Position); 87 88 ovrHmdDesc desc = ovr_GetHmdDesc(sensor); 89 90 // DeviceInfo 91 mProductName = desc.ProductName; 92 mManufacturer = desc.Manufacturer; 93 mVersion = desc.Type; 94 95 // SensorInfo 96 mVendorId = desc.VendorId; 97 mProductId = desc.ProductId; 98 mSerialNumber = desc.SerialNumber; 99 100 mActionCodeIndex = actionCodeIndex; 101 102 if(mActionCodeIndex >= OculusVRConstants::MaxSensors) 103 { 104 // Cannot declare more sensors than we are able to handle 105 mIsValid = false; 106 } 107 else 108 { 109 mIsValid = true; 110 } 111 112 updateTrackingCaps(); 113} 114 115void OculusVRSensorDevice::buildCodeTable() 116{ 117 // Obtain all of the device codes 118 for(U32 i=0; i<OculusVRConstants::MaxSensors; ++i) 119 { 120 OVR_SENSORROT[i] = INPUTMGR->getNextDeviceCode(); 121 122 OVR_SENSORROTANG[i] = INPUTMGR->getNextDeviceCode(); 123 124 OVR_SENSORROTAXISX[i] = INPUTMGR->getNextDeviceCode(); 125 OVR_SENSORROTAXISY[i] = INPUTMGR->getNextDeviceCode(); 126 127 OVR_SENSORACCELERATION[i] = INPUTMGR->getNextDeviceCode(); 128 OVR_SENSORANGVEL[i] = INPUTMGR->getNextDeviceCode(); 129 OVR_SENSORMAGNETOMETER[i] = INPUTMGR->getNextDeviceCode(); 130 131 OVR_SENSORPOSITION[i] = INPUTMGR->getNextDeviceCode(); 132 } 133 134 // Build out the virtual map 135 char buffer[64]; 136 for(U32 i=0; i<OculusVRConstants::MaxSensors; ++i) 137 { 138 dSprintf(buffer, 64, "ovr_sensorrot%d", i); 139 INPUTMGR->addVirtualMap( buffer, SI_ROT, OVR_SENSORROT[i] ); 140 141 dSprintf(buffer, 64, "ovr_sensorrotang%d", i); 142 INPUTMGR->addVirtualMap( buffer, SI_POS, OVR_SENSORROTANG[i] ); 143 144 dSprintf(buffer, 64, "ovr_sensorrotaxisx%d", i); 145 INPUTMGR->addVirtualMap( buffer, SI_AXIS, OVR_SENSORROTAXISX[i] ); 146 dSprintf(buffer, 64, "ovr_sensorrotaxisy%d", i); 147 INPUTMGR->addVirtualMap( buffer, SI_AXIS, OVR_SENSORROTAXISY[i] ); 148 149 dSprintf(buffer, 64, "ovr_sensoracceleration%d", i); 150 INPUTMGR->addVirtualMap( buffer, SI_POS, OVR_SENSORACCELERATION[i] ); 151 152 dSprintf(buffer, 64, "ovr_sensorangvel%d", i); 153 INPUTMGR->addVirtualMap( buffer, SI_POS, OVR_SENSORANGVEL[i] ); 154 155 dSprintf(buffer, 64, "ovr_sensormagnetometer%d", i); 156 INPUTMGR->addVirtualMap( buffer, SI_POS, OVR_SENSORMAGNETOMETER[i] ); 157 158 dSprintf(buffer, 64, "ovr_sensorpos%d", i); 159 INPUTMGR->addVirtualMap( buffer, SI_POS, OVR_SENSORPOSITION[i] ); 160 } 161} 162 163//----------------------------------------------------------------------------- 164 165bool OculusVRSensorDevice::process(U32 deviceType, bool generateRotAsAngAxis, bool generateRotAsEuler, bool generateRotationAsAxisEvents, bool generatePositionEvents, F32 maxAxisRadius, bool generateRawSensor) 166{ 167 if(!mIsValid) 168 return false; 169 170 // Grab current state 171 ovrTrackingState ts = ovr_GetTrackingState(mDevice, ovr_GetTimeInSeconds(), ovrTrue); 172 mLastStatus = ts.StatusFlags; 173 174 // Store the current data from the sensor and compare with previous data 175 U32 diff; 176 OculusVRSensorData* currentBuffer = (mPrevData == mDataBuffer[0]) ? mDataBuffer[1] : mDataBuffer[0]; 177 currentBuffer->setData(ts, maxAxisRadius); 178 diff = mPrevData->compare(currentBuffer, generateRawSensor); 179 180 // Update the previous data pointer. We do this here in case someone calls our 181 // console functions during one of the input events below. 182 mPrevData = currentBuffer; 183 184 // Rotation event 185 if(diff & OculusVRSensorData::DIFF_ROT) 186 { 187 if(generateRotAsAngAxis) 188 { 189 AngAxisF axisAA(currentBuffer->mRotQuat); 190 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_ROT, OVR_SENSORROT[mActionCodeIndex], SI_MOVE, axisAA); 191 } 192 193 if(generateRotAsEuler) 194 { 195 // Convert angles to degrees 196 VectorF angles; 197 for(U32 i=0; i<3; ++i) 198 { 199 angles[i] = mRadToDeg(currentBuffer->mRotEuler[i]); 200 } 201 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORROTANG[mActionCodeIndex], SI_MOVE, angles); 202 } 203 } 204 205 // Rotation as axis event 206 if(generateRotationAsAxisEvents && diff & OculusVRSensorData::DIFF_ROTAXIS) 207 { 208 if(diff & OculusVRSensorData::DIFF_ROTAXISX) 209 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISX[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.x); 210 if(diff & OculusVRSensorData::DIFF_ROTAXISY) 211 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISY[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.y); 212 } 213 214 if (generatePositionEvents && diff & OculusVRSensorData::DIFF_POS) 215 { 216 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISX[mActionCodeIndex], SI_MOVE, currentBuffer->mPosition); 217 } 218 219 // Raw sensor event 220 if(generateRawSensor && diff & OculusVRSensorData::DIFF_RAW) 221 { 222 if(diff & OculusVRSensorData::DIFF_ACCEL) 223 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORACCELERATION[mActionCodeIndex], SI_MOVE, currentBuffer->mAcceleration); 224 225 if(diff & OculusVRSensorData::DIFF_ANGVEL) 226 { 227 // Convert angles to degrees 228 VectorF angles; 229 for(U32 i=0; i<3; ++i) 230 { 231 angles[i] = mRadToDeg(currentBuffer->mAngVelocity[i]); 232 } 233 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORANGVEL[mActionCodeIndex], SI_MOVE, angles); 234 } 235 236 if(diff & OculusVRSensorData::DIFF_MAG) 237 INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORMAGNETOMETER[mActionCodeIndex], SI_MOVE, currentBuffer->mMagnetometer); 238 } 239 240 if (diff & OculusVRSensorData::DIFF_STATUS) 241 { 242 if (Con::isFunction("onOculusStatusUpdate")) 243 { 244 Con::executef("onOculusStatusUpdate", ts.StatusFlags); 245 } 246 } 247 248 return true; 249} 250 251//----------------------------------------------------------------------------- 252 253void OculusVRSensorDevice::reset() 254{ 255 if(!mIsValid) 256 return; 257 258 ovr_RecenterPose(mDevice); 259} 260 261bool OculusVRSensorDevice::getYawCorrection() const 262{ 263 if(!mIsValid) 264 return false; 265 266 return !(mCurrentTrackingCaps & ovrTrackingCap_MagYawCorrection); 267} 268 269void OculusVRSensorDevice::setYawCorrection(bool state) 270{ 271 if(!mIsValid) 272 return; 273 274 if (state == !mYawCorrectionDisabled) 275 return; 276 277 // Don't allow if not capable 278 if(state && !(mSupportedTrackingCaps & ovrTrackingCap_MagYawCorrection)) 279 return; 280 281 mYawCorrectionDisabled = !state; 282 updateTrackingCaps(); 283} 284 285void OculusVRSensorDevice::setPositionTracking(bool state) 286{ 287 if(!mIsValid) 288 return; 289 290 if (state == !mPositionTrackingDisabled) 291 return; 292 293 if(state && !(mSupportedTrackingCaps & ovrTrackingCap_Position)) 294 return; 295 296 mPositionTrackingDisabled = !state; 297 updateTrackingCaps(); 298} 299 300bool OculusVRSensorDevice::getMagnetometerCalibrationAvailable() const 301{ 302 if(!mIsValid) 303 return false; 304 305 return (mSupportedTrackingCaps & ovrTrackingCap_MagYawCorrection) != 0; 306} 307 308bool OculusVRSensorDevice::getOrientationTrackingAvailable() const 309{ 310 if(!mIsValid) 311 return false; 312 313 return (mSupportedTrackingCaps & ovrTrackingCap_Orientation) != 0; 314} 315 316bool OculusVRSensorDevice::getPositionTrackingAvailable() const 317{ 318 if(!mIsValid) 319 return false; 320 321 return (mSupportedTrackingCaps & ovrTrackingCap_Position) != 0; 322} 323 324//----------------------------------------------------------------------------- 325 326EulerF OculusVRSensorDevice::getEulerRotation() 327{ 328 if(!mIsValid) 329 return Point3F::Zero; 330 331 ovrTrackingState ts = ovr_GetTrackingState(mDevice, ovr_GetTimeInSeconds(), ovrTrue); 332 OVR::Quatf orientation = ts.HeadPose.ThePose.Orientation; 333 334 // Sensor rotation in Euler format 335 EulerF rot; 336 OculusVRUtil::convertRotation(orientation, rot); 337 338 return rot; 339} 340 341EulerF OculusVRSensorDevice::getRawEulerRotation() 342{ 343 if(!mIsValid) 344 return Point3F::Zero; 345 346 ovrTrackingState ts = ovr_GetTrackingState(mDevice, ovr_GetTimeInSeconds(), ovrTrue); 347 OVR::Quatf orientation = ts.HeadPose.ThePose.Orientation; 348 349 // Sensor rotation in Euler format 350 EulerF rot; 351 OculusVRUtil::convertRotation(orientation, rot); 352 return rot; 353} 354 355VectorF OculusVRSensorDevice::getAcceleration() 356{ 357 if(!mIsValid) 358 return VectorF::Zero; 359 360 ovrTrackingState ts = ovr_GetTrackingState(mDevice, ovr_GetTimeInSeconds(), ovrTrue); 361 OVR::Vector3f a = ts.HeadPose.LinearAcceleration; 362 363 // Sensor acceleration in VectorF format 364 VectorF acceleration; 365 OculusVRUtil::convertAcceleration(a, acceleration); 366 367 return acceleration; 368} 369 370EulerF OculusVRSensorDevice::getAngularVelocity() 371{ 372 if(!mIsValid) 373 return EulerF::Zero; 374 375 ovrTrackingState ts = ovr_GetTrackingState(mDevice, ovr_GetTimeInSeconds(), ovrTrue); 376 OVR::Vector3f v = ts.HeadPose.AngularVelocity; 377 378 // Sensor angular velocity in EulerF format 379 EulerF vel; 380 OculusVRUtil::convertAngularVelocity(v, vel); 381 382 return vel; 383} 384 385Point3F OculusVRSensorDevice::getPosition() 386{ 387 if(!mIsValid) 388 return Point3F(); 389 390 ovrTrackingState ts = ovr_GetTrackingState(mDevice, ovr_GetTimeInSeconds(), ovrTrue); 391 OVR::Vector3f v = ts.HeadPose.ThePose.Position; 392 return Point3F(-v.x, v.z, -v.y); 393} 394 395void OculusVRSensorDevice::updateTrackingCaps() 396{ 397 if (!mIsValid) 398 return; 399 400 // Set based on current vars 401 mCurrentTrackingCaps = ovrTrackingCap_Orientation; 402 403 if (!mYawCorrectionDisabled) 404 mCurrentTrackingCaps |= ovrTrackingCap_MagYawCorrection; 405 if (!mPositionTrackingDisabled) 406 mCurrentTrackingCaps |= ovrTrackingCap_Position; 407 408 ovr_ConfigureTracking(mDevice, mCurrentTrackingCaps, 0); 409} 410