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.

121 lines
3.6 KiB

  1. using UnityEngine;
  2. using System.Collections;
  3. using System;
  4. using System.Collections.Generic;
  5. using Oculus.Avatar;
  6. public class OvrAvatarRemoteDriver : OvrAvatarDriver
  7. {
  8. Queue<OvrAvatarPacket> packetQueue = new Queue<OvrAvatarPacket>();
  9. IntPtr CurrentSDKPacket = IntPtr.Zero;
  10. float CurrentPacketTime = 0f;
  11. const int MinPacketQueue = 1;
  12. const int MaxPacketQueue = 4;
  13. int CurrentSequence = -1;
  14. // Used for legacy Unity only packet blending
  15. bool isStreaming = false;
  16. OvrAvatarPacket currentPacket = null;
  17. public void QueuePacket(int sequence, OvrAvatarPacket packet)
  18. {
  19. if (sequence > CurrentSequence)
  20. {
  21. CurrentSequence = sequence;
  22. packetQueue.Enqueue(packet);
  23. }
  24. }
  25. public override void UpdateTransforms(IntPtr sdkAvatar)
  26. {
  27. switch(Mode)
  28. {
  29. case PacketMode.SDK:
  30. UpdateFromSDKPacket(sdkAvatar);
  31. break;
  32. case PacketMode.Unity:
  33. UpdateFromUnityPacket(sdkAvatar);
  34. break;
  35. default:
  36. break;
  37. }
  38. }
  39. private void UpdateFromSDKPacket(IntPtr sdkAvatar)
  40. {
  41. if (CurrentSDKPacket == IntPtr.Zero && packetQueue.Count >= MinPacketQueue)
  42. {
  43. CurrentSDKPacket = packetQueue.Dequeue().ovrNativePacket;
  44. }
  45. if (CurrentSDKPacket != IntPtr.Zero)
  46. {
  47. float PacketDuration = CAPI.ovrAvatarPacket_GetDurationSeconds(CurrentSDKPacket);
  48. CAPI.ovrAvatar_UpdatePoseFromPacket(sdkAvatar, CurrentSDKPacket, Mathf.Min(PacketDuration, CurrentPacketTime));
  49. CurrentPacketTime += Time.deltaTime;
  50. if (CurrentPacketTime > PacketDuration)
  51. {
  52. CAPI.ovrAvatarPacket_Free(CurrentSDKPacket);
  53. CurrentSDKPacket = IntPtr.Zero;
  54. CurrentPacketTime = CurrentPacketTime - PacketDuration;
  55. //Throw away packets deemed too old.
  56. while (packetQueue.Count > MaxPacketQueue)
  57. {
  58. packetQueue.Dequeue();
  59. }
  60. }
  61. }
  62. }
  63. private void UpdateFromUnityPacket(IntPtr sdkAvatar)
  64. {
  65. // If we're not currently streaming, check to see if we've buffered enough
  66. if (!isStreaming && packetQueue.Count > MinPacketQueue)
  67. {
  68. currentPacket = packetQueue.Dequeue();
  69. isStreaming = true;
  70. }
  71. // If we are streaming, update our pose
  72. if (isStreaming)
  73. {
  74. CurrentPacketTime += Time.deltaTime;
  75. // If we've elapsed past our current packet, advance
  76. while (CurrentPacketTime > currentPacket.Duration)
  77. {
  78. // If we're out of packets, stop streaming and
  79. // lock to the final frame
  80. if (packetQueue.Count == 0)
  81. {
  82. CurrentPose = currentPacket.FinalFrame;
  83. CurrentPacketTime = 0.0f;
  84. currentPacket = null;
  85. isStreaming = false;
  86. return;
  87. }
  88. while (packetQueue.Count > MaxPacketQueue)
  89. {
  90. packetQueue.Dequeue();
  91. }
  92. // Otherwise, dequeue the next packet
  93. CurrentPacketTime -= currentPacket.Duration;
  94. currentPacket = packetQueue.Dequeue();
  95. }
  96. // Compute the pose based on our current time offset in the packet
  97. CurrentPose = currentPacket.GetPoseFrame(CurrentPacketTime);
  98. UpdateTransformsFromPose(sdkAvatar);
  99. }
  100. }
  101. }