NrealLightControllerStateParser.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal
  10. {
  11. using System;
  12. using UnityEngine;
  13. /// <summary>
  14. /// The class parses the raw states of Nreal Controller to usable states by invoking
  15. /// parsing method every frame. </summary>
  16. public class NrealLightControllerStateParser : IControllerStateParser
  17. {
  18. /// <summary> Values that represent touch area enums. </summary>
  19. private enum TouchAreaEnum
  20. {
  21. /// <summary> An enum constant representing the none option. </summary>
  22. None,
  23. /// <summary> An enum constant representing the center option. </summary>
  24. Center,
  25. /// <summary> An enum constant representing the up option. </summary>
  26. Up,
  27. /// <summary> An enum constant representing the down option. </summary>
  28. Down,
  29. /// <summary> An enum constant representing the left option. </summary>
  30. Left,
  31. /// <summary> An enum constant representing the right option. </summary>
  32. Right
  33. }
  34. /// <summary> The buttons down. </summary>
  35. private bool[] _buttons_down = new bool[3];
  36. /// <summary> The buttons up. </summary>
  37. private bool[] _buttons_up = new bool[3];
  38. /// <summary> The buttons. </summary>
  39. private bool[] _buttons = new bool[3];
  40. /// <summary> The down. </summary>
  41. private bool[] _down = new bool[3];
  42. /// <summary> The touch. </summary>
  43. private Vector2 _touch;
  44. /// <summary> The current touch area. </summary>
  45. private TouchAreaEnum _currentTouchArea = TouchAreaEnum.None;
  46. /// <summary> True to touch status. </summary>
  47. private bool _touch_status;
  48. /// <summary> True to physical button. </summary>
  49. private bool _physical_button;
  50. /// <summary> True to physical button down. </summary>
  51. private bool _physical_button_down;
  52. /// <summary> The current down button. </summary>
  53. private int _current_down_btn = -1;
  54. /// <summary> The second parameters sqrt. </summary>
  55. private const float Params_Sqrt_2 = 1.414f;
  56. /// <summary> Length of the center half side. </summary>
  57. private const float CenterHalfSideLength = 0.9f / Params_Sqrt_2;
  58. /// <summary> Length of the ok half side. </summary>
  59. private const float OKHalfSideLength = 0.9f / Params_Sqrt_2 * 0.5f;
  60. /// <summary> The precision. </summary>
  61. private const float PRECISION = 0.000001f;
  62. /// <summary> Parser controller state. </summary>
  63. /// <param name="state"> The state.</param>
  64. public void ParserControllerState(ControllerState state)
  65. {
  66. try
  67. {
  68. _touch_status = (Mathf.Abs(state.touchPos.x) > PRECISION || Mathf.Abs(state.touchPos.y) > PRECISION);
  69. if (!_touch_status)
  70. {
  71. _touch.x = 0f;
  72. _touch.y = 0f;
  73. }
  74. else
  75. {
  76. _touch.x = state.touchPos.x;
  77. _touch.y = state.touchPos.y;
  78. }
  79. UpdateCurrentTouchArea();
  80. lock (_buttons)
  81. {
  82. lock (_down)
  83. {
  84. for (int i = 0; i < _buttons.Length; ++i)
  85. {
  86. _down[i] = _buttons[i];
  87. }
  88. }
  89. _physical_button_down = _physical_button;
  90. _physical_button = state.GetButton(ControllerButton.TRIGGER);
  91. if (_current_down_btn != -1)
  92. {
  93. _buttons[_current_down_btn] = _physical_button;
  94. if (!_buttons[_current_down_btn])
  95. _current_down_btn = -1;
  96. }
  97. else
  98. {
  99. _buttons[0] = false; //Trigger
  100. _buttons[1] = false; //App
  101. _buttons[2] = false; //Home
  102. bool _is_down = !_physical_button_down & _physical_button;
  103. if (_currentTouchArea == TouchAreaEnum.Center)
  104. _buttons[0] = _physical_button && _is_down;
  105. else if (_currentTouchArea == TouchAreaEnum.Up)
  106. _buttons[1] = _physical_button && _is_down;
  107. else if (_currentTouchArea == TouchAreaEnum.Down)
  108. _buttons[2] = _physical_button && _is_down;
  109. _current_down_btn = -1;
  110. for (int i = 0; i < 3; i++)
  111. {
  112. if (_buttons[i])
  113. {
  114. _current_down_btn = i;
  115. break;
  116. }
  117. }
  118. }
  119. lock (_buttons_up)
  120. {
  121. lock (_buttons_down)
  122. {
  123. for (int i = 0; i < _buttons.Length; ++i)
  124. {
  125. _buttons_up[i] = (_down[i] & !_buttons[i]);
  126. _buttons_down[i] = (!_down[i] & _buttons[i]);
  127. }
  128. }
  129. }
  130. }
  131. }
  132. catch (Exception e)
  133. {
  134. NRDebugger.Error("Controller Data Error :" + e.ToString());
  135. }
  136. state.isTouching = _touch_status;
  137. state.touchPos = _touch;
  138. state.buttonsState =
  139. (_buttons[0] ? ControllerButton.TRIGGER : 0)
  140. | (_buttons[1] ? ControllerButton.APP : 0)
  141. | (_buttons[2] ? ControllerButton.HOME : 0);
  142. state.buttonsDown =
  143. (_buttons_down[0] ? ControllerButton.TRIGGER : 0)
  144. | (_buttons_down[1] ? ControllerButton.APP : 0)
  145. | (_buttons_down[2] ? ControllerButton.HOME : 0);
  146. state.buttonsUp =
  147. (_buttons_up[0] ? ControllerButton.TRIGGER : 0)
  148. | (_buttons_up[1] ? ControllerButton.APP : 0)
  149. | (_buttons_up[2] ? ControllerButton.HOME : 0);
  150. }
  151. /// <summary> Updates the current touch area. </summary>
  152. private void UpdateCurrentTouchArea()
  153. {
  154. _currentTouchArea = TouchAreaEnum.None;
  155. if (!_touch_status)
  156. return;
  157. if (_touch.y < -CenterHalfSideLength * 0.9f)
  158. _currentTouchArea = TouchAreaEnum.Down;
  159. else if (_touch.y > CenterHalfSideLength * 0.8f)
  160. _currentTouchArea = TouchAreaEnum.Up;
  161. else
  162. _currentTouchArea = TouchAreaEnum.Center;
  163. }
  164. }
  165. }