Source: addons/gyroscope.js

  1. import register from "../util/register.js";
  2. import m_cam_fact from "../extern/camera.js";
  3. import m_ctl_fact from "../extern/controls.js";
  4. import m_scenes_fact from "../extern/scenes.js";
  5. import m_trans_fact from "../extern/transform.js";
  6. import m_util_fact from "../extern/util.js";
  7. import * as m_vec3 from "../libs/gl_matrix/vec3.js";
  8. /**
  9. * Gyroscope actions add-on.
  10. * Provides support for gyroscope on mobile devices.
  11. * @see http://www.w3.org/TR/orientation-event/
  12. * @module gyroscope
  13. */
  14. function Gyroscope(ns, exports) {
  15. var m_cam = m_cam_fact(ns);
  16. var m_ctl = m_ctl_fact(ns);
  17. var m_scenes = m_scenes_fact(ns);
  18. var m_trans = m_trans_fact(ns);
  19. var m_util = m_util_fact(ns);
  20. var _begin_angles = new Float32Array(3);
  21. var _curr_angles = new Float32Array(3);
  22. var _vec3_tmp = m_vec3.create();
  23. var VERTICAL_BETA_ANGLE_THRESHOLD_UP = m_util.deg_to_rad(110);
  24. var VERTICAL_BETA_ANGLE_THRESHOLD_DOWN = m_util.deg_to_rad(70);
  25. var VERTICAL_GAMMA_ANGLE_THRESHOLD_UP = m_util.deg_to_rad(70);
  26. var VERTICAL_GAMMA_ANGLE_THRESHOLD_DOWN = - m_util.deg_to_rad(70);
  27. /**
  28. * Enable camera rotation according to orientation of mobile device.
  29. * @method module:gyroscope.enable_camera_rotation
  30. */
  31. exports.enable_camera_rotation = function() {
  32. var cam_obj = m_scenes.get_active_camera();
  33. create_camera_rotation_sensors(cam_obj);
  34. }
  35. function create_camera_rotation_sensors(obj) {
  36. var g_a_sensor = m_ctl.create_gyro_angles_sensor();
  37. var g_q_sensor = m_ctl.create_gyro_quat_sensor();
  38. var save_angles = true;
  39. var cam_rotate_cb = function(obj, id, pulse) {
  40. if (pulse > 0) {
  41. if (m_cam.is_eye_camera(obj)) {
  42. var hmd_quat = m_ctl.get_sensor_payload(obj, id, 1);
  43. var up_axis = m_vec3.transformQuat(m_util.AXIS_MY, hmd_quat, _vec3_tmp);
  44. m_cam.set_vertical_axis(obj, up_axis);
  45. m_trans.set_rotation_v(obj, hmd_quat);
  46. } else {
  47. _curr_angles = m_ctl.get_sensor_payload(obj, id, 0);
  48. if (save_angles) {
  49. _begin_angles[0] = _curr_angles[0];
  50. _begin_angles[1] = _curr_angles[1];
  51. _begin_angles[2] = _curr_angles[2];
  52. save_angles = false;
  53. }
  54. var delta_beta = 0;
  55. var delta_gamma = 0;
  56. if (window.orientation == 0) {
  57. delta_beta = (_curr_angles[1] - _begin_angles[1]);
  58. delta_gamma = (_curr_angles[0] - _begin_angles[0]);
  59. if (_curr_angles[1] > VERTICAL_BETA_ANGLE_THRESHOLD_DOWN &&
  60. _curr_angles[1] < VERTICAL_BETA_ANGLE_THRESHOLD_UP)
  61. delta_gamma = 0;
  62. }
  63. if (window.orientation == 180) {
  64. delta_beta = (_curr_angles[1] - _begin_angles[1]);
  65. if (_curr_angles[1] < 0)
  66. delta_beta = -delta_beta;
  67. delta_gamma = (_begin_angles[0] - _curr_angles[0]);
  68. if (delta_beta > Math.PI / 2 || delta_beta < - Math.PI / 2)
  69. delta_beta = 0;
  70. if (_curr_angles[1] > - VERTICAL_BETA_ANGLE_THRESHOLD_UP &&
  71. _curr_angles[1] < - VERTICAL_BETA_ANGLE_THRESHOLD_DOWN)
  72. delta_gamma = 0;
  73. }
  74. if (window.orientation == -90) {
  75. delta_beta = (_curr_angles[0] - _begin_angles[0]);
  76. if (delta_beta > Math.PI / 2 || delta_beta < - Math.PI / 2)
  77. delta_beta = 0;
  78. delta_gamma = (_begin_angles[1] - _curr_angles[1]);
  79. if (_curr_angles[0] > VERTICAL_GAMMA_ANGLE_THRESHOLD_UP ||
  80. _curr_angles[0] < VERTICAL_GAMMA_ANGLE_THRESHOLD_DOWN)
  81. delta_gamma = 0;
  82. }
  83. if (window.orientation == 90) {
  84. delta_beta = (_begin_angles[0] - _curr_angles[0]);
  85. if (delta_beta > Math.PI / 2 || delta_beta < - Math.PI / 2)
  86. delta_beta = 0;
  87. delta_gamma = (_curr_angles[1] - _begin_angles[1]);
  88. if (_curr_angles[0] > VERTICAL_GAMMA_ANGLE_THRESHOLD_UP ||
  89. _curr_angles[0] < VERTICAL_GAMMA_ANGLE_THRESHOLD_DOWN)
  90. delta_gamma = 0;
  91. }
  92. m_cam.rotate_camera(obj, delta_gamma, delta_beta);
  93. _begin_angles[0] = _curr_angles[0];
  94. _begin_angles[1] = _curr_angles[1];
  95. _begin_angles[2] = _curr_angles[2];
  96. }
  97. }
  98. }
  99. m_ctl.create_sensor_manifold(obj, "CAMERA_ROTATE_GYRO",
  100. m_ctl.CT_CONTINUOUS, [g_a_sensor, g_q_sensor], null,
  101. cam_rotate_cb);
  102. }
  103. /**
  104. * Disable camera rotation according to orientation of mobile device.
  105. * @method module:gyroscope.disable_camera_rotation
  106. */
  107. exports.disable_camera_rotation = function() {
  108. var cam_obj = m_scenes.get_active_camera();
  109. m_ctl.remove_sensor_manifold(cam_obj, "CAMERA_ROTATE_GYRO");
  110. }
  111. };
  112. var gyroscope_factory = register("gyroscope", Gyroscope);
  113. export default gyroscope_factory;