04-15-2017 03:36 PM
using UnityEngine;using System.Collections;using System.Collections.Generic;using System;using System.IO;
public class RemoteLoopbackManager : MonoBehaviour {
public OvrAvatar LocalAvatar; public OvrAvatar LoopbackAvatar; public String fName = "C:\\temp\\Recording.avs"; public Boolean recording = true; int offset = 0; float startTime; FileStream file; Dictionary<string, object> animationFrame; int packetSequence = 0;
// Use this for initialization void Start () {
LocalAvatar.RecordPackets = recording; if (recording) { // recording mode LocalAvatar.PacketRecorded += OnLocalAvatarPacketRecorded; File.Delete(fName); file = new FileStream(fName, FileMode.CreateNew); } else { // playback mode file = new FileStream(fName, FileMode.Open); }
initPlayback();
} void Update() { if (recording) return; // bail out, nothing to record
////////////////////////////////////////////////////// // if we are still here, then we are playing back! ////////////////////////////////////////////////////// if (animationFrame == null) animationFrame = ReadAnimationFrame();
var currentTime = Time.time - startTime; var animationTime = (double)animationFrame["time"];
if (animationTime > currentTime) { Debug.Log("Not playing yet " + animationTime + " " + currentTime); return; }
PlaybackPacketData((byte[])animationFrame["data"]); // reset frame animationFrame = null;
}
Dictionary<string, object> ReadAnimationFrame() { ///////////////////////////////////////////////////////////////////////////////////////////// // from hereon, we play back... ///////////////////////////////////////////////////////////////////////////////////////////// // read frameSize ///////////////////////////////////////////////////////////////////////////////////////////// var frameSize = new byte[sizeof(int)]; offset += file.Read(frameSize, 0, frameSize.Length);
///////////////////////////////////////////////////////////////////////////////////////////// // read frameTime ///////////////////////////////////////////////////////////////////////////////////////////// var frameTime = new byte[sizeof(double)]; offset += file.Read(frameTime, 0, frameTime.Length);
var animationTime = BitConverter.ToDouble(frameTime, 0);
var frameContent = new byte[BitConverter.ToInt32(frameSize, 0)];
// read in frameSize bytes of data offset += file.Read(frameContent, 0, frameContent.Length); // wrap around if (offset >= file.Length) { initPlayback(); return null; } var animationFrame = new Dictionary<string, object>(); animationFrame.Add("time", animationTime); animationFrame.Add("data", frameContent);
return animationFrame;
}
void initPlayback() { // reset filepointer to the beginning of file file.Position = offset = 0; // reset time startTime = Time.time; // reset animationFrame animationFrame = null; }
void OnLocalAvatarPacketRecorded(object sender, OvrAvatar.PacketEventArgs args) { using (MemoryStream outputStream = new MemoryStream()) {
BinaryWriter writer = new BinaryWriter(outputStream); writer.Write(packetSequence); args.Packet.Write(outputStream); var dataBytes = outputStream.ToArray();
//////////////////////////////////////////////////////////// // write frameSize //////////////////////////////////////////////////////////// var frameSize = BitConverter.GetBytes(dataBytes.Length); file.Write(frameSize, 0, frameSize.Length);// write size of frame
//////////////////////////////////////////////////////////// // write currentTime //////////////////////////////////////////////////////////// var diffTime = (double)(Time.time - startTime); var currentTime = BitConverter.GetBytes(diffTime); file.Write(currentTime, 0, currentTime.Length); // write relative time
Debug.Log(diffTime);
//////////////////////////////////////////////////////////// // write framedata //////////////////////////////////////////////////////////// file.Write(dataBytes, 0, dataBytes.Length);// write data
file.Flush(); SendPacketData(outputStream.ToArray());
} }
void SendPacketData(byte[] data) { // Loopback by just "receiving" the data ReceivePacketData(data); }
void ReceivePacketData(byte[] data) { using (MemoryStream inputStream = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(inputStream); int sequence = reader.ReadInt32(); OvrAvatarPacket packet = OvrAvatarPacket.Read(inputStream); LoopbackAvatar.GetComponent<OvrAvatarRemoteDriver>().QueuePacket(sequence, packet); } }
void PlaybackPacketData(byte[] data) { using (MemoryStream inputStream = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(inputStream); LoopbackAvatar.GetComponent<OvrAvatarRemoteDriver>().QueuePacket(reader.ReadInt32(), OvrAvatarPacket.Read(inputStream)); } }}
04-25-2017 12:15 PM
05-14-2017 12:08 PM
05-16-2017 12:35 PM
05-16-2017 04:47 PM
06-10-2017 03:29 AM
08-24-2017 01:17 AM
01-11-2018 09:43 AM
using UnityEngine;
using System.Collections;
using System;
using System.IO;
using Oculus.Avatar;
using System.Runtime.InteropServices;
using System.Collections.Generic;
public class Playback : MonoBehaviour
{
[Serializable]
class PacketsFile
{
public LinkedList<Packet> packetList;
};
[Serializable]
class Packet
{
public byte[] PacketData;
};
public OvrAvatar LocalAvatar;
public OvrAvatar LoopbackAvatar;
private int PacketSequence = 0;
LinkedList<Packet> packetQueue = new LinkedList<Packet>();
public bool record = false;
bool _lastRecord = false;
public bool playback = false;
public string fileName = "C:\\temp\\Recording.avs";
LinkedList<Packet> _recordedQueue = new LinkedList<Packet>();
void Start()
{
LocalAvatar.RecordPackets = true;
LocalAvatar.PacketRecorded += OnLocalAvatarPacketRecorded;
_lastRecord = record;
if (playback)
{
ReadFile();
}
}
void OnLocalAvatarPacketRecorded(object sender, OvrAvatar.PacketEventArgs args)
{
if (playback)
{
LinkedListNode<Packet> packet = _recordedQueue.First;
if (packet == null)
{
ReadFile();
packet = _recordedQueue.First;
}
SendPacketData(packet.Value.PacketData);
_recordedQueue.RemoveFirst();
}
else using (MemoryStream outputStream = new MemoryStream())
{
BinaryWriter writer = new BinaryWriter(outputStream);
var size = CAPI.ovrAvatarPacket_GetSize(args.Packet.ovrNativePacket);
byte[] data = new byte[size];
CAPI.ovrAvatarPacket_Write(args.Packet.ovrNativePacket, size, data);
writer.Write(PacketSequence++);
writer.Write(size);
writer.Write(data);
SendPacketData(outputStream.ToArray());
}
}
void Update()
{
if (!record && _lastRecord)
{
WriteToFile();
_lastRecord = record;
}
if (packetQueue.Count > 0)
{
List<Packet> deadList = new List<Packet>();
foreach (Packet packet in packetQueue)
{
ReceivePacketData(packet.PacketData);
deadList.Add(packet);
}
foreach (var packet in deadList)
{
packetQueue.Remove(packet);
}
}
}
void SendPacketData(byte[] data)
{
Packet packet = new Packet();
packet.PacketData = data;
packetQueue.AddLast(packet);
if (record && !playback) _recordedQueue.AddLast(packet);
}
void ReceivePacketData(byte[] data)
{
using (MemoryStream inputStream = new MemoryStream(data))
{
BinaryReader reader = new BinaryReader(inputStream);
int sequence = reader.ReadInt32();
int size = reader.ReadInt32();
byte[] sdkData = reader.ReadBytes(size);
IntPtr packet = CAPI.ovrAvatarPacket_Read((UInt32)data.Length, sdkData);
LoopbackAvatar.GetComponent<OvrAvatarRemoteDriver>().QueuePacket(sequence, new OvrAvatarPacket { ovrNativePacket = packet });
}
}
void WriteToFile()
{
using (Stream stream = File.Open(fileName, FileMode.Create))
{
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize(stream, new PacketsFile { packetList = _recordedQueue });
}
Debug.Log("File written");
}
void ReadFile()
{
using (Stream stream = File.Open(fileName, FileMode.Open))
{
_recordedQueue = (new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Deserialize(stream) as PacketsFile).packetList;
}
Debug.Log("File read");
}
}
02-19-2018 09:33 AM
05-27-2019 02:04 AM