AndroidMotionManager.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "AndroidMotionManager.h"
  23. #include "platformAndroid.h"
  24. #include "string/stringBuffer.h"
  25. #include "sim/simBase.h"
  26. #include "game/gameInterface.h"
  27. extern AndroidPlatState platState;
  28. static const double kFilterConst = 0.1;
  29. static const double kUpdateInterval = 0.2;
  30. //TODO: convert objc to c++
  31. /*
  32. @implementation AndroidMotionManager
  33. @synthesize referenceAttitude;
  34. @synthesize accelerometerEnabled;
  35. @synthesize gyroscopeEnabled;
  36. - (id)init
  37. {
  38. if (!(self = [super init])) return nil;
  39. if(self != NULL)
  40. {
  41. accelerometerEnabled = NO;
  42. gyroscopeEnabled = NO;
  43. motionManager = [[CMMotionManager alloc] init];
  44. if(motionManager.deviceMotionAvailable)
  45. {
  46. [motionManager setDeviceMotionUpdateInterval:kUpdateInterval];
  47. }
  48. else
  49. {
  50. [motionManager setAccelerometerUpdateInterval:kUpdateInterval];
  51. }
  52. }
  53. else
  54. {
  55. Con::printf("Could not initialized AndroidMotionManager!");
  56. return 0;
  57. }
  58. return self;
  59. }
  60. double accelAxes[6];
  61. - (void)enableAccelerometer
  62. {
  63. accelerometerEnabled = YES;
  64. }
  65. - (void)disableAccelerometer
  66. {
  67. accelerometerEnabled = NO;
  68. }
  69. - (bool)isAccelerometerActive
  70. {
  71. return motionManager.accelerometerActive;
  72. }
  73. - (bool)enableGyroscope
  74. {
  75. if(motionManager.gyroAvailable)
  76. gyroscopeEnabled = YES;
  77. else
  78. {
  79. Con::errorf("Gyroscope not supported on this device");
  80. return false;
  81. }
  82. return true;
  83. }
  84. - (bool)disableGyroscope
  85. {
  86. if(motionManager.gyroAvailable)
  87. gyroscopeEnabled = NO;
  88. else
  89. {
  90. Con::errorf("Gyroscope not supported on this device");
  91. return false;
  92. }
  93. return true;
  94. }
  95. - (bool)isGyroAvailable
  96. {
  97. return motionManager.gyroAvailable;
  98. }
  99. - (bool)isGyroActive
  100. {
  101. return motionManager.gyroActive;
  102. }
  103. static double filteredAccel[3] = {0, 0, 0};
  104. void (^accelerometerHandler)(CMAccelerometerData*, NSError*) = ^(CMAccelerometerData *accelData, NSError *)
  105. {
  106. if(gMotionManager.accelerometerEnabled)
  107. {
  108. U32 accelAxes[6] = { SI_ACCELX, SI_ACCELY, SI_ACCELZ, SI_GRAVX, SI_GRAVY, SI_GRAVZ };
  109. double userAcc[6];
  110. if(platState.portrait)
  111. {
  112. filteredAccel[0] = (accelData.acceleration.x * kFilterConst) + (filteredAccel[0] * (1.0 - kFilterConst));
  113. filteredAccel[1] = (accelData.acceleration.y * kFilterConst) + (filteredAccel[1] * (1.0 - kFilterConst));
  114. filteredAccel[2] = (accelData.acceleration.z * kFilterConst) + (filteredAccel[2] * (1.0 - kFilterConst));
  115. userAcc[0] = accelData.acceleration.x - filteredAccel[0];
  116. userAcc[1] = accelData.acceleration.y - filteredAccel[1];
  117. userAcc[2] = accelData.acceleration.z - filteredAccel[2];
  118. // Assign the non-filtered data to gravity
  119. userAcc[3] = accelData.acceleration.x;
  120. userAcc[4] = accelData.acceleration.y;
  121. userAcc[5] = accelData.acceleration.z;
  122. }
  123. else
  124. {
  125. filteredAccel[0] = (accelData.acceleration.y * kFilterConst) + (filteredAccel[0] * (1.0 - kFilterConst));
  126. filteredAccel[1] = (accelData.acceleration.x * kFilterConst) + (filteredAccel[1] * (1.0 - kFilterConst));
  127. filteredAccel[2] = (accelData.acceleration.z * kFilterConst) + (filteredAccel[2] * (1.0 - kFilterConst));
  128. userAcc[0] = accelData.acceleration.y - filteredAccel[0];
  129. userAcc[1] = accelData.acceleration.x - filteredAccel[1];
  130. userAcc[2] = accelData.acceleration.z - filteredAccel[2];
  131. // Assign the non-filtered data to gravity
  132. userAcc[3] = accelData.acceleration.y;
  133. userAcc[4] = accelData.acceleration.x;
  134. userAcc[5] = accelData.acceleration.z;
  135. }
  136. for( int i = 0; i < 6; i++)
  137. {
  138. InputEvent event;
  139. event.deviceInst = 0;
  140. event.fValue = userAcc[i];
  141. event.deviceType = AccelerometerDeviceType;
  142. event.objType = accelAxes[i];
  143. event.objInst = i;
  144. event.action = SI_MOTION;
  145. event.modifier = 0;
  146. Game->postEvent(event);
  147. }
  148. }
  149. };
  150. void (^motionHandler)(CMDeviceMotion*, NSError*) = ^(CMDeviceMotion *motionData, NSError *error)
  151. {
  152. if(gMotionManager.referenceAttitude == NULL)
  153. [gMotionManager resetDeviceMotionReference];
  154. CMAttitude* currentAttitude = motionData.attitude;
  155. [currentAttitude multiplyByInverseOfAttitude:gMotionManager.referenceAttitude];
  156. if(gMotionManager.accelerometerEnabled)
  157. {
  158. U32 accelAxes[6] = { SI_ACCELX, SI_ACCELY, SI_ACCELZ, SI_GRAVX, SI_GRAVY, SI_GRAVZ };
  159. double userAcc[6];
  160. if(platState.portrait)
  161. {
  162. userAcc[0] = motionData.userAcceleration.x;
  163. userAcc[1] = motionData.userAcceleration.y;
  164. userAcc[2] = motionData.userAcceleration.z;
  165. userAcc[3] = motionData.gravity.x;
  166. userAcc[4] = motionData.gravity.y;
  167. userAcc[5] = motionData.gravity.z;
  168. }
  169. else
  170. {
  171. userAcc[0] = motionData.userAcceleration.y;
  172. userAcc[1] = motionData.userAcceleration.x;
  173. userAcc[2] = motionData.userAcceleration.z;
  174. userAcc[3] = motionData.gravity.y;
  175. userAcc[4] = motionData.gravity.x;
  176. userAcc[5] = motionData.gravity.z;
  177. }
  178. for( int i = 0; i < 6; i++)
  179. {
  180. InputEvent event;
  181. event.deviceInst = 0;
  182. event.fValue = userAcc[i];
  183. event.deviceType = AccelerometerDeviceType;
  184. event.objType = accelAxes[i];
  185. event.objInst = i;
  186. event.action = SI_MOTION;
  187. event.modifier = 0;
  188. Game->postEvent(event);
  189. }
  190. }
  191. if(gMotionManager.gyroscopeEnabled)
  192. {
  193. double gyroData[6] = { currentAttitude.pitch,
  194. currentAttitude.yaw,
  195. currentAttitude.roll,
  196. motionData.rotationRate.x,
  197. motionData.rotationRate.y,
  198. motionData.rotationRate.z };
  199. U32 gyroAxes[6] = { SI_PITCH, SI_YAW, SI_ROLL, SI_GYROX, SI_GYROY, SI_GYROZ };
  200. for( int i = 0; i < 6; i++)
  201. {
  202. InputEvent event;
  203. event.deviceInst = 0;
  204. event.fValue = gyroData[i];
  205. event.deviceType = GyroscopeDeviceType;
  206. event.objType = gyroAxes[i];
  207. event.objInst = i;
  208. event.action = SI_MOTION;
  209. event.modifier = 0;
  210. Game->postEvent(event);
  211. }
  212. }
  213. };
  214. - (bool)startDeviceMotion
  215. {
  216. if(motionManager.deviceMotionAvailable)
  217. {
  218. if(referenceAttitude == NULL)
  219. referenceAttitude = motionManager.deviceMotion.attitude;
  220. [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:motionHandler];
  221. }
  222. else
  223. {
  224. [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:accelerometerHandler];
  225. }
  226. return true;
  227. }
  228. - (bool)stopDeviceMotion
  229. {
  230. if(motionManager.deviceMotionAvailable)
  231. [motionManager stopDeviceMotionUpdates];
  232. else
  233. {
  234. [motionManager stopAccelerometerUpdates];
  235. }
  236. return true;
  237. }
  238. - (bool)resetDeviceMotionReference
  239. {
  240. if(motionManager.deviceMotionAvailable)
  241. {
  242. referenceAttitude = motionManager.deviceMotion.attitude;
  243. return true;
  244. }
  245. Con::errorf("Device Motion not supported on this device (check OS)");
  246. return false;
  247. }
  248. - (bool)isDeviceMotionAvailable
  249. {
  250. return motionManager.deviceMotionAvailable;
  251. }
  252. - (bool)isDeviceMotionActive
  253. {
  254. return motionManager.deviceMotionActive;
  255. }
  256. @end
  257. */
  258. ConsoleFunction(initMotionManager, void, 1, 1, "() Initialize the AndroidMotionManager")
  259. {
  260. //TODO: convert objc
  261. /* if(gMotionManager != NULL)
  262. {
  263. Con::printf("Motion Manager already initialized");
  264. }
  265. else
  266. gMotionManager = [[AndroidMotionManager alloc] init];
  267. */
  268. }
  269. ConsoleFunction(enableAccelerometer, void, 1, 1, "() Allow accelerometer tracking during device motion updates")
  270. {
  271. //TODO: convert objc
  272. /*if(gMotionManager == NULL)
  273. gMotionManager = [[AndroidMotionManager alloc] init];
  274. gMotionManager.accelerometerEnabled = YES;
  275. [gMotionManager startDeviceMotion];
  276. */
  277. }
  278. ConsoleFunction(disableAccelerometer, void, 1, 1, "() Stop accelerometer tracking")
  279. {
  280. //TODO: convert objc
  281. /*if(gMotionManager != NULL)
  282. gMotionManager.accelerometerEnabled = NO;
  283. else
  284. {
  285. Con::warnf("Motion Manager was not initialized. Initializing now");
  286. gMotionManager = [[AndroidMotionManager alloc] init];
  287. }*/
  288. }
  289. ConsoleFunction(isAccelerometerActive, bool, 1, 1, "() Check to see if Accelerometer is being polled\n"
  290. "@return True if accelerometer is on, false otherwise")
  291. {
  292. //TODO: convert objc
  293. /*
  294. if(gMotionManager != NULL)
  295. return [gMotionManager isAccelerometerActive];
  296. else
  297. {
  298. Con::warnf("Motion Manager was not initialized. Initializing now");
  299. gMotionManager = [[AndroidMotionManager alloc] init];
  300. return [gMotionManager isAccelerometerActive];
  301. }
  302. */
  303. return false;
  304. }
  305. ConsoleFunction(isGyroAvailable, bool, 1, 1, "() Check to see if this Android device has a gyroscope\n"
  306. "@return True if gyro is on the device, false otherwise")
  307. {
  308. //TODO: convert objc
  309. /*
  310. if(gMotionManager != NULL)
  311. return [gMotionManager isGyroAvailable];
  312. else
  313. {
  314. Con::warnf("Motion Manager was not initialized. Initializing now");
  315. gMotionManager = [[AndroidMotionManager alloc] init];
  316. return [gMotionManager isGyroAvailable];
  317. }
  318. */
  319. return false;
  320. }
  321. ConsoleFunction(isGyroActive, bool, 1, 1, "() Check to see if this Android device has a gyroscope\n"
  322. "@return True if gyro is on the device, false otherwise")
  323. {
  324. //TODO: convert objc
  325. /*
  326. if(gMotionManager != NULL)
  327. return [gMotionManager isGyroActive];
  328. else
  329. {
  330. Con::warnf("Motion Manager was not initialized. Initializing now");
  331. gMotionManager = [[AndroidMotionManager alloc] init];
  332. return [gMotionManager isGyroActive];
  333. }
  334. */
  335. return false;
  336. }
  337. ConsoleFunction(enableGyroscope, void, 1, 1, "() Start the gyroscope tracking\n"
  338. "@return True if gyroscope is supported, false otherwise")
  339. {
  340. //TODO: convert objc
  341. /*
  342. if(gMotionManager != NULL)
  343. gMotionManager.gyroscopeEnabled = YES;
  344. else
  345. {
  346. Con::warnf("Motion Manager was not initialized. Initializing now");
  347. gMotionManager = [[AndroidMotionManager alloc] init];
  348. gMotionManager.gyroscopeEnabled = YES;
  349. [gMotionManager startDeviceMotion];
  350. }
  351. */
  352. }
  353. ConsoleFunction(stopGyroscope, void, 1, 1, "() Stop gyroscope tracking\n"
  354. "@return True if gyroscope is supported, false otherwise")
  355. {
  356. //TODO: convert objc
  357. /*if(gMotionManager != NULL)
  358. gMotionManager.gyroscopeEnabled = NO;
  359. else
  360. {
  361. Con::warnf("Motion Manager was not initialized. Initializing now");
  362. gMotionManager = [[AndroidMotionManager alloc] init];
  363. }
  364. */
  365. }
  366. ConsoleFunction(isDeviceMotionAvailable, bool, 1, 1, "() Check to see if this Android device supports advanced device motion (requires gyroscope\n"
  367. "@return True if Device Motion is supported, false otherwise")
  368. {
  369. //TODO: convert objc
  370. /*if(gMotionManager != NULL)
  371. return [gMotionManager isDeviceMotionAvailable];
  372. else
  373. {
  374. Con::warnf("Motion Manager was not initialized. Initializing now");
  375. gMotionManager = [[AndroidMotionManager alloc] init];
  376. return [gMotionManager isDeviceMotionAvailable];
  377. }
  378. */
  379. return false;
  380. }
  381. ConsoleFunction(isDeviceMotionActive, bool, 1, 1, "() Check to see if the device motion is running\n"
  382. "@return True if device motion is being tracked, false otherwise")
  383. {
  384. //TODO: convert objc
  385. /*
  386. if(gMotionManager != NULL)
  387. return [gMotionManager isDeviceMotionActive];
  388. Con::warnf("Motion Manager was not initialized. Initializing now");
  389. gMotionManager = [[AndroidMotionManager alloc] init];
  390. return [gMotionManager isDeviceMotionActive];
  391. */
  392. return false;
  393. }
  394. ConsoleFunction(startDeviceMotion, bool, 1, 1, "() Start Device motion tracking\n"
  395. "@return True if device motion is supported, false otherwise")
  396. {
  397. //TODO: convert objc
  398. /*
  399. if(gMotionManager != NULL)
  400. return [gMotionManager startDeviceMotion];
  401. else
  402. {
  403. Con::warnf("Motion Manager was not initialized. Initializing now");
  404. gMotionManager = [[AndroidMotionManager alloc] init];
  405. return [gMotionManager startDeviceMotion];
  406. }
  407. */
  408. return false;
  409. }
  410. ConsoleFunction(stopDeviceMotion, bool, 1, 1, "() Stop Device Motion tracking\n"
  411. "@return True if device motion is supported, false otherwise")
  412. {
  413. //TODO: convert objc
  414. /*
  415. if(gMotionManager != NULL)
  416. return [gMotionManager stopDeviceMotion];
  417. else
  418. {
  419. Con::warnf("Motion Manager was not initialized. Initializing now");
  420. gMotionManager = [[AndroidMotionManager alloc] init];
  421. return [gMotionManager stopDeviceMotion];
  422. }
  423. */
  424. return false;
  425. }