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.

890 lines
39 KiB

5 years ago
  1. //========= Copyright 2016-2020, HTC Corporation. All rights reserved. ===========
  2. #pragma warning disable 0649
  3. using HTC.UnityPlugin.Utility;
  4. using HTC.UnityPlugin.VRModuleManagement;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Runtime.InteropServices;
  8. using UnityEngine;
  9. #if VIU_OCULUSVR_AVATAR
  10. using Oculus.Avatar;
  11. #endif
  12. namespace HTC.UnityPlugin.Vive.OculusVRExtension
  13. {
  14. // Only works in playing mode
  15. public class VIUOculusVRRenderModel : MonoBehaviour
  16. {
  17. private struct ChildTransforms
  18. {
  19. public Transform root;
  20. public Transform attach;
  21. }
  22. // Name of the sub-object which represents the "local" coordinate space for each component.
  23. public const string LOCAL_TRANSFORM_NAME = "attach";
  24. public const string MODEL_OVERRIDE_WARNNING = "Model override is really only meant to be used in " +
  25. "the scene view for lining things up. Use tracked device " +
  26. "index instead to ensure the correct model is displayed for all users.";
  27. private const uint LEFT_INDEX = 1;
  28. private const uint RIGHT_INDEX = 2;
  29. [Tooltip(MODEL_OVERRIDE_WARNNING)]
  30. [SerializeField]
  31. private string m_modelOverride;
  32. [Tooltip("Shader to apply to model.")]
  33. [SerializeField]
  34. private Shader m_shaderOverride;
  35. [Tooltip("Update transforms of components at runtime to reflect user action.")]
  36. [SerializeField]
  37. private bool m_updateDynamically = true;
  38. private uint m_deviceIndex = VRModule.INVALID_DEVICE_INDEX;
  39. private MeshFilter m_meshFilter;
  40. private MeshRenderer m_meshRenderer;
  41. private IndexedTable<string, ChildTransforms> m_chilTransforms = new IndexedTable<string, ChildTransforms>();
  42. private IndexedTable<int, Material> m_materials = new IndexedTable<int, Material>();
  43. private HashSet<string> m_loadingRenderModels = new HashSet<string>();
  44. private bool m_isAppQuit;
  45. #if (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  46. private IntPtr sdkAvatar = IntPtr.Zero;
  47. private HashSet<UInt64> assetLoadingIds = new HashSet<UInt64>();
  48. private Dictionary<string, OvrAvatarComponent> trackedComponents =
  49. new Dictionary<string, OvrAvatarComponent>();
  50. private OvrAvatarTouchController ovrController;
  51. private int renderPartCount = 0;
  52. private Shader SurfaceShader;
  53. private Shader SurfaceShaderSelfOccluding;
  54. private List<OvrAvatarRenderComponent> RenderParts = new List<OvrAvatarRenderComponent>();
  55. private ovrAvatarHandInputState inputStateLeft;
  56. private ovrAvatarHandInputState inputStateRight;
  57. private bool firstSkinnedUpdate = true;
  58. private bool assetsFinishedLoading = false;
  59. private bool isMaterialInitilized = false;
  60. private bool isMeshInitilized = false;
  61. private ovrAvatarControllerType m_controllerType = ovrAvatarControllerType.Quest;
  62. #endif
  63. private string preferedModelName
  64. {
  65. get
  66. {
  67. if (!string.IsNullOrEmpty(m_modelOverride)) { return m_modelOverride; }
  68. #if UNITY_EDITOR
  69. if (!Application.isPlaying)
  70. {
  71. return string.Empty;
  72. }
  73. else
  74. #endif
  75. {
  76. return VRModule.GetCurrentDeviceState(m_deviceIndex).renderModelName;
  77. }
  78. }
  79. }
  80. private Shader preferedShader { get { return m_shaderOverride == null ? Shader.Find("Standard") : m_shaderOverride; } }
  81. public bool updateDynamically { get { return m_updateDynamically; } set { m_updateDynamically = value; } }
  82. public bool isLoadingModel { get { return m_loadingRenderModels.Count > 0; } }
  83. public string loadedModelName { get; private set; }
  84. public bool isModelLoaded { get { return !string.IsNullOrEmpty(loadedModelName); } }
  85. public Shader loadedShader { get; private set; }
  86. public string modelOverride
  87. {
  88. get
  89. {
  90. return m_modelOverride;
  91. }
  92. set
  93. {
  94. m_modelOverride = value;
  95. LoadPreferedModel();
  96. }
  97. }
  98. public Shader shaderOverride
  99. {
  100. get
  101. {
  102. return m_shaderOverride;
  103. }
  104. set
  105. {
  106. m_shaderOverride = value;
  107. SetPreferedShader();
  108. }
  109. }
  110. #if UNITY_EDITOR
  111. private void OnValidate()
  112. {
  113. if (Application.isPlaying)
  114. {
  115. UnityEditor.EditorApplication.delayCall += () =>
  116. {
  117. if (!m_isAppQuit && this != null && isActiveAndEnabled)
  118. {
  119. LoadPreferedModel();
  120. SetPreferedShader();
  121. }
  122. };
  123. }
  124. }
  125. #endif
  126. private void Update()
  127. {
  128. if (m_updateDynamically)
  129. {
  130. #if (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  131. if (sdkAvatar == IntPtr.Zero)
  132. {
  133. return;
  134. }
  135. if (m_deviceIndex == LEFT_INDEX)
  136. {
  137. inputStateLeft.transform.position = transform.position;
  138. inputStateLeft.transform.orientation = transform.rotation;
  139. inputStateLeft.transform.scale = transform.localScale;
  140. inputStateLeft.buttonMask = 0;
  141. inputStateLeft.touchMask = ovrAvatarTouch.Pointing | ovrAvatarTouch.ThumbUp;
  142. if (ViveInput.GetPress(HandRole.LeftHand, ControllerButton.AKey))
  143. {
  144. inputStateLeft.buttonMask |= ovrAvatarButton.One;
  145. }
  146. if (ViveInput.GetPress(HandRole.LeftHand, ControllerButton.BKey))
  147. {
  148. inputStateLeft.buttonMask |= ovrAvatarButton.Two;
  149. }
  150. if (ViveInput.GetPress(HandRole.LeftHand, ControllerButton.System))
  151. {
  152. inputStateLeft.buttonMask |= ovrAvatarButton.Three;
  153. }
  154. if (ViveInput.GetPress(HandRole.LeftHand, ControllerButton.Pad))
  155. {
  156. inputStateLeft.buttonMask |= ovrAvatarButton.Joystick;
  157. }
  158. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.AKeyTouch))
  159. {
  160. inputStateLeft.touchMask &= ~ovrAvatarTouch.ThumbUp;
  161. inputStateLeft.touchMask |= ovrAvatarTouch.One;
  162. }
  163. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.BkeyTouch))
  164. {
  165. inputStateLeft.touchMask &= ~ovrAvatarTouch.ThumbUp;
  166. inputStateLeft.touchMask |= ovrAvatarTouch.Two;
  167. }
  168. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.PadTouch))
  169. {
  170. inputStateLeft.touchMask &= ~ovrAvatarTouch.ThumbUp;
  171. inputStateLeft.touchMask |= ovrAvatarTouch.Joystick;
  172. }
  173. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.TriggerTouch))
  174. {
  175. inputStateLeft.touchMask &= ~ovrAvatarTouch.Pointing;
  176. inputStateLeft.touchMask |= ovrAvatarTouch.Index;
  177. }
  178. inputStateLeft.joystickX = ViveInput.GetAxis(HandRole.LeftHand, ControllerAxis.JoystickX);
  179. inputStateLeft.joystickY = ViveInput.GetAxis(HandRole.LeftHand, ControllerAxis.JoystickY);
  180. inputStateLeft.indexTrigger = ViveInput.GetAxis(HandRole.LeftHand, ControllerAxis.Trigger);
  181. inputStateLeft.handTrigger = ViveInput.GetAxis(HandRole.LeftHand, ControllerAxis.CapSenseGrip);
  182. inputStateLeft.isActive = true;
  183. }
  184. else if (m_deviceIndex == RIGHT_INDEX)
  185. {
  186. inputStateRight.transform.position = transform.position;
  187. inputStateRight.transform.orientation = transform.rotation;
  188. inputStateRight.transform.scale = transform.localScale;
  189. inputStateRight.buttonMask = 0;
  190. inputStateRight.touchMask = ovrAvatarTouch.Pointing | ovrAvatarTouch.ThumbUp;
  191. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.AKey))
  192. {
  193. inputStateRight.buttonMask |= ovrAvatarButton.One;
  194. }
  195. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.BKey))
  196. {
  197. inputStateRight.buttonMask |= ovrAvatarButton.Two;
  198. }
  199. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.Pad))
  200. {
  201. inputStateRight.buttonMask |= ovrAvatarButton.Joystick;
  202. }
  203. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.AKeyTouch))
  204. {
  205. inputStateRight.touchMask &= ~ovrAvatarTouch.ThumbUp;
  206. inputStateRight.touchMask |= ovrAvatarTouch.One;
  207. }
  208. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.BkeyTouch))
  209. {
  210. inputStateRight.touchMask &= ~ovrAvatarTouch.ThumbUp;
  211. inputStateRight.touchMask |= ovrAvatarTouch.Two;
  212. }
  213. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.PadTouch))
  214. {
  215. inputStateRight.touchMask &= ~ovrAvatarTouch.ThumbUp;
  216. inputStateRight.touchMask |= ovrAvatarTouch.Joystick;
  217. }
  218. if (ViveInput.GetPress(HandRole.RightHand, ControllerButton.TriggerTouch))
  219. {
  220. inputStateRight.touchMask &= ~ovrAvatarTouch.Pointing;
  221. inputStateRight.touchMask |= ovrAvatarTouch.Index;
  222. }
  223. inputStateRight.joystickX = ViveInput.GetAxis(HandRole.RightHand, ControllerAxis.JoystickX);
  224. inputStateRight.joystickY = ViveInput.GetAxis(HandRole.RightHand, ControllerAxis.JoystickY);
  225. inputStateRight.indexTrigger = ViveInput.GetAxis(HandRole.RightHand, ControllerAxis.Trigger);
  226. inputStateRight.handTrigger = ViveInput.GetAxis(HandRole.RightHand, ControllerAxis.CapSenseGrip);
  227. inputStateRight.isActive = true;
  228. }
  229. CAPI.ovrAvatarPose_UpdateHandsWithType(sdkAvatar, inputStateLeft, inputStateRight, m_controllerType);
  230. CAPI.ovrAvatarPose_Finalize(sdkAvatar, Time.deltaTime);
  231. #endif
  232. UpdateComponents();
  233. #if VIU_OCULUSVR_1_37_0_OR_NEWER && VIU_OCULUSVR_AVATAR
  234. if (m_deviceIndex == LEFT_INDEX)
  235. {
  236. ovrAvatarControllerComponent component = new ovrAvatarControllerComponent();
  237. if (CAPI.ovrAvatarPose_GetLeftControllerComponent(sdkAvatar, ref component))
  238. {
  239. UpdateAvatarComponent(component.renderComponent);
  240. }
  241. }
  242. else if (m_deviceIndex == RIGHT_INDEX)
  243. {
  244. ovrAvatarControllerComponent component = new ovrAvatarControllerComponent();
  245. if (CAPI.ovrAvatarPose_GetRightControllerComponent(sdkAvatar, ref component))
  246. {
  247. UpdateAvatarComponent(component.renderComponent);
  248. }
  249. }
  250. #endif
  251. }
  252. }
  253. private void OnEnable()
  254. {
  255. LoadPreferedModel();
  256. }
  257. private void OnDestroy()
  258. {
  259. ClearModel();
  260. }
  261. private void OnApplicationQuit()
  262. {
  263. m_isAppQuit = true;
  264. }
  265. public void ClearModel()
  266. {
  267. if (!isModelLoaded) { return; }
  268. if (m_meshRenderer != null) { Destroy(m_meshRenderer); }
  269. if (m_meshFilter != null) { Destroy(m_meshFilter); }
  270. for (int i = 0, imax = m_chilTransforms.Count; i < imax; ++i)
  271. {
  272. var c = m_chilTransforms.GetValueByIndex(i);
  273. if (c.root == null) { continue; }
  274. Destroy(c.root.gameObject);
  275. }
  276. m_chilTransforms.Clear();
  277. m_materials.Clear();
  278. loadedModelName = string.Empty;
  279. loadedShader = null;
  280. }
  281. private void SetPreferedShader()
  282. {
  283. SetShader(preferedShader);
  284. }
  285. private void SetShader(Shader newShader)
  286. {
  287. if (loadedShader == newShader) { return; }
  288. loadedShader = newShader;
  289. if (m_materials == null) { return; }
  290. for (int i = 0, imax = m_materials.Count; i < imax; ++i)
  291. {
  292. var mat = m_materials.GetValueByIndex(i);
  293. if (mat != null)
  294. {
  295. mat.shader = newShader;
  296. }
  297. }
  298. }
  299. private void LoadPreferedModel()
  300. {
  301. LoadModel(preferedModelName);
  302. }
  303. private void LoadModel(string renderModelName)
  304. {
  305. //Debug.Log(transform.parent.parent.name + " Try LoadModel " + renderModelName);
  306. #if UNITY_EDITOR
  307. if (!Application.isPlaying)
  308. {
  309. Debug.LogWarning("LoadModel failed! This function only works in playing mode");
  310. return;
  311. }
  312. #endif
  313. if (string.IsNullOrEmpty(loadedModelName) && string.IsNullOrEmpty(renderModelName)) { return; }
  314. if (loadedModelName == renderModelName) { return; }
  315. if (m_loadingRenderModels.Contains(renderModelName)) { return; }
  316. ClearModel();
  317. if (!m_isAppQuit && !string.IsNullOrEmpty(renderModelName))
  318. {
  319. //Debug.Log(transform.parent.parent.name + " LoadModel " + renderModelName);
  320. m_loadingRenderModels.Add(renderModelName);
  321. #if VIU_OCULUSVR_1_37_0_OR_NEWER && VIU_OCULUSVR_AVATAR
  322. OvrAvatarSDKManager.AvatarSpecRequestParams avatarSpecRequest = new OvrAvatarSDKManager.AvatarSpecRequestParams(
  323. 0,
  324. this.AvatarSpecificationCallback,
  325. false,
  326. ovrAvatarAssetLevelOfDetail.Highest,
  327. false,
  328. ovrAvatarLookAndFeelVersion.Two,
  329. ovrAvatarLookAndFeelVersion.One,
  330. false);
  331. OvrAvatarSDKManager.Instance.RequestAvatarSpecification(avatarSpecRequest);
  332. #elif VIU_OCULUSVR_1_36_0_OR_NEWER && VIU_OCULUSVR_AVATAR
  333. OvrAvatarSDKManager.Instance.RequestAvatarSpecification(
  334. 0,
  335. this.AvatarSpecificationCallback,
  336. false,
  337. ovrAvatarAssetLevelOfDetail.Highest,
  338. false,
  339. ovrAvatarLookAndFeelVersion.Two,
  340. ovrAvatarLookAndFeelVersion.One,
  341. false);
  342. #elif VIU_OCULUSVR_1_32_0_OR_NEWER && VIU_OCULUSVR_AVATAR
  343. OvrAvatarSDKManager.Instance.RequestAvatarSpecification(
  344. 0,
  345. this.AvatarSpecificationCallback,
  346. false,
  347. ovrAvatarAssetLevelOfDetail.Highest,
  348. false);
  349. #endif
  350. }
  351. }
  352. private void AvatarSpecificationCallback(IntPtr avatarSpecification)
  353. {
  354. #if (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  355. sdkAvatar = CAPI.ovrAvatar_Create(avatarSpecification, ovrAvatarCapabilities.All);
  356. CAPI.ovrAvatar_SetLeftControllerVisibility(sdkAvatar, true);
  357. CAPI.ovrAvatar_SetRightControllerVisibility(sdkAvatar, true);
  358. //Fetch all the assets that this avatar uses.
  359. UInt32 assetCount = CAPI.ovrAvatar_GetReferencedAssetCount(sdkAvatar);
  360. for (UInt32 i = 0; i < assetCount; ++i)
  361. {
  362. UInt64 id = CAPI.ovrAvatar_GetReferencedAsset(sdkAvatar, i);
  363. if (OvrAvatarSDKManager.Instance.GetAsset(id) == null)
  364. {
  365. OvrAvatarSDKManager.Instance.BeginLoadingAsset(
  366. id,
  367. ovrAvatarAssetLevelOfDetail.Highest,
  368. AssetLoadedCallback);
  369. assetLoadingIds.Add(id);
  370. }
  371. }
  372. #endif
  373. }
  374. #if (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  375. private void AssetLoadedCallback(OvrAvatarAsset asset)
  376. {
  377. assetLoadingIds.Remove(asset.assetID);
  378. }
  379. #endif
  380. private void OnLoadModelComplete(string renderModelName)
  381. {
  382. m_loadingRenderModels.Remove(renderModelName);
  383. if (loadedModelName == renderModelName) { return; }
  384. if (preferedModelName != renderModelName) { return; }
  385. if (!isActiveAndEnabled) { return; }
  386. //Debug.Log(transform.parent.parent.name + " OnLoadModelComplete " + renderModelName);
  387. ClearModel();
  388. loadedModelName = renderModelName;
  389. }
  390. private void UpdateComponents()
  391. {
  392. #if (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  393. if (assetLoadingIds.Count == 0)
  394. {
  395. if (!assetsFinishedLoading)
  396. {
  397. UpdateSDKAvatarUnityState();
  398. assetsFinishedLoading = true;
  399. }
  400. }
  401. #endif
  402. }
  403. #if (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  404. private void UpdateSDKAvatarUnityState()
  405. {
  406. #if VIU_OCULUSVR_1_37_0_OR_NEWER && VIU_OCULUSVR_AVATAR
  407. ovrAvatarControllerComponent controllerComponent = new ovrAvatarControllerComponent();
  408. ovrAvatarComponent dummyComponent = new ovrAvatarComponent();
  409. OvrAvatarTouchController controller = null;
  410. if (m_deviceIndex == LEFT_INDEX)
  411. {
  412. if (CAPI.ovrAvatarPose_GetLeftControllerComponent(sdkAvatar, ref controllerComponent))
  413. {
  414. CAPI.ovrAvatarComponent_Get(controllerComponent.renderComponent, true, ref dummyComponent);
  415. AddAvatarComponent(ref controller, dummyComponent);
  416. controller.isLeftHand = true;
  417. }
  418. }
  419. else if (m_deviceIndex == RIGHT_INDEX)
  420. {
  421. if (CAPI.ovrAvatarPose_GetRightControllerComponent(sdkAvatar, ref controllerComponent))
  422. {
  423. CAPI.ovrAvatarComponent_Get(controllerComponent.renderComponent, true, ref dummyComponent);
  424. AddAvatarComponent(ref controller, dummyComponent);
  425. controller.isLeftHand = false;
  426. }
  427. }
  428. #elif (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  429. //Iterate through all the render components
  430. UInt32 componentCount = CAPI.ovrAvatarComponent_Count(sdkAvatar);
  431. for (UInt32 i = 0; i < componentCount; i++)
  432. {
  433. IntPtr ptr = CAPI.ovrAvatarComponent_Get_Native(sdkAvatar, i);
  434. ovrAvatarComponent component = (ovrAvatarComponent)Marshal.PtrToStructure(ptr, typeof(ovrAvatarComponent));
  435. if (!trackedComponents.ContainsKey(component.name))
  436. {
  437. GameObject componentObject = null;
  438. Type specificType = null;
  439. if (specificType == null && (ovrAvatarCapabilities.All & ovrAvatarCapabilities.Hands) != 0)
  440. {
  441. if (m_deviceIndex == LEFT_INDEX)
  442. {
  443. ovrAvatarControllerComponent? controllerComponent = CAPI.ovrAvatarPose_GetLeftControllerComponent(sdkAvatar);
  444. if (specificType == null && controllerComponent.HasValue && ptr == controllerComponent.Value.renderComponent)
  445. {
  446. specificType = typeof(OvrAvatarTouchController);
  447. if (ovrController != null)
  448. {
  449. componentObject = ovrController.gameObject;
  450. }
  451. }
  452. }
  453. else if (m_deviceIndex == RIGHT_INDEX)
  454. {
  455. ovrAvatarControllerComponent? controllerComponent = CAPI.ovrAvatarPose_GetRightControllerComponent(sdkAvatar);
  456. if (specificType == null && controllerComponent.HasValue && ptr == controllerComponent.Value.renderComponent)
  457. {
  458. specificType = typeof(OvrAvatarTouchController);
  459. if (ovrController != null)
  460. {
  461. componentObject = ovrController.gameObject;
  462. }
  463. }
  464. }
  465. }
  466. if (componentObject != null)
  467. {
  468. AddAvatarComponent(componentObject, component);
  469. }
  470. }
  471. UpdateAvatarComponent(component);
  472. }
  473. #endif
  474. }
  475. #if VIU_OCULUSVR_1_37_0_OR_NEWER && VIU_OCULUSVR_AVATAR
  476. private void AddAvatarComponent<T>(ref T root, ovrAvatarComponent nativeComponent) where T : OvrAvatarComponent
  477. {
  478. GameObject componentObject = new GameObject();
  479. componentObject.name = nativeComponent.name;
  480. componentObject.transform.SetParent(transform);
  481. root = componentObject.AddComponent<T>();
  482. AddRenderParts(root, nativeComponent, componentObject.transform);
  483. }
  484. #elif VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER
  485. private void AddAvatarComponent(GameObject componentObject, ovrAvatarComponent component)
  486. {
  487. OvrAvatarComponent ovrComponent = componentObject.AddComponent<OvrAvatarComponent>();
  488. trackedComponents.Add(component.name, ovrComponent);
  489. AddRenderParts(ovrComponent, component, componentObject.transform);
  490. }
  491. #endif
  492. private void AddRenderParts(
  493. OvrAvatarComponent ovrComponent,
  494. ovrAvatarComponent component,
  495. Transform parent)
  496. {
  497. for (UInt32 renderPartIndex = 0; renderPartIndex < component.renderPartCount; renderPartIndex++)
  498. {
  499. GameObject renderPartObject = new GameObject();
  500. renderPartObject.name = GetRenderPartName(component, renderPartIndex);
  501. renderPartObject.transform.SetParent(parent);
  502. renderPartObject.transform.localPosition = Vector2.zero;
  503. renderPartObject.transform.localRotation = Quaternion.identity;
  504. IntPtr renderPart = GetRenderPart(component, renderPartIndex);
  505. ovrAvatarRenderPartType type = CAPI.ovrAvatarRenderPart_GetType(renderPart);
  506. OvrAvatarRenderComponent ovrRenderPart = null;
  507. switch (type)
  508. {
  509. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
  510. ovrRenderPart = AddSkinnedMeshRenderPBSComponent(renderPartObject, CAPI.ovrAvatarRenderPart_GetSkinnedMeshRenderPBS(renderPart));
  511. break;
  512. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
  513. ovrRenderPart = AddSkinnedMeshRenderPBSV2Component(renderPartObject, CAPI.ovrAvatarRenderPart_GetSkinnedMeshRenderPBSV2(renderPart));
  514. break;
  515. default:
  516. break;// throw new NotImplementedException(string.Format("Unsupported render part type: {0}", type.ToString()));
  517. }
  518. if (ovrRenderPart != null)
  519. {
  520. ovrComponent.RenderParts.Add(ovrRenderPart);
  521. RenderParts.Add(ovrRenderPart);
  522. }
  523. }
  524. }
  525. private OvrAvatarSkinnedMeshRenderPBSComponent AddSkinnedMeshRenderPBSComponent(GameObject gameObject, ovrAvatarRenderPart_SkinnedMeshRenderPBS skinnedMeshRenderPBS)
  526. {
  527. OvrAvatarSkinnedMeshRenderPBSComponent skinnedMeshRenderer = gameObject.AddComponent<OvrAvatarSkinnedMeshRenderPBSComponent>();
  528. OvrAvatarAssetMesh meshAsset = (OvrAvatarAssetMesh)OvrAvatarSDKManager.Instance.GetAsset(skinnedMeshRenderPBS.meshAssetID);
  529. SkinnedMeshRenderer renderer = meshAsset.CreateSkinnedMeshRendererOnObject(gameObject);
  530. #if UNITY_ANDROID
  531. renderer.quality = SkinQuality.Bone2;
  532. #else
  533. renderer.quality = SkinQuality.Bone4;
  534. #endif
  535. renderer.updateWhenOffscreen = true;
  536. skinnedMeshRenderer.mesh = renderer;
  537. transform.GetChild(0).localPosition = Vector2.zero;
  538. transform.GetChild(0).localRotation = Quaternion.identity;
  539. transform.GetChild(0).GetComponentInChildren<OvrAvatarSkinnedMeshRenderPBSComponent>().gameObject.SetActive(false);
  540. var shader = Shader.Find("OvrAvatar/AvatarSurfaceShaderPBS");
  541. renderer.sharedMaterial = CreateAvatarMaterial(gameObject.name + "_material", shader);
  542. SetMaterialOpaque(renderer.sharedMaterial);
  543. skinnedMeshRenderer.bones = renderer.bones;
  544. return skinnedMeshRenderer;
  545. }
  546. private OvrAvatarSkinnedMeshPBSV2RenderComponent AddSkinnedMeshRenderPBSV2Component(GameObject gameObject, ovrAvatarRenderPart_SkinnedMeshRenderPBS_V2 skinnedMeshRenderPBSV2)
  547. {
  548. OvrAvatarSkinnedMeshPBSV2RenderComponent skinnedMeshRenderer = gameObject.AddComponent<OvrAvatarSkinnedMeshPBSV2RenderComponent>();
  549. OvrAvatarAssetMesh meshAsset = (OvrAvatarAssetMesh)OvrAvatarSDKManager.Instance.GetAsset(skinnedMeshRenderPBSV2.meshAssetID);
  550. SkinnedMeshRenderer renderer = meshAsset.CreateSkinnedMeshRendererOnObject(gameObject);
  551. #if UNITY_ANDROID
  552. renderer.quality = SkinQuality.Bone2;
  553. #else
  554. renderer.quality = SkinQuality.Bone4;
  555. #endif
  556. renderer.updateWhenOffscreen = true;
  557. skinnedMeshRenderer.mesh = renderer;
  558. transform.GetChild(0).localPosition = Vector2.zero;
  559. transform.GetChild(0).localRotation = Quaternion.identity;
  560. transform.GetChild(0).GetComponentInChildren<OvrAvatarSkinnedMeshPBSV2RenderComponent>().gameObject.SetActive(false);
  561. var shader = Shader.Find("OvrAvatar/AvatarPBRV2Simple");
  562. renderer.sharedMaterial = CreateAvatarMaterial(gameObject.name + "_material", shader);
  563. SetMaterialOpaque(renderer.sharedMaterial);
  564. skinnedMeshRenderer.bones = renderer.bones;
  565. return skinnedMeshRenderer;
  566. }
  567. private Material CreateAvatarMaterial(string name, Shader shader)
  568. {
  569. if (shader == null)
  570. {
  571. throw new Exception("No shader provided for avatar material.");
  572. }
  573. Material mat = new Material(shader);
  574. mat.name = name;
  575. return mat;
  576. }
  577. private void SetMaterialOpaque(Material mat)
  578. {
  579. // Initialize shader to use geometry render queue with no blending
  580. mat.SetOverrideTag("Queue", "Geometry");
  581. mat.SetOverrideTag("RenderType", "Opaque");
  582. mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
  583. mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
  584. mat.DisableKeyword("_ALPHATEST_ON");
  585. mat.DisableKeyword("_ALPHABLEND_ON");
  586. mat.DisableKeyword("_ALPHAPREMULTIPLY_ON");
  587. mat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
  588. }
  589. private static string GetRenderPartName(ovrAvatarComponent component, uint renderPartIndex)
  590. {
  591. return component.name + "_renderPart_" + (int)renderPartIndex;
  592. }
  593. static public IntPtr GetRenderPart(ovrAvatarComponent component, UInt32 renderPartIndex)
  594. {
  595. long offset = Marshal.SizeOf(typeof(IntPtr)) * renderPartIndex;
  596. IntPtr marshalPtr = new IntPtr(component.renderParts.ToInt64() + offset);
  597. return (IntPtr)Marshal.PtrToStructure(marshalPtr, typeof(IntPtr));
  598. }
  599. #if VIU_OCULUSVR_1_37_0_OR_NEWER
  600. private void UpdateAvatarComponent(IntPtr nativeComponent)
  601. {
  602. ovrAvatarComponent nativeAvatarComponent = new ovrAvatarComponent();
  603. CAPI.ovrAvatarComponent_Get(nativeComponent, false, ref nativeAvatarComponent);
  604. ConvertTransform(nativeAvatarComponent.transform, transform);
  605. for (UInt32 renderPartIndex = 0; renderPartIndex < nativeAvatarComponent.renderPartCount; renderPartIndex++)
  606. {
  607. if (RenderParts.Count <= renderPartIndex)
  608. {
  609. break;
  610. }
  611. OvrAvatarRenderComponent renderComponent = RenderParts[(int)renderPartIndex];
  612. IntPtr renderPart = OvrAvatar.GetRenderPart(nativeAvatarComponent, renderPartIndex);
  613. ovrAvatarRenderPartType type = CAPI.ovrAvatarRenderPart_GetType(renderPart);
  614. ovrAvatarTransform localTransform;
  615. ovrAvatarVisibilityFlags visibilityMask;
  616. var mesh = renderComponent.mesh;
  617. var bones = renderComponent.bones;
  618. switch (type)
  619. {
  620. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
  621. visibilityMask = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetVisibilityMask(renderPart);
  622. localTransform = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetTransform(renderPart);
  623. if ((visibilityMask & ovrAvatarVisibilityFlags.FirstPerson) != 0)
  624. {
  625. renderComponent.gameObject.SetActive(true);
  626. mesh.enabled = true;
  627. }
  628. UpdateSkinnedMesh(localTransform, renderPart, bones);
  629. UInt64 albedoTextureID = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetAlbedoTextureAssetID(renderPart);
  630. UInt64 surfaceTextureID = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetSurfaceTextureAssetID(renderPart);
  631. mesh.sharedMaterial.SetTexture("_Albedo", OvrAvatarComponent.GetLoadedTexture(albedoTextureID));
  632. mesh.sharedMaterial.SetTexture("_Surface", OvrAvatarComponent.GetLoadedTexture(surfaceTextureID));
  633. break;
  634. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
  635. visibilityMask = CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetVisibilityMask(renderPart);
  636. localTransform = CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetTransform(renderPart);
  637. if ((visibilityMask & ovrAvatarVisibilityFlags.FirstPerson) != 0)
  638. {
  639. renderComponent.gameObject.SetActive(true);
  640. mesh.enabled = true;
  641. }
  642. UpdateSkinnedMesh(localTransform, renderPart, bones);
  643. ovrAvatarPBSMaterialState materialState =
  644. CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetPBSMaterialState(renderPart);
  645. Texture2D diffuseTexture = OvrAvatarComponent.GetLoadedTexture(materialState.albedoTextureID);
  646. Texture2D normalTexture = OvrAvatarComponent.GetLoadedTexture(materialState.normalTextureID);
  647. Texture2D metallicTexture = OvrAvatarComponent.GetLoadedTexture(materialState.metallicnessTextureID);
  648. mesh.materials[0].SetTexture("_MainTex", diffuseTexture);
  649. mesh.materials[0].SetTexture("_NormalMap", normalTexture);
  650. mesh.materials[0].SetTexture("_RoughnessMap", metallicTexture);
  651. break;
  652. default:
  653. break;
  654. }
  655. }
  656. }
  657. #elif VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER
  658. private void UpdateAvatarComponent(ovrAvatarComponent component)
  659. {
  660. for (UInt32 renderPartIndex = 0; renderPartIndex < component.renderPartCount; renderPartIndex++)
  661. {
  662. if (RenderParts.Count <= renderPartIndex)
  663. {
  664. break;
  665. }
  666. OvrAvatarRenderComponent renderComponent = RenderParts[(int)renderPartIndex];
  667. IntPtr renderPart = OvrAvatar.GetRenderPart(component, renderPartIndex);
  668. ovrAvatarRenderPartType type = CAPI.ovrAvatarRenderPart_GetType(renderPart);
  669. switch (type)
  670. {
  671. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
  672. var mat = renderComponent.mesh.sharedMaterial;
  673. var bones = renderComponent.bones;
  674. ovrAvatarVisibilityFlags visibilityMask = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetVisibilityMask(renderPart);
  675. ovrAvatarTransform localTransform = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetTransform(renderPart);
  676. UpdateSkinnedMesh(localTransform, renderPart, bones);
  677. UInt64 albedoTextureID = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetAlbedoTextureAssetID(renderPart);
  678. UInt64 surfaceTextureID = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetSurfaceTextureAssetID(renderPart);
  679. mat.SetTexture("_Albedo", OvrAvatarComponent.GetLoadedTexture(albedoTextureID));
  680. mat.SetTexture("_Surface", OvrAvatarComponent.GetLoadedTexture(surfaceTextureID));
  681. break;
  682. default:
  683. break;
  684. }
  685. }
  686. }
  687. #endif
  688. private void UpdateSkinnedMesh(ovrAvatarTransform localTransform, IntPtr renderPart, Transform[] bones)
  689. {
  690. ConvertTransform(localTransform, transform);
  691. ovrAvatarRenderPartType type = CAPI.ovrAvatarRenderPart_GetType(renderPart);
  692. UInt64 dirtyJoints;
  693. switch (type)
  694. {
  695. case ovrAvatarRenderPartType.SkinnedMeshRender:
  696. dirtyJoints = CAPI.ovrAvatarSkinnedMeshRender_GetDirtyJoints(renderPart);
  697. break;
  698. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
  699. dirtyJoints = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetDirtyJoints(renderPart);
  700. break;
  701. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
  702. dirtyJoints = CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetDirtyJoints(renderPart);
  703. break;
  704. default:
  705. throw new Exception("Unhandled render part type: " + type);
  706. }
  707. for (UInt32 i = 0; i < 64; i++)
  708. {
  709. UInt64 dirtyMask = (ulong)1 << (int)i;
  710. // We need to make sure that we fully update the initial position of
  711. // Skinned mesh renderers, then, thereafter, we can only update dirty joints
  712. if ((firstSkinnedUpdate && i < bones.Length) ||
  713. (dirtyMask & dirtyJoints) != 0)
  714. {
  715. //This joint is dirty and needs to be updated
  716. Transform targetBone = bones[i];
  717. ovrAvatarTransform transform;
  718. switch (type)
  719. {
  720. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
  721. transform = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetJointTransform(renderPart, i);
  722. break;
  723. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
  724. transform = CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetJointTransform(renderPart, i);
  725. break;
  726. default:
  727. throw new Exception("Unhandled render part type: " + type);
  728. }
  729. ConvertTransform(transform, targetBone);
  730. }
  731. }
  732. firstSkinnedUpdate = false;
  733. }
  734. private void ConvertTransform(ovrAvatarTransform transform, Transform target)
  735. {
  736. Vector3 position = transform.position;
  737. position.z = -position.z;
  738. Quaternion orientation = transform.orientation;
  739. orientation.x = -orientation.x;
  740. orientation.y = -orientation.y;
  741. target.localPosition = position;
  742. target.localRotation = orientation;
  743. target.localScale = transform.scale;
  744. }
  745. #endif
  746. public void SetDeviceIndex(uint index)
  747. {
  748. //Debug.Log(transform.parent.parent.name + " SetDeviceIndex " + index);
  749. m_deviceIndex = index;
  750. #if (VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER) && VIU_OCULUSVR_AVATAR
  751. ovrController = this.GetComponent<OvrAvatarTouchController>();
  752. #endif
  753. #if VIU_OCULUSVR && VIU_OCULUSVR_AVATAR
  754. var headsetType = OVRPlugin.GetSystemHeadsetType();
  755. switch (headsetType)
  756. {
  757. #if !VIU_OCULUSVR_19_0_OR_NEWER
  758. case OVRPlugin.SystemHeadset.GearVR_R320:
  759. case OVRPlugin.SystemHeadset.GearVR_R321:
  760. case OVRPlugin.SystemHeadset.GearVR_R322:
  761. case OVRPlugin.SystemHeadset.GearVR_R323:
  762. case OVRPlugin.SystemHeadset.GearVR_R324:
  763. case OVRPlugin.SystemHeadset.GearVR_R325:
  764. m_controllerType = ovrAvatarControllerType.Malibu;
  765. break;
  766. case OVRPlugin.SystemHeadset.Oculus_Go:
  767. m_controllerType = ovrAvatarControllerType.Go;
  768. break;
  769. #endif
  770. #if VIU_OCULUSVR_16_0_OR_NEWER
  771. case OVRPlugin.SystemHeadset.Oculus_Link_Quest:
  772. #endif
  773. case OVRPlugin.SystemHeadset.Oculus_Quest:
  774. #if VIU_OCULUSVR_1_37_0_OR_NEWER
  775. case OVRPlugin.SystemHeadset.Rift_S:
  776. m_controllerType = ovrAvatarControllerType.Quest;
  777. break;
  778. #endif
  779. case OVRPlugin.SystemHeadset.Rift_DK1:
  780. case OVRPlugin.SystemHeadset.Rift_DK2:
  781. case OVRPlugin.SystemHeadset.Rift_CV1:
  782. default:
  783. m_controllerType = ovrAvatarControllerType.Touch;
  784. break;
  785. }
  786. #endif
  787. LoadPreferedModel();
  788. }
  789. }
  790. }