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.

452 lines
15 KiB

5 years ago
  1. //========= Copyright 2016-2020, HTC Corporation. All rights reserved. ===========
  2. using HTC.UnityPlugin.Utility;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Reflection;
  7. using UnityEngine;
  8. #if VIU_STEAMVR_2_0_0_OR_NEWER && UNITY_STANDALONE
  9. using Valve.VR;
  10. #endif
  11. namespace HTC.UnityPlugin.VRModuleManagement
  12. {
  13. public partial class VRModule : SingletonBehaviour<VRModule>
  14. {
  15. private static readonly DeviceState s_defaultState;
  16. private static readonly SimulatorVRModule s_simulator;
  17. private static readonly Dictionary<string, uint> s_deviceSerialNumberTable;
  18. [SerializeField]
  19. private bool m_dontDestroyOnLoad = true;
  20. [SerializeField]
  21. private bool m_lockPhysicsUpdateRateToRenderFrequency = true;
  22. [SerializeField]
  23. private VRModuleSelectEnum m_selectModule = VRModuleSelectEnum.Auto;
  24. [SerializeField]
  25. private VRModuleTrackingSpaceType m_trackingSpaceType = VRModuleTrackingSpaceType.RoomScale;
  26. [SerializeField]
  27. private NewPosesEvent m_onNewPoses = new NewPosesEvent();
  28. [SerializeField]
  29. private NewInputEvent m_onNewInput = new NewInputEvent();
  30. [SerializeField]
  31. private ControllerRoleChangedEvent m_onControllerRoleChanged = new ControllerRoleChangedEvent();
  32. [SerializeField]
  33. private InputFocusEvent m_onInputFocus = new InputFocusEvent();
  34. [SerializeField]
  35. private DeviceConnectedEvent m_onDeviceConnected = new DeviceConnectedEvent();
  36. [SerializeField]
  37. private ActiveModuleChangedEvent m_onActiveModuleChanged = new ActiveModuleChangedEvent();
  38. private bool m_delayDeactivate = false;
  39. private bool m_isDestoryed = false;
  40. private ModuleBase[] m_modules;
  41. private ModuleBase[] m_modulesOrdered;
  42. private VRModuleActiveEnum m_activatedModule = VRModuleActiveEnum.Uninitialized;
  43. private ModuleBase m_activatedModuleBase;
  44. private DeviceState[] m_prevStates;
  45. private DeviceState[] m_currStates;
  46. static VRModule()
  47. {
  48. SetDefaultInitGameObjectGetter(GetDefaultInitGameObject);
  49. s_defaultState = new DeviceState(INVALID_DEVICE_INDEX);
  50. s_simulator = new SimulatorVRModule();
  51. s_deviceSerialNumberTable = new Dictionary<string, uint>(16);
  52. }
  53. private static GameObject GetDefaultInitGameObject()
  54. {
  55. return new GameObject("[ViveInputUtility]");
  56. }
  57. public static GameObject GetInstanceGameObject()
  58. {
  59. return Instance.gameObject;
  60. }
  61. protected override void OnSingletonBehaviourInitialized()
  62. {
  63. if (m_dontDestroyOnLoad && transform.parent == null && Application.isPlaying)
  64. {
  65. DontDestroyOnLoad(gameObject);
  66. }
  67. m_activatedModule = VRModuleActiveEnum.Uninitialized;
  68. m_activatedModuleBase = null;
  69. try
  70. {
  71. var modules = new List<ModuleBase>();
  72. var modulesOrdered = new List<ModuleBase>();
  73. foreach (var type in Assembly.GetAssembly(typeof(ModuleBase)).GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(ModuleBase))))
  74. {
  75. var inst = type == typeof(SimulatorVRModule) ? s_simulator : (ModuleBase)Activator.CreateInstance(type);
  76. var index = inst.moduleIndex;
  77. if (index < 0)
  78. {
  79. Debug.LogWarning("Invalid module index, module will not be activated! module name=" + type.Name + " index=" + index);
  80. }
  81. else if (index < modules.Count && modules[index] != null)
  82. {
  83. Debug.LogWarning("Duplicated module index, module will not be activated! module name=" + type.Name + " index=" + index);
  84. }
  85. else
  86. {
  87. while (index >= modules.Count) { modules.Add(null); }
  88. modules[index] = inst;
  89. }
  90. var order = inst.moduleOrder;
  91. if (order < 0)
  92. {
  93. Debug.LogWarning("Invalid module order, module will not be activated! module name=" + type.Name + " order=" + order);
  94. }
  95. else if (order < modulesOrdered.Count && modulesOrdered[order] != null)
  96. {
  97. Debug.LogWarning("Duplicated module order, module will not be activated! module name=" + type.Name + " order=" + order);
  98. }
  99. else
  100. {
  101. while (order >= modulesOrdered.Count) { modulesOrdered.Add(null); }
  102. modulesOrdered[order] = inst;
  103. }
  104. }
  105. m_modules = modules.ToArray();
  106. m_modulesOrdered = modulesOrdered.ToArray();
  107. }
  108. catch (Exception e)
  109. {
  110. m_modules = new ModuleBase[] { new DefaultModule() };
  111. m_modulesOrdered = new ModuleBase[] { new DefaultModule() };
  112. Debug.LogError(e);
  113. }
  114. }
  115. private uint GetDeviceStateLength() { return m_currStates == null ? 0u : (uint)m_currStates.Length; }
  116. private void EnsureDeviceStateLength(uint capacity)
  117. {
  118. // NOTE: this will clear out the array
  119. var cap = Mathf.Min((int)capacity, (int)MAX_DEVICE_COUNT);
  120. if (GetDeviceStateLength() < cap)
  121. {
  122. m_prevStates = new DeviceState[cap];
  123. m_currStates = new DeviceState[cap];
  124. }
  125. }
  126. private bool TryGetValidDeviceState(uint index, out IVRModuleDeviceState prevState, out IVRModuleDeviceStateRW currState)
  127. {
  128. DeviceState prevRawState;
  129. DeviceState currRawState;
  130. if (TryGetValidDeviceState(index, out prevRawState, out currRawState))
  131. {
  132. prevState = prevRawState;
  133. currState = currRawState;
  134. return true;
  135. }
  136. else
  137. {
  138. prevState = null;
  139. currState = null;
  140. return false;
  141. }
  142. }
  143. private bool TryGetValidDeviceState(uint index, out DeviceState prevState, out DeviceState currState)
  144. {
  145. if (m_currStates == null || m_currStates[index] == null)
  146. {
  147. prevState = null;
  148. currState = null;
  149. return false;
  150. }
  151. else
  152. {
  153. prevState = m_prevStates[index];
  154. currState = m_currStates[index];
  155. return true;
  156. }
  157. }
  158. private void EnsureValidDeviceState(uint index, out IVRModuleDeviceState prevState, out IVRModuleDeviceStateRW currState)
  159. {
  160. if (!TryGetValidDeviceState(index, out prevState, out currState))
  161. {
  162. prevState = m_prevStates[index] = new DeviceState(index);
  163. currState = m_currStates[index] = new DeviceState(index);
  164. }
  165. }
  166. private void Update()
  167. {
  168. if (!IsInstance) { return; }
  169. // Get should activate module
  170. var shouldActivateModule = GetShouldActivateModule();
  171. // Update module activity
  172. if (m_activatedModule != shouldActivateModule)
  173. {
  174. // Do clean up
  175. if (m_activatedModule != VRModuleActiveEnum.Uninitialized)
  176. {
  177. DeactivateModule();
  178. }
  179. if (shouldActivateModule != VRModuleActiveEnum.Uninitialized)
  180. {
  181. ActivateModule(shouldActivateModule);
  182. }
  183. }
  184. if (m_activatedModuleBase != null)
  185. {
  186. m_activatedModuleBase.Update();
  187. }
  188. }
  189. private void FixedUpdate()
  190. {
  191. if (!IsInstance) { return; }
  192. if (m_activatedModuleBase != null)
  193. {
  194. m_activatedModuleBase.FixedUpdate();
  195. }
  196. }
  197. private void LateUpdate()
  198. {
  199. if (!IsInstance) { return; }
  200. if (m_activatedModuleBase != null)
  201. {
  202. m_activatedModuleBase.LateUpdate();
  203. }
  204. }
  205. protected override void OnDestroy()
  206. {
  207. if (IsInstance)
  208. {
  209. m_isDestoryed = true;
  210. if (!m_delayDeactivate)
  211. {
  212. DeactivateModule();
  213. }
  214. }
  215. base.OnDestroy();
  216. }
  217. private VRModuleActiveEnum GetShouldActivateModule()
  218. {
  219. if (m_isDestoryed) { return VRModuleActiveEnum.Uninitialized; }
  220. if (m_selectModule == VRModuleSelectEnum.Auto)
  221. {
  222. for (int i = m_modulesOrdered.Length - 1; i >= 0; --i)
  223. {
  224. if (m_modulesOrdered[i] != null && m_modulesOrdered[i].ShouldActiveModule())
  225. {
  226. return (VRModuleActiveEnum)m_modulesOrdered[i].moduleIndex;
  227. }
  228. }
  229. }
  230. else if (m_selectModule >= 0 && (int)m_selectModule < m_modules.Length)
  231. {
  232. return (VRModuleActiveEnum)m_selectModule;
  233. }
  234. else
  235. {
  236. return VRModuleActiveEnum.None;
  237. }
  238. return VRModuleActiveEnum.Uninitialized;
  239. }
  240. private void ActivateModule(VRModuleActiveEnum module)
  241. {
  242. if (m_activatedModule != VRModuleActiveEnum.Uninitialized)
  243. {
  244. Debug.LogError("Must deactivate before activate module! Current activatedModule:" + m_activatedModule);
  245. return;
  246. }
  247. if (module == VRModuleActiveEnum.Uninitialized)
  248. {
  249. Debug.LogError("Activate module cannot be Uninitialized! Use DeactivateModule instead");
  250. return;
  251. }
  252. m_activatedModule = module;
  253. m_activatedModuleBase = m_modules[(int)module];
  254. m_activatedModuleBase.Activated();
  255. #if UNITY_2017_1_OR_NEWER
  256. Application.onBeforeRender += BeforeRenderUpdateModule;
  257. #else
  258. Camera.onPreCull += OnCameraPreCull;
  259. #endif
  260. InvokeActiveModuleChangedEvent(m_activatedModule);
  261. }
  262. #if !UNITY_2017_1_OR_NEWER
  263. private int m_preCullOnceFrame = -1;
  264. private void OnCameraPreCull(Camera cam)
  265. {
  266. var thisFrame = Time.frameCount;
  267. if (m_preCullOnceFrame == thisFrame) { return; }
  268. #if UNITY_5_5_OR_NEWER
  269. if ((cam.cameraType & (CameraType.Game | CameraType.VR)) == 0) { return; }
  270. #else
  271. if ((cam.cameraType & CameraType.Game) == 0) { return; }
  272. #endif
  273. m_preCullOnceFrame = thisFrame;
  274. BeforeRenderUpdateModule();
  275. }
  276. #endif
  277. private void BeforeRenderUpdateModule()
  278. {
  279. if (m_activatedModuleBase != null)
  280. {
  281. m_activatedModuleBase.BeforeRenderUpdate();
  282. }
  283. }
  284. private void DeactivateModule()
  285. {
  286. if (m_activatedModule == VRModuleActiveEnum.Uninitialized)
  287. {
  288. return;
  289. }
  290. if (m_activatedModuleBase == null)
  291. {
  292. return;
  293. }
  294. m_delayDeactivate = false;
  295. #if UNITY_2017_1_OR_NEWER
  296. Application.onBeforeRender -= BeforeRenderUpdateModule;
  297. #else
  298. Camera.onPreCull -= OnCameraPreCull;
  299. #endif
  300. DeviceState prevState;
  301. DeviceState currState;
  302. // copy status to from current state to previous state, and reset current state
  303. for (uint i = 0u, imax = GetDeviceStateLength(); i < imax; ++i)
  304. {
  305. if (!TryGetValidDeviceState(i, out prevState, out currState)) { continue; }
  306. if (prevState.isConnected || currState.isConnected)
  307. {
  308. prevState.CopyFrom(currState);
  309. currState.Reset();
  310. }
  311. }
  312. s_deviceSerialNumberTable.Clear();
  313. // send disconnect event
  314. SendAllDeviceConnectedEvent();
  315. var deactivatedModuleBase = m_activatedModuleBase;
  316. m_activatedModule = VRModuleActiveEnum.Uninitialized;
  317. m_activatedModuleBase = null;
  318. deactivatedModuleBase.Deactivated();
  319. InvokeActiveModuleChangedEvent(VRModuleActiveEnum.Uninitialized);
  320. }
  321. private void ModuleFlushDeviceState()
  322. {
  323. DeviceState prevState;
  324. DeviceState currState;
  325. // copy status to from current state to previous state
  326. for (uint i = 0u, imax = GetDeviceStateLength(); i < imax; ++i)
  327. {
  328. if (!TryGetValidDeviceState(i, out prevState, out currState)) { continue; }
  329. if (prevState.isConnected || currState.isConnected)
  330. {
  331. prevState.CopyFrom(currState);
  332. }
  333. }
  334. }
  335. private void ModuleConnectedDeviceChanged()
  336. {
  337. DeviceState prevState;
  338. DeviceState currState;
  339. m_delayDeactivate = true;
  340. // send connect/disconnect event
  341. for (uint i = 0u, imax = GetDeviceStateLength(); i < imax; ++i)
  342. {
  343. if (!TryGetValidDeviceState(i, out prevState, out currState)) { continue; }
  344. if (prevState.isConnected == currState.isConnected) { continue; }
  345. if (currState.isConnected)
  346. {
  347. if (string.IsNullOrEmpty(currState.serialNumber))
  348. {
  349. Debug.LogError("Device connected with empty serialNumber. index:" + i);
  350. }
  351. else if (s_deviceSerialNumberTable.ContainsKey(currState.serialNumber))
  352. {
  353. Debug.LogError("Device connected with duplicate serialNumber: " + currState.serialNumber + " index:" + i + "(" + s_deviceSerialNumberTable[currState.serialNumber] + ")");
  354. }
  355. else
  356. {
  357. s_deviceSerialNumberTable.Add(currState.serialNumber, i);
  358. }
  359. }
  360. else
  361. {
  362. s_deviceSerialNumberTable.Remove(prevState.serialNumber);
  363. }
  364. }
  365. SendAllDeviceConnectedEvent();
  366. m_delayDeactivate = false;
  367. if (m_isDestoryed)
  368. {
  369. DeactivateModule();
  370. }
  371. }
  372. private void SendAllDeviceConnectedEvent()
  373. {
  374. DeviceState prevState;
  375. DeviceState currState;
  376. for (uint i = 0u, imax = GetDeviceStateLength(); i < imax; ++i)
  377. {
  378. if (!TryGetValidDeviceState(i, out prevState, out currState)) { continue; }
  379. if (prevState.isConnected != currState.isConnected)
  380. {
  381. InvokeDeviceConnectedEvent(i, currState.isConnected);
  382. }
  383. }
  384. }
  385. }
  386. }