Assignment for RMIT Mixed Reality in 2020
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.

135 lines
5.2 KiB

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. using Oculus.Avatar;
  6. public class OvrAvatarRenderComponent : MonoBehaviour {
  7. private bool firstSkinnedUpdate = true;
  8. public SkinnedMeshRenderer mesh;
  9. public Transform[] bones;
  10. bool isBodyComponent = false;
  11. protected void UpdateActive(OvrAvatar avatar, ovrAvatarVisibilityFlags mask)
  12. {
  13. bool doActiveHack = isBodyComponent && avatar.EnableExpressive && avatar.ShowFirstPerson && !avatar.ShowThirdPerson;
  14. if (doActiveHack)
  15. {
  16. bool showFirstPerson = (mask & ovrAvatarVisibilityFlags.FirstPerson) != 0;
  17. bool showThirdPerson = (mask & ovrAvatarVisibilityFlags.ThirdPerson) != 0;
  18. gameObject.SetActive(showThirdPerson || showThirdPerson);
  19. if (!showFirstPerson)
  20. {
  21. mesh.enabled = false;
  22. }
  23. }
  24. else
  25. {
  26. bool active = avatar.ShowFirstPerson && (mask & ovrAvatarVisibilityFlags.FirstPerson) != 0;
  27. active |= avatar.ShowThirdPerson && (mask & ovrAvatarVisibilityFlags.ThirdPerson) != 0;
  28. this.gameObject.SetActive(active);
  29. mesh.enabled = active;
  30. }
  31. }
  32. protected SkinnedMeshRenderer CreateSkinnedMesh(ulong assetID, ovrAvatarVisibilityFlags visibilityMask, int thirdPersonLayer, int firstPersonLayer)
  33. {
  34. isBodyComponent = name.Contains("body");
  35. OvrAvatarAssetMesh meshAsset = (OvrAvatarAssetMesh)OvrAvatarSDKManager.Instance.GetAsset(assetID);
  36. if (meshAsset == null)
  37. {
  38. throw new Exception("Couldn't find mesh for asset " + assetID);
  39. }
  40. if ((visibilityMask & ovrAvatarVisibilityFlags.ThirdPerson) != 0)
  41. {
  42. this.gameObject.layer = thirdPersonLayer;
  43. }
  44. else
  45. {
  46. this.gameObject.layer = firstPersonLayer;
  47. }
  48. SkinnedMeshRenderer renderer = meshAsset.CreateSkinnedMeshRendererOnObject(gameObject);
  49. #if UNITY_ANDROID
  50. renderer.quality = SkinQuality.Bone2;
  51. #else
  52. renderer.quality = SkinQuality.Bone4;
  53. #endif
  54. renderer.updateWhenOffscreen = true;
  55. if ((visibilityMask & ovrAvatarVisibilityFlags.SelfOccluding) == 0)
  56. {
  57. renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
  58. }
  59. gameObject.SetActive(false);
  60. return renderer;
  61. }
  62. protected void UpdateSkinnedMesh(OvrAvatar avatar, Transform[] bones, ovrAvatarTransform localTransform, ovrAvatarVisibilityFlags visibilityMask, IntPtr renderPart)
  63. {
  64. UpdateActive(avatar, visibilityMask);
  65. OvrAvatar.ConvertTransform(localTransform, this.transform);
  66. ovrAvatarRenderPartType type = CAPI.ovrAvatarRenderPart_GetType(renderPart);
  67. UInt64 dirtyJoints;
  68. switch (type)
  69. {
  70. case ovrAvatarRenderPartType.SkinnedMeshRender:
  71. dirtyJoints = CAPI.ovrAvatarSkinnedMeshRender_GetDirtyJoints(renderPart);
  72. break;
  73. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
  74. dirtyJoints = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetDirtyJoints(renderPart);
  75. break;
  76. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
  77. dirtyJoints = CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetDirtyJoints(renderPart);
  78. break;
  79. default:
  80. throw new Exception("Unhandled render part type: " + type);
  81. }
  82. for (UInt32 i = 0; i < 64; i++)
  83. {
  84. UInt64 dirtyMask = (ulong)1 << (int)i;
  85. // We need to make sure that we fully update the initial position of
  86. // Skinned mesh renderers, then, thereafter, we can only update dirty joints
  87. if ((firstSkinnedUpdate && i < bones.Length) ||
  88. (dirtyMask & dirtyJoints) != 0)
  89. {
  90. //This joint is dirty and needs to be updated
  91. Transform targetBone = bones[i];
  92. ovrAvatarTransform transform;
  93. switch (type)
  94. {
  95. case ovrAvatarRenderPartType.SkinnedMeshRender:
  96. transform = CAPI.ovrAvatarSkinnedMeshRender_GetJointTransform(renderPart, i);
  97. break;
  98. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
  99. transform = CAPI.ovrAvatarSkinnedMeshRenderPBS_GetJointTransform(renderPart, i);
  100. break;
  101. case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
  102. transform = CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetJointTransform(renderPart, i);
  103. break;
  104. default:
  105. throw new Exception("Unhandled render part type: " + type);
  106. }
  107. OvrAvatar.ConvertTransform(transform, targetBone);
  108. }
  109. }
  110. firstSkinnedUpdate = false;
  111. }
  112. protected Material CreateAvatarMaterial(string name, Shader shader)
  113. {
  114. if (shader == null)
  115. {
  116. throw new Exception("No shader provided for avatar material.");
  117. }
  118. Material mat = new Material(shader);
  119. mat.name = name;
  120. return mat;
  121. }
  122. }