162 lines
4.7 KiB
C#
162 lines
4.7 KiB
C#
using System;
|
|
using Oculus.Platform.Models;
|
|
using UnityEngine;
|
|
|
|
namespace Oculus.Platform.Samples.VrVoiceChat
|
|
{
|
|
public class P2PManager
|
|
{
|
|
private static readonly float UPDATE_DELAY = 0.1f;
|
|
|
|
private ulong m_remoteID;
|
|
|
|
private PeerConnectionState m_state;
|
|
|
|
private float m_timeForNextUpdate;
|
|
|
|
private static readonly byte PACKET_SIZE = 29;
|
|
|
|
private static readonly byte PACKET_FORMAT;
|
|
|
|
private readonly byte[] sendTransformBuffer = new byte[PACKET_SIZE];
|
|
|
|
private readonly byte[] receiveTransformBuffer = new byte[PACKET_SIZE];
|
|
|
|
private Vector3 receivedPosition;
|
|
|
|
private Vector3 receivedPositionPrior;
|
|
|
|
private Quaternion receivedRotation;
|
|
|
|
private Quaternion receivedRotationPrior;
|
|
|
|
private float receivedTime;
|
|
|
|
public bool Connected
|
|
{
|
|
get
|
|
{
|
|
return m_state == PeerConnectionState.Connected;
|
|
}
|
|
}
|
|
|
|
public bool ShouldSendHeadUpdate
|
|
{
|
|
get
|
|
{
|
|
return Time.time >= m_timeForNextUpdate && m_state == PeerConnectionState.Connected;
|
|
}
|
|
}
|
|
|
|
public P2PManager(Transform initialHeadTransform)
|
|
{
|
|
receivedPositionPrior = (receivedPosition = initialHeadTransform.localPosition);
|
|
receivedRotationPrior = (receivedRotation = initialHeadTransform.localRotation);
|
|
Net.SetPeerConnectRequestCallback(PeerConnectRequestCallback);
|
|
Net.SetConnectionStateChangedCallback(ConnectionStateChangedCallback);
|
|
}
|
|
|
|
public void ConnectTo(ulong userID)
|
|
{
|
|
m_remoteID = userID;
|
|
if (PlatformManager.MyID < userID)
|
|
{
|
|
Net.Connect(userID);
|
|
}
|
|
}
|
|
|
|
public void Disconnect()
|
|
{
|
|
if (m_remoteID != 0)
|
|
{
|
|
Net.Close(m_remoteID);
|
|
m_remoteID = 0uL;
|
|
m_state = PeerConnectionState.Unknown;
|
|
}
|
|
}
|
|
|
|
private void PeerConnectRequestCallback(Message<Oculus.Platform.Models.NetworkingPeer> msg)
|
|
{
|
|
Debug.LogFormat("Connection request from {0}, authorized is {1}", msg.Data.ID, m_remoteID);
|
|
if (msg.Data.ID == m_remoteID)
|
|
{
|
|
Net.Accept(msg.Data.ID);
|
|
}
|
|
}
|
|
|
|
private void ConnectionStateChangedCallback(Message<Oculus.Platform.Models.NetworkingPeer> msg)
|
|
{
|
|
Debug.LogFormat("Connection state to {0} changed to {1}", msg.Data.ID, msg.Data.State);
|
|
if (msg.Data.ID == m_remoteID)
|
|
{
|
|
m_state = msg.Data.State;
|
|
if (m_state == PeerConnectionState.Timeout && PlatformManager.MyID < m_remoteID)
|
|
{
|
|
Net.Connect(m_remoteID);
|
|
}
|
|
}
|
|
PlatformManager.SetBackgroundColorForState();
|
|
}
|
|
|
|
public void SendHeadTransform(Transform headTransform)
|
|
{
|
|
m_timeForNextUpdate = Time.time + UPDATE_DELAY;
|
|
sendTransformBuffer[0] = PACKET_FORMAT;
|
|
int offset = 1;
|
|
PackFloat(headTransform.localPosition.x, sendTransformBuffer, ref offset);
|
|
PackFloat(headTransform.localPosition.y, sendTransformBuffer, ref offset);
|
|
PackFloat(headTransform.localPosition.z, sendTransformBuffer, ref offset);
|
|
PackFloat(headTransform.localRotation.x, sendTransformBuffer, ref offset);
|
|
PackFloat(headTransform.localRotation.y, sendTransformBuffer, ref offset);
|
|
PackFloat(headTransform.localRotation.z, sendTransformBuffer, ref offset);
|
|
PackFloat(headTransform.localRotation.w, sendTransformBuffer, ref offset);
|
|
Net.SendPacket(m_remoteID, sendTransformBuffer, SendPolicy.Unreliable);
|
|
}
|
|
|
|
private void PackFloat(float f, byte[] buf, ref int offset)
|
|
{
|
|
Buffer.BlockCopy(BitConverter.GetBytes(f), 0, buf, offset, 4);
|
|
offset += 4;
|
|
}
|
|
|
|
public void GetRemoteHeadTransform(Transform headTransform)
|
|
{
|
|
bool flag = false;
|
|
Packet packet;
|
|
while ((packet = Net.ReadPacket()) != null)
|
|
{
|
|
if (packet.Size != PACKET_SIZE)
|
|
{
|
|
Debug.Log("Invalid packet size: " + packet.Size);
|
|
continue;
|
|
}
|
|
packet.ReadBytes(receiveTransformBuffer);
|
|
if (receiveTransformBuffer[0] != PACKET_FORMAT)
|
|
{
|
|
Debug.Log("Invalid packet type: " + packet.Size);
|
|
}
|
|
else
|
|
{
|
|
flag = true;
|
|
}
|
|
}
|
|
if (flag)
|
|
{
|
|
receivedPositionPrior = receivedPosition;
|
|
receivedPosition.x = BitConverter.ToSingle(receiveTransformBuffer, 1);
|
|
receivedPosition.y = BitConverter.ToSingle(receiveTransformBuffer, 5);
|
|
receivedPosition.z = BitConverter.ToSingle(receiveTransformBuffer, 9);
|
|
receivedRotationPrior = receivedRotation;
|
|
receivedRotation.x = BitConverter.ToSingle(receiveTransformBuffer, 13);
|
|
receivedRotation.y = BitConverter.ToSingle(receiveTransformBuffer, 17) * -1f;
|
|
receivedRotation.z = BitConverter.ToSingle(receiveTransformBuffer, 21);
|
|
receivedRotation.w = BitConverter.ToSingle(receiveTransformBuffer, 25) * -1f;
|
|
receivedTime = Time.time;
|
|
}
|
|
float t = Math.Min(Time.time - receivedTime, UPDATE_DELAY) / UPDATE_DELAY;
|
|
headTransform.localPosition = Vector3.Lerp(receivedPositionPrior, receivedPosition, t);
|
|
headTransform.localRotation = Quaternion.Slerp(receivedRotationPrior, receivedRotation, t);
|
|
}
|
|
}
|
|
}
|