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