Torque3D Documentation / _generateds / oculusVRSensorDevice.cpp

oculusVRSensorDevice.cpp

Engine/source/platform/input/oculusVR/oculusVRSensorDevice.cpp

More...

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