2021년 4학년 1학기 기업연계프로젝트2 컴퓨터소프트웨어공학과 <원광투어팀> 팀장 : 송유진 팀원 : 김나영, 이경희, 한유진
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

859 lines
37 KiB

5 years ago
  1. //========= Copyright 2016-2020, HTC Corporation. All rights reserved. ===========
  2. using HTC.UnityPlugin.Vive;
  3. using HTC.UnityPlugin.Utility;
  4. using UnityEngine;
  5. using System;
  6. #if UNITY_2017_2_OR_NEWER
  7. using UnityEngine.XR;
  8. #else
  9. using XRSettings = UnityEngine.VR.VRSettings;
  10. using XRDevice = UnityEngine.VR.VRDevice;
  11. #endif
  12. namespace HTC.UnityPlugin.VRModuleManagement
  13. {
  14. public partial class VRModule : SingletonBehaviour<VRModule>
  15. {
  16. public static readonly bool isSimulatorSupported =
  17. #if VIU_SIUMULATOR_SUPPORT
  18. true;
  19. #else
  20. false;
  21. #endif
  22. }
  23. public interface ISimulatorVRModule
  24. {
  25. event Action onActivated;
  26. event Action onDeactivated;
  27. event SimulatorVRModule.UpdateDeviceStateHandler onUpdateDeviceState;
  28. }
  29. public sealed class SimulatorVRModule : VRModule.ModuleBase, ISimulatorVRModule
  30. {
  31. public delegate void UpdateDeviceStateHandler(IVRModuleDeviceState[] prevState, IVRModuleDeviceStateRW[] currState);
  32. public const uint SIMULATOR_MAX_DEVICE_COUNT = 16u;
  33. private const uint RIGHT_INDEX = 1;
  34. private const uint LEFT_INDEX = 2;
  35. private static readonly RigidPose s_initHmdPose = new RigidPose(new Vector3(0f, 1.75f, 0f), Quaternion.identity);
  36. private static RigidPose s_offsetLeftController = RigidPose.identity;
  37. private static RigidPose s_offsetRightController = RigidPose.identity;
  38. private static RigidPose s_offsetTracker = RigidPose.identity;
  39. private bool m_prevXREnabled;
  40. private bool m_resetDevices;
  41. private IMGUIHandle m_guiHandle;
  42. private IVRModuleDeviceState[] m_prevStates;
  43. private IVRModuleDeviceStateRW[] m_currStates;
  44. public event Action onActivated;
  45. public event Action onDeactivated;
  46. public event UpdateDeviceStateHandler onUpdateDeviceState;
  47. public override int moduleOrder { get { return (int)DefaultModuleOrder.Simulator; } }
  48. public override int moduleIndex { get { return (int)VRModuleSelectEnum.Simulator; } }
  49. public uint selectedDeviceIndex { get; private set; }
  50. public bool hasControlFocus { get; private set; }
  51. public override bool ShouldActiveModule() { return VIUSettings.activateSimulatorModule; }
  52. public override void OnActivated()
  53. {
  54. if (m_prevXREnabled = XRSettings.enabled)
  55. {
  56. XRSettings.enabled = false;
  57. }
  58. m_resetDevices = true;
  59. hasControlFocus = true;
  60. selectedDeviceIndex = VRModule.INVALID_DEVICE_INDEX;
  61. // Simulator instructions GUI
  62. m_guiHandle = VRModule.Instance.gameObject.GetComponent<IMGUIHandle>();
  63. if (m_guiHandle == null)
  64. {
  65. m_guiHandle = VRModule.Instance.gameObject.AddComponent<IMGUIHandle>();
  66. m_guiHandle.simulator = this;
  67. }
  68. m_prevStates = new IVRModuleDeviceState[SIMULATOR_MAX_DEVICE_COUNT];
  69. m_currStates = new IVRModuleDeviceStateRW[SIMULATOR_MAX_DEVICE_COUNT];
  70. EnsureDeviceStateLength(SIMULATOR_MAX_DEVICE_COUNT);
  71. for (uint i = 0u; i < SIMULATOR_MAX_DEVICE_COUNT; ++i)
  72. {
  73. EnsureValidDeviceState(i, out m_prevStates[i], out m_currStates[i]);
  74. }
  75. if (onActivated != null)
  76. {
  77. onActivated();
  78. }
  79. }
  80. public override void OnDeactivated()
  81. {
  82. if (m_guiHandle != null)
  83. {
  84. m_guiHandle.simulator = null;
  85. UnityEngine.Object.Destroy(m_guiHandle);
  86. m_guiHandle = null;
  87. }
  88. UpdateMainCamTracking();
  89. XRSettings.enabled = m_prevXREnabled;
  90. if (onDeactivated != null)
  91. {
  92. onDeactivated();
  93. }
  94. }
  95. public override uint GetRightControllerDeviceIndex() { return RIGHT_INDEX; }
  96. public override uint GetLeftControllerDeviceIndex() { return LEFT_INDEX; }
  97. public override void Update()
  98. {
  99. if (VIUSettings.enableSimulatorKeyboardMouseControl)
  100. {
  101. UpdateKeyDown();
  102. Cursor.visible = !hasControlFocus;
  103. Cursor.lockState = hasControlFocus ? CursorLockMode.Locked : CursorLockMode.None;
  104. }
  105. }
  106. public override void BeforeRenderUpdate()
  107. {
  108. FlushDeviceState();
  109. InternalUpdateDeviceState(m_prevStates, m_currStates);
  110. ProcessConnectedDeviceChanged();
  111. ProcessDevicePoseChanged();
  112. ProcessDeviceInputChanged();
  113. }
  114. public void InternalUpdateDeviceState(IVRModuleDeviceState[] prevState, IVRModuleDeviceStateRW[] currState)
  115. {
  116. if (VIUSettings.enableSimulatorKeyboardMouseControl && hasControlFocus)
  117. {
  118. if (IsEscapeKeyDown())
  119. {
  120. if (IsDeviceSelected())
  121. {
  122. DeselectDevice();
  123. }
  124. else
  125. {
  126. //SetSimulatorActive(false);
  127. hasControlFocus = false;
  128. }
  129. }
  130. // reset to default state
  131. if (m_resetDevices || IsResetAllKeyDown())
  132. {
  133. m_resetDevices = false;
  134. foreach (var state in currState)
  135. {
  136. switch (state.deviceIndex)
  137. {
  138. case VRModule.HMD_DEVICE_INDEX:
  139. case RIGHT_INDEX:
  140. case LEFT_INDEX:
  141. InitializeDevice(currState[VRModule.HMD_DEVICE_INDEX], state);
  142. break;
  143. default:
  144. if (state.isConnected)
  145. {
  146. state.Reset();
  147. }
  148. break;
  149. }
  150. }
  151. DeselectDevice();
  152. }
  153. // align devices with hmd
  154. if (IsResetDevicesKeyDown())
  155. {
  156. foreach (var state in currState)
  157. {
  158. switch (state.deviceIndex)
  159. {
  160. case VRModule.HMD_DEVICE_INDEX:
  161. break;
  162. case RIGHT_INDEX:
  163. state.pose = currState[VRModule.HMD_DEVICE_INDEX].pose * s_offsetRightController;
  164. break;
  165. case LEFT_INDEX:
  166. state.pose = currState[VRModule.HMD_DEVICE_INDEX].pose * s_offsetLeftController;
  167. break;
  168. default:
  169. if (state.isConnected)
  170. {
  171. state.pose = currState[VRModule.HMD_DEVICE_INDEX].pose * s_offsetTracker;
  172. }
  173. break;
  174. }
  175. }
  176. }
  177. // select/deselect device
  178. IVRModuleDeviceStateRW keySelectDevice;
  179. if (GetDeviceByInputDownKeyCode(currState, out keySelectDevice))
  180. {
  181. if (IsShiftKeyPressed())
  182. {
  183. // remove device
  184. if (keySelectDevice.isConnected && keySelectDevice.deviceIndex != VRModule.HMD_DEVICE_INDEX)
  185. {
  186. if (IsSelectedDevice(keySelectDevice))
  187. {
  188. DeselectDevice();
  189. }
  190. keySelectDevice.Reset();
  191. }
  192. }
  193. else
  194. {
  195. if (IsSelectedDevice(keySelectDevice))
  196. {
  197. DeselectDevice();
  198. }
  199. else
  200. {
  201. // select device
  202. if (!keySelectDevice.isConnected)
  203. {
  204. InitializeDevice(currState[VRModule.HMD_DEVICE_INDEX], keySelectDevice);
  205. }
  206. SelectDevice(keySelectDevice);
  207. }
  208. }
  209. }
  210. var selectedDevice = VRModule.IsValidDeviceIndex(selectedDeviceIndex) && currState[selectedDeviceIndex].isConnected ? currState[selectedDeviceIndex] : null;
  211. if (selectedDevice != null)
  212. {
  213. // control selected device
  214. ControlDevice(selectedDevice);
  215. if (selectedDevice.deviceClass == VRModuleDeviceClass.Controller || selectedDevice.deviceClass == VRModuleDeviceClass.GenericTracker)
  216. {
  217. HandleDeviceInput(selectedDevice);
  218. }
  219. }
  220. else if (hasControlFocus)
  221. {
  222. // control device group
  223. ControlDeviceGroup(currState);
  224. }
  225. // control camera (TFGH)
  226. if (currState[VRModule.HMD_DEVICE_INDEX].isConnected)
  227. {
  228. ControlCamera(currState[VRModule.HMD_DEVICE_INDEX]);
  229. }
  230. }
  231. else if (IsDeviceSelected())
  232. {
  233. DeselectDevice();
  234. }
  235. if (onUpdateDeviceState != null)
  236. {
  237. onUpdateDeviceState(prevState, currState);
  238. }
  239. UpdateMainCamTracking();
  240. }
  241. private bool m_autoTrackMainCam;
  242. private RigidPose m_mainCamStartPose;
  243. private void UpdateMainCamTracking()
  244. {
  245. if (VIUSettings.simulatorAutoTrackMainCamera)
  246. {
  247. if (!m_autoTrackMainCam)
  248. {
  249. m_autoTrackMainCam = true;
  250. m_mainCamStartPose = new RigidPose(Camera.main.transform, true);
  251. }
  252. if (Camera.main != null)
  253. {
  254. var hmd = VRModule.GetDeviceState(VRModule.HMD_DEVICE_INDEX);
  255. if (hmd.isConnected)
  256. {
  257. RigidPose.SetPose(Camera.main.transform, hmd.pose);
  258. }
  259. }
  260. }
  261. else
  262. {
  263. if (m_autoTrackMainCam)
  264. {
  265. m_autoTrackMainCam = false;
  266. if (Camera.main != null)
  267. {
  268. RigidPose.SetPose(Camera.main.transform, m_mainCamStartPose);
  269. }
  270. }
  271. }
  272. }
  273. private bool IsSelectedDevice(IVRModuleDeviceStateRW state)
  274. {
  275. return selectedDeviceIndex == state.deviceIndex;
  276. }
  277. private bool IsDeviceSelected()
  278. {
  279. return VRModule.IsValidDeviceIndex(selectedDeviceIndex);
  280. }
  281. private void SelectDevice(IVRModuleDeviceStateRW state)
  282. {
  283. selectedDeviceIndex = state.deviceIndex;
  284. }
  285. private void DeselectDevice()
  286. {
  287. selectedDeviceIndex = VRModule.INVALID_DEVICE_INDEX;
  288. }
  289. // Input.GetKeyDown in UpdateDeviceState is not working
  290. private bool m_menuKeyPressed;
  291. private bool m_resetDevicesKeyPressed;
  292. private bool m_resetAllKeyPressed;
  293. private bool m_escapeKeyPressed;
  294. private bool m_shiftKeyPressed;
  295. private bool m_backQuotePressed;
  296. private bool[] m_alphaKeyDownState = new bool[10];
  297. private void UpdateKeyDown()
  298. {
  299. m_menuKeyPressed = Input.GetKeyDown(KeyCode.M);
  300. m_resetDevicesKeyPressed = Input.GetKeyDown(KeyCode.F2);
  301. m_resetAllKeyPressed = Input.GetKeyDown(KeyCode.F3);
  302. m_escapeKeyPressed = Input.GetKeyDown(KeyCode.Escape);
  303. m_shiftKeyPressed = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
  304. m_backQuotePressed = Input.GetKey(KeyCode.BackQuote);
  305. m_alphaKeyDownState[0] = Input.GetKeyDown(KeyCode.Alpha0) || Input.GetKeyDown(KeyCode.Keypad0);
  306. m_alphaKeyDownState[1] = Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1);
  307. m_alphaKeyDownState[2] = Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2);
  308. m_alphaKeyDownState[3] = Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3);
  309. m_alphaKeyDownState[4] = Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4);
  310. m_alphaKeyDownState[5] = Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5);
  311. m_alphaKeyDownState[6] = Input.GetKeyDown(KeyCode.Alpha6) || Input.GetKeyDown(KeyCode.Keypad6);
  312. m_alphaKeyDownState[7] = Input.GetKeyDown(KeyCode.Alpha7) || Input.GetKeyDown(KeyCode.Keypad7);
  313. m_alphaKeyDownState[8] = Input.GetKeyDown(KeyCode.Alpha8) || Input.GetKeyDown(KeyCode.Keypad8);
  314. m_alphaKeyDownState[9] = Input.GetKeyDown(KeyCode.Alpha9) || Input.GetKeyDown(KeyCode.Keypad9);
  315. }
  316. private bool IsMenuKeyDown() { return m_menuKeyPressed; }
  317. private bool IsResetAllKeyDown() { return m_resetAllKeyPressed; }
  318. private bool IsResetDevicesKeyDown() { return m_resetDevicesKeyPressed; }
  319. private bool IsEscapeKeyDown() { return m_escapeKeyPressed; }
  320. private bool IsShiftKeyPressed() { return m_shiftKeyPressed; }
  321. private bool GetDeviceByInputDownKeyCode(IVRModuleDeviceStateRW[] deviceStates, out IVRModuleDeviceStateRW deviceState)
  322. {
  323. if (!m_backQuotePressed)
  324. {
  325. if (m_alphaKeyDownState[0]) { deviceState = deviceStates[0]; return true; }
  326. if (m_alphaKeyDownState[1]) { deviceState = deviceStates[1]; return true; }
  327. if (m_alphaKeyDownState[2]) { deviceState = deviceStates[2]; return true; }
  328. if (m_alphaKeyDownState[3]) { deviceState = deviceStates[3]; return true; }
  329. if (m_alphaKeyDownState[4]) { deviceState = deviceStates[4]; return true; }
  330. if (m_alphaKeyDownState[5]) { deviceState = deviceStates[5]; return true; }
  331. if (m_alphaKeyDownState[6]) { deviceState = deviceStates[6]; return true; }
  332. if (m_alphaKeyDownState[7]) { deviceState = deviceStates[7]; return true; }
  333. if (m_alphaKeyDownState[8]) { deviceState = deviceStates[8]; return true; }
  334. if (m_alphaKeyDownState[9]) { deviceState = deviceStates[9]; return true; }
  335. }
  336. else
  337. {
  338. if (m_alphaKeyDownState[0]) { deviceState = deviceStates[10]; return true; }
  339. if (m_alphaKeyDownState[1]) { deviceState = deviceStates[11]; return true; }
  340. if (m_alphaKeyDownState[2]) { deviceState = deviceStates[12]; return true; }
  341. if (m_alphaKeyDownState[3]) { deviceState = deviceStates[13]; return true; }
  342. if (m_alphaKeyDownState[4]) { deviceState = deviceStates[14]; return true; }
  343. if (m_alphaKeyDownState[5]) { deviceState = deviceStates[15]; return true; }
  344. }
  345. deviceState = null;
  346. return false;
  347. }
  348. private void InitializeDevice(IVRModuleDeviceStateRW hmdState, IVRModuleDeviceStateRW deviceState)
  349. {
  350. switch (deviceState.deviceIndex)
  351. {
  352. case VRModule.HMD_DEVICE_INDEX:
  353. {
  354. deviceState.isConnected = true;
  355. deviceState.deviceClass = VRModuleDeviceClass.HMD;
  356. deviceState.serialNumber = "VIU Simulator HMD Device";
  357. deviceState.modelNumber = deviceState.serialNumber;
  358. deviceState.renderModelName = deviceState.serialNumber;
  359. deviceState.deviceModel = VRModuleDeviceModel.ViveHMD;
  360. deviceState.isPoseValid = true;
  361. deviceState.pose = s_initHmdPose;
  362. break;
  363. }
  364. case RIGHT_INDEX:
  365. {
  366. deviceState.isConnected = true;
  367. deviceState.deviceClass = VRModuleDeviceClass.Controller;
  368. deviceState.serialNumber = "VIU Simulator Controller Device " + RIGHT_INDEX;
  369. deviceState.modelNumber = deviceState.serialNumber;
  370. deviceState.renderModelName = deviceState.serialNumber;
  371. deviceState.deviceModel = VIUSettings.simulatorRightControllerModel;
  372. deviceState.input2DType = VRModuleInput2DType.TouchpadOnly;
  373. var pose = new RigidPose(new Vector3(0.3f, -0.25f, 0.7f), Quaternion.identity);
  374. deviceState.isPoseValid = true;
  375. deviceState.pose = (hmdState.isConnected ? hmdState.pose : s_initHmdPose) * pose;
  376. s_offsetRightController = RigidPose.FromToPose(hmdState.isConnected ? hmdState.pose : s_initHmdPose, deviceState.pose);
  377. deviceState.buttonPressed = 0ul;
  378. deviceState.buttonTouched = 0ul;
  379. deviceState.ResetAxisValues();
  380. break;
  381. }
  382. case LEFT_INDEX:
  383. {
  384. deviceState.isConnected = true;
  385. deviceState.deviceClass = VRModuleDeviceClass.Controller;
  386. deviceState.serialNumber = "VIU Simulator Controller Device " + LEFT_INDEX;
  387. deviceState.modelNumber = deviceState.serialNumber;
  388. deviceState.renderModelName = deviceState.serialNumber;
  389. deviceState.deviceModel = VIUSettings.simulatorLeftControllerModel;
  390. deviceState.input2DType = VRModuleInput2DType.TouchpadOnly;
  391. var pose = new RigidPose(new Vector3(-0.3f, -0.25f, 0.7f), Quaternion.identity);
  392. deviceState.isPoseValid = true;
  393. deviceState.pose = (hmdState.isConnected ? hmdState.pose : s_initHmdPose) * pose;
  394. s_offsetLeftController = RigidPose.FromToPose(hmdState.isConnected ? hmdState.pose : s_initHmdPose, deviceState.pose);
  395. deviceState.buttonPressed = 0ul;
  396. deviceState.buttonTouched = 0ul;
  397. deviceState.ResetAxisValues();
  398. break;
  399. }
  400. default:
  401. {
  402. deviceState.isConnected = true;
  403. deviceState.deviceClass = VRModuleDeviceClass.GenericTracker;
  404. deviceState.serialNumber = "VIU Simulator Generic Tracker Device " + deviceState.deviceIndex;
  405. deviceState.modelNumber = deviceState.serialNumber;
  406. deviceState.renderModelName = deviceState.serialNumber;
  407. deviceState.deviceModel = VIUSettings.simulatorOtherModel;
  408. var pose = new RigidPose(new Vector3(0f, -0.25f, 0.7f), Quaternion.identity);
  409. deviceState.isPoseValid = true;
  410. deviceState.pose = (hmdState.isConnected ? hmdState.pose : s_initHmdPose) * pose;
  411. s_offsetTracker = RigidPose.FromToPose(hmdState.isConnected ? hmdState.pose : s_initHmdPose, deviceState.pose);
  412. deviceState.buttonPressed = 0ul;
  413. deviceState.buttonTouched = 0ul;
  414. deviceState.ResetAxisValues();
  415. break;
  416. }
  417. }
  418. }
  419. private void ControlDevice(IVRModuleDeviceStateRW deviceState)
  420. {
  421. var pose = deviceState.pose;
  422. var poseEuler = pose.rot.eulerAngles;
  423. var deltaAngle = Time.unscaledDeltaTime * VIUSettings.simulatorMouseRotateSpeed;
  424. var deltaKeyAngle = Time.unscaledDeltaTime * VIUSettings.simulatorKeyRotateSpeed;
  425. poseEuler.x = Mathf.Repeat(poseEuler.x + 180f, 360f) - 180f;
  426. if (!IsShiftKeyPressed())
  427. {
  428. var pitchDelta = -Input.GetAxisRaw("Mouse Y") * deltaAngle;
  429. if (pitchDelta > 0f)
  430. {
  431. if (poseEuler.x < 90f && poseEuler.x > -180f)
  432. {
  433. poseEuler.x = Mathf.Min(90f, poseEuler.x + pitchDelta);
  434. }
  435. }
  436. else if (pitchDelta < 0f)
  437. {
  438. if (poseEuler.x < 180f && poseEuler.x > -90f)
  439. {
  440. poseEuler.x = Mathf.Max(-90f, poseEuler.x + pitchDelta);
  441. }
  442. }
  443. poseEuler.y += Input.GetAxisRaw("Mouse X") * deltaAngle;
  444. }
  445. if (Input.GetKey(KeyCode.DownArrow))
  446. {
  447. if (poseEuler.x < 90f && poseEuler.x > -180f)
  448. {
  449. poseEuler.x = Mathf.Min(90f, poseEuler.x + deltaKeyAngle);
  450. }
  451. }
  452. if (Input.GetKey(KeyCode.UpArrow))
  453. {
  454. if (poseEuler.x < 180f && poseEuler.x > -90f)
  455. {
  456. poseEuler.x = Mathf.Max(-90f, poseEuler.x - deltaKeyAngle);
  457. }
  458. }
  459. if (Input.GetKey(KeyCode.RightArrow)) { poseEuler.y += deltaKeyAngle; }
  460. if (Input.GetKey(KeyCode.LeftArrow)) { poseEuler.y -= deltaKeyAngle; }
  461. if (Input.GetKey(KeyCode.C)) { poseEuler.z += deltaKeyAngle; }
  462. if (Input.GetKey(KeyCode.Z)) { poseEuler.z -= deltaKeyAngle; }
  463. if (Input.GetKey(KeyCode.X)) { poseEuler.z = 0f; }
  464. pose.rot = Quaternion.Euler(poseEuler);
  465. var deltaMove = Time.unscaledDeltaTime * VIUSettings.simulatorKeyMoveSpeed;
  466. var moveForward = Quaternion.Euler(0f, poseEuler.y, 0f) * Vector3.forward;
  467. var moveRight = Quaternion.Euler(0f, poseEuler.y, 0f) * Vector3.right;
  468. if (Input.GetKey(KeyCode.D)) { pose.pos += moveRight * deltaMove; }
  469. if (Input.GetKey(KeyCode.A)) { pose.pos -= moveRight * deltaMove; }
  470. if (Input.GetKey(KeyCode.E)) { pose.pos += Vector3.up * deltaMove; }
  471. if (Input.GetKey(KeyCode.Q)) { pose.pos -= Vector3.up * deltaMove; }
  472. if (Input.GetKey(KeyCode.W)) { pose.pos += moveForward * deltaMove; }
  473. if (Input.GetKey(KeyCode.S)) { pose.pos -= moveForward * deltaMove; }
  474. deviceState.pose = pose;
  475. }
  476. private void ControlDeviceGroup(IVRModuleDeviceStateRW[] deviceStates)
  477. {
  478. var hmdPose = deviceStates[VRModule.HMD_DEVICE_INDEX].pose;
  479. var hmdPoseEuler = hmdPose.rot.eulerAngles;
  480. var oldRigPose = new RigidPose(hmdPose.pos, Quaternion.Euler(0f, hmdPoseEuler.y, 0f));
  481. var deltaAngle = Time.unscaledDeltaTime * VIUSettings.simulatorMouseRotateSpeed;
  482. var deltaKeyAngle = Time.unscaledDeltaTime * VIUSettings.simulatorKeyRotateSpeed;
  483. // translate and rotate HMD
  484. hmdPoseEuler.x = Mathf.Repeat(hmdPoseEuler.x + 180f, 360f) - 180f;
  485. var pitchDelta = -Input.GetAxisRaw("Mouse Y") * deltaAngle;
  486. if (pitchDelta > 0f)
  487. {
  488. if (hmdPoseEuler.x < 90f && hmdPoseEuler.x > -180f)
  489. {
  490. hmdPoseEuler.x = Mathf.Min(90f, hmdPoseEuler.x + pitchDelta);
  491. }
  492. }
  493. else if (pitchDelta < 0f)
  494. {
  495. if (hmdPoseEuler.x < 180f && hmdPoseEuler.x > -90f)
  496. {
  497. hmdPoseEuler.x = Mathf.Max(-90f, hmdPoseEuler.x + pitchDelta);
  498. }
  499. }
  500. if (Input.GetKey(KeyCode.DownArrow))
  501. {
  502. if (hmdPoseEuler.x < 90f && hmdPoseEuler.x > -180f)
  503. {
  504. hmdPoseEuler.x = Mathf.Min(90f, hmdPoseEuler.x + deltaKeyAngle);
  505. }
  506. }
  507. if (Input.GetKey(KeyCode.UpArrow))
  508. {
  509. if (hmdPoseEuler.x < 180f && hmdPoseEuler.x > -90f)
  510. {
  511. hmdPoseEuler.x = Mathf.Max(-90f, hmdPoseEuler.x - deltaKeyAngle);
  512. }
  513. }
  514. if (Input.GetKey(KeyCode.RightArrow)) { hmdPoseEuler.y += deltaKeyAngle; }
  515. if (Input.GetKey(KeyCode.LeftArrow)) { hmdPoseEuler.y -= deltaKeyAngle; }
  516. if (Input.GetKey(KeyCode.C)) { hmdPoseEuler.z += deltaKeyAngle; }
  517. if (Input.GetKey(KeyCode.Z)) { hmdPoseEuler.z -= deltaKeyAngle; }
  518. if (Input.GetKey(KeyCode.X)) { hmdPoseEuler.z = 0f; }
  519. hmdPoseEuler.y += Input.GetAxisRaw("Mouse X") * deltaAngle;
  520. hmdPose.rot = Quaternion.Euler(hmdPoseEuler);
  521. var deltaMove = Time.unscaledDeltaTime * VIUSettings.simulatorKeyMoveSpeed;
  522. var moveForward = Quaternion.Euler(0f, hmdPoseEuler.y, 0f) * Vector3.forward;
  523. var moveRight = Quaternion.Euler(0f, hmdPoseEuler.y, 0f) * Vector3.right;
  524. if (Input.GetKey(KeyCode.D)) { hmdPose.pos += moveRight * deltaMove; }
  525. if (Input.GetKey(KeyCode.A)) { hmdPose.pos -= moveRight * deltaMove; }
  526. if (Input.GetKey(KeyCode.E)) { hmdPose.pos += Vector3.up * deltaMove; }
  527. if (Input.GetKey(KeyCode.Q)) { hmdPose.pos -= Vector3.up * deltaMove; }
  528. if (Input.GetKey(KeyCode.W)) { hmdPose.pos += moveForward * deltaMove; }
  529. if (Input.GetKey(KeyCode.S)) { hmdPose.pos -= moveForward * deltaMove; }
  530. deviceStates[VRModule.HMD_DEVICE_INDEX].pose = hmdPose;
  531. var rigPoseOffset = new RigidPose(hmdPose.pos, Quaternion.Euler(0f, hmdPose.rot.eulerAngles.y, 0f)) * oldRigPose.GetInverse();
  532. for (int i = deviceStates.Length - 1; i >= 0; --i)
  533. {
  534. if (i == VRModule.HMD_DEVICE_INDEX) { continue; }
  535. var state = deviceStates[i];
  536. if (!state.isConnected) { continue; }
  537. state.pose = rigPoseOffset * state.pose;
  538. }
  539. }
  540. private void ControlCamera(IVRModuleDeviceStateRW deviceState)
  541. {
  542. var pose = deviceState.pose;
  543. var poseEuler = pose.rot.eulerAngles;
  544. var deltaKeyAngle = Time.unscaledDeltaTime * VIUSettings.simulatorKeyRotateSpeed;
  545. poseEuler.x = Mathf.Repeat(poseEuler.x + 180f, 360f) - 180f;
  546. if (Input.GetKey(KeyCode.K))
  547. {
  548. if (poseEuler.x < 90f && poseEuler.x > -180f)
  549. {
  550. poseEuler.x = Mathf.Min(90f, poseEuler.x + deltaKeyAngle);
  551. }
  552. }
  553. if (Input.GetKey(KeyCode.I))
  554. {
  555. if (poseEuler.x < 180f && poseEuler.x > -90f)
  556. {
  557. poseEuler.x = Mathf.Max(-90f, poseEuler.x - deltaKeyAngle);
  558. }
  559. }
  560. if (Input.GetKey(KeyCode.L)) { poseEuler.y += deltaKeyAngle; }
  561. if (Input.GetKey(KeyCode.J)) { poseEuler.y -= deltaKeyAngle; }
  562. if (Input.GetKey(KeyCode.N)) { poseEuler.z += deltaKeyAngle; }
  563. if (Input.GetKey(KeyCode.V)) { poseEuler.z -= deltaKeyAngle; }
  564. if (Input.GetKey(KeyCode.B)) { poseEuler.z = 0f; }
  565. pose.rot = Quaternion.Euler(poseEuler);
  566. var deltaMove = Time.unscaledDeltaTime * VIUSettings.simulatorKeyMoveSpeed;
  567. var moveForward = Quaternion.Euler(0f, poseEuler.y, 0f) * Vector3.forward;
  568. var moveRight = Quaternion.Euler(0f, poseEuler.y, 0f) * Vector3.right;
  569. if (Input.GetKey(KeyCode.H)) { pose.pos += moveRight * deltaMove; }
  570. if (Input.GetKey(KeyCode.F)) { pose.pos -= moveRight * deltaMove; }
  571. if (Input.GetKey(KeyCode.Y)) { pose.pos += Vector3.up * deltaMove; }
  572. if (Input.GetKey(KeyCode.R)) { pose.pos -= Vector3.up * deltaMove; }
  573. if (Input.GetKey(KeyCode.T)) { pose.pos += moveForward * deltaMove; }
  574. if (Input.GetKey(KeyCode.G)) { pose.pos -= moveForward * deltaMove; }
  575. deviceState.pose = pose;
  576. }
  577. private void HandleDeviceInput(IVRModuleDeviceStateRW deviceState)
  578. {
  579. var leftPressed = Input.GetMouseButton(0);
  580. var rightPressed = Input.GetMouseButton(1);
  581. var midPressed = Input.GetMouseButton(2);
  582. deviceState.SetButtonPress(VRModuleRawButton.Trigger, leftPressed);
  583. deviceState.SetButtonTouch(VRModuleRawButton.Trigger, leftPressed);
  584. deviceState.SetAxisValue(VRModuleRawAxis.Trigger, leftPressed ? 1f : 0f);
  585. deviceState.SetButtonPress(VRModuleRawButton.Grip, midPressed);
  586. deviceState.SetButtonTouch(VRModuleRawButton.Grip, midPressed);
  587. deviceState.SetAxisValue(VRModuleRawAxis.CapSenseGrip, midPressed ? 1f : 0f);
  588. deviceState.SetButtonPress(VRModuleRawButton.Touchpad, rightPressed);
  589. deviceState.SetButtonPress(VRModuleRawButton.ApplicationMenu, IsMenuKeyDown());
  590. deviceState.SetButtonTouch(VRModuleRawButton.ApplicationMenu, IsMenuKeyDown());
  591. if (VIUSettings.simulateTrackpadTouch && IsShiftKeyPressed())
  592. {
  593. deviceState.SetButtonTouch(VRModuleRawButton.Touchpad, true);
  594. deviceState.SetAxisValue(VRModuleRawAxis.TouchpadX, deviceState.GetAxisValue(VRModuleRawAxis.TouchpadX) + (Input.GetAxisRaw("Mouse X") * 0.1f));
  595. deviceState.SetAxisValue(VRModuleRawAxis.TouchpadY, deviceState.GetAxisValue(VRModuleRawAxis.TouchpadY) + (Input.GetAxisRaw("Mouse Y") * 0.1f));
  596. }
  597. else
  598. {
  599. deviceState.SetButtonTouch(VRModuleRawButton.Touchpad, rightPressed);
  600. deviceState.SetAxisValue(VRModuleRawAxis.TouchpadX, 0f);
  601. deviceState.SetAxisValue(VRModuleRawAxis.TouchpadY, 0f);
  602. }
  603. }
  604. private class IMGUIHandle : MonoBehaviour
  605. {
  606. public SimulatorVRModule simulator { get; set; }
  607. private bool showGUI { get; set; }
  608. private void Start()
  609. {
  610. showGUI = true;
  611. }
  612. private void Update()
  613. {
  614. if (Input.GetKeyDown(KeyCode.F1))
  615. {
  616. showGUI = !showGUI;
  617. }
  618. }
  619. private static string Bold(string s) { return "<b>" + s + "</b>"; }
  620. private static string SetColor(string s, string color) { return "<color=" + color + ">" + s + "</color>"; }
  621. private void OnGUI()
  622. {
  623. if (!VIUSettings.enableSimulatorKeyboardMouseControl) { return; }
  624. if (!showGUI || simulator == null) { return; }
  625. var hints = string.Empty;
  626. if (simulator.hasControlFocus)
  627. {
  628. GUI.skin.box.stretchWidth = false;
  629. GUI.skin.box.stretchHeight = false;
  630. GUI.skin.box.alignment = TextAnchor.UpperLeft;
  631. GUI.skin.button.alignment = TextAnchor.MiddleCenter;
  632. GUI.skin.box.normal.textColor = Color.white;
  633. // device status grids
  634. GUI.skin.box.padding = new RectOffset(10, 10, 5, 5);
  635. GUILayout.BeginArea(new Rect(5f, 5f, Screen.width, 30f));
  636. GUILayout.BeginHorizontal();
  637. for (uint i = 0u; i < SIMULATOR_MAX_DEVICE_COUNT; ++i)
  638. {
  639. var isHmd = i == VRModule.HMD_DEVICE_INDEX;
  640. var isSelectedDevice = i == simulator.selectedDeviceIndex;
  641. var isConndected = VRModule.GetCurrentDeviceState(i).isConnected;
  642. var deviceName = isHmd ? "HMD 0" : i.ToString();
  643. var colorName = !isConndected ? "grey" : isSelectedDevice ? "lime" : "white";
  644. GUILayout.Box(SetColor(Bold(deviceName), colorName));
  645. }
  646. GUILayout.EndHorizontal();
  647. GUILayout.EndArea();
  648. var selectedDeviceClass = VRModule.GetCurrentDeviceState(simulator.selectedDeviceIndex).deviceClass;
  649. // instructions
  650. if (selectedDeviceClass == VRModuleDeviceClass.Invalid)
  651. {
  652. hints += "Pause simulator: " + Bold("ESC") + "\n";
  653. hints += "Toggle instructions: " + Bold("F1") + "\n";
  654. hints += "Align devices to HMD: " + Bold("F2") + "\n";
  655. hints += "Reset all devices to initial state: " + Bold("F3") + "\n\n";
  656. hints += "Move: " + Bold("WASD / QE") + "\n";
  657. hints += "Rotate: " + Bold("Mouse") + "\n";
  658. hints += "Add and select a device: \n";
  659. hints += " [N] " + Bold("Num 0~9") + "\n";
  660. hints += " [10+N] " + Bold("` + Num 0~5") + "\n";
  661. hints += "Remove and deselect a device: \n";
  662. hints += " [N] " + Bold("Shift + Num 0~9") + "\n";
  663. hints += " [10+N] " + Bold("Shift + ` + Num 0~5") + "\n";
  664. }
  665. else
  666. {
  667. hints += "Toggle instructions: " + Bold("F1") + "\n";
  668. hints += "Align devices with HMD: " + Bold("F2") + "\n";
  669. hints += "Reset all devices to initial state: " + Bold("F3") + "\n\n";
  670. hints += "Currently controlling ";
  671. hints += SetColor(Bold("Device " + simulator.selectedDeviceIndex.ToString()) + " " + Bold("(" + selectedDeviceClass.ToString() + ")") + "\n", "lime");
  672. if (simulator.selectedDeviceIndex <= 9)
  673. {
  674. hints += "Deselect this device: " + Bold("ESC") + " / " + Bold("Num " + simulator.selectedDeviceIndex) + "\n";
  675. }
  676. else
  677. {
  678. hints += "Deselect this device: " + Bold("ESC") + " / " + Bold("` + Num " + simulator.selectedDeviceIndex) + "\n";
  679. }
  680. hints += "Add and select a device: \n";
  681. hints += " [N] " + Bold("Num 0~9") + "\n";
  682. hints += " [10+N] " + Bold("` + Num 0~5") + "\n";
  683. hints += "Remove and deselect a device: \n";
  684. hints += " [N] " + Bold("Shift + Num 0~9") + "\n";
  685. hints += " [10+N] " + Bold("Shift + ` + Num 0~5") + "\n";
  686. hints += "\n";
  687. hints += "Move: " + Bold("WASD / QE") + "\n";
  688. hints += "Rotate (pitch and yaw): " + Bold("Mouse") + " or " + Bold("Arrow Keys") + "\n";
  689. hints += "Rotate (roll): " + Bold("ZC") + "\n";
  690. hints += "Reset roll: " + Bold("X") + "\n";
  691. if (selectedDeviceClass == VRModuleDeviceClass.Controller || selectedDeviceClass == VRModuleDeviceClass.GenericTracker)
  692. {
  693. hints += "\n";
  694. hints += "Trigger press: " + Bold("Mouse Left") + "\n";
  695. hints += "Grip press: " + Bold("Mouse Middle") + "\n";
  696. hints += "Trackpad press: " + Bold("Mouse Right") + "\n";
  697. hints += "Trackpad touch: " + Bold("Hold Shift") + " + " + Bold("Mouse") + "\n";
  698. hints += "Menu button press: " + Bold("M") + "\n";
  699. }
  700. }
  701. hints += "\n";
  702. hints += "HMD Move: " + Bold("TFGH / RY") + "\n";
  703. hints += "HMD Rotate (pitch and yaw): " + Bold("IJKL") + "\n";
  704. hints += "HMD Rotate (roll): " + Bold("VN") + "\n";
  705. hints += "HMD Reset roll: " + Bold("B");
  706. GUI.skin.box.padding = new RectOffset(10, 10, 10, 10);
  707. GUILayout.BeginArea(new Rect(5f, 35f, Screen.width, Screen.height));
  708. GUILayout.Box(hints);
  709. GUILayout.EndArea();
  710. }
  711. else
  712. {
  713. // simulator resume button
  714. int buttonHeight = 30;
  715. int buttonWidth = 130;
  716. Rect ButtonRect = new Rect((Screen.width * 0.5f) - (buttonWidth * 0.5f), (Screen.height * 0.5f) - buttonHeight, buttonWidth, buttonHeight);
  717. if (GUI.Button(ButtonRect, Bold("Back to simulator")))
  718. {
  719. simulator.hasControlFocus = true;
  720. }
  721. GUI.skin.box.padding = new RectOffset(10, 10, 5, 5);
  722. GUILayout.BeginArea(new Rect(5f, 5f, Screen.width, 30f));
  723. GUILayout.BeginHorizontal();
  724. hints += "Toggle instructions: " + Bold("F1");
  725. GUILayout.Box(hints);
  726. GUILayout.EndHorizontal();
  727. GUILayout.EndArea();
  728. }
  729. }
  730. }
  731. }
  732. }