dwelling act 4 (live motion cap w/ kinect azure)
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.

251 lines
8.0 KiB

1 year ago
using LZ4Sharp;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine;
namespace com.rfilkov.kinect
{
// message-received delegate
internal delegate void ReceivedMessageEventHandler(object sender, ReceivedMessageEventArgs e);
// received message event
internal class ReceivedMessageEventArgs : System.EventArgs
{
public NetMessageData message;
public bool synched;
public ReceivedMessageEventArgs(NetMessageData message)
{
this.message = message;
this.synched = false;
}
public ReceivedMessageEventArgs(NetMessageData message, bool synched)
{
this.message = message;
this.synched = synched;
}
}
// network connection data
internal class NetConnData
{
public TcpClient client = null;
public NetworkStream stream = null;
public string remoteIP = string.Empty;
private static int counter = 1;
public int messageSize = 0;
public int ID = 0; //counter of clients (each is unique)
public bool readyToSend = true;
public bool isActive = false;
public const int MaxMessageQueueLength = 10; // 50; 2;
public Queue<NetMessageData> messageQueue = new Queue<NetMessageData>(MaxMessageQueueLength);
public byte[] messageBuffer = null;
public int bytesReceived = 0;
public int packetCounter = 0;
public ulong messageReceiveTime = 0;
public NetConnData()
{
ID = counter;
counter++;
messageBuffer = new byte[messageSize];
}
public void ResetCounters()
{
bytesReceived = 0;
packetCounter = 0;
}
}
// network message type
public enum NetMessageType : int { Control = 0, Color = 1, Depth = 2, Infrared = 3, BodyData = 4, BodyIndex = 5, Pose = 6, Depth2Color = 7, Color2Depth = 8, Color2BodyIndex = 9, Color2Infrared = 10 }
// frame encode type
public enum FrameEncodeType : int { None = 0, Raw = 1, Jpeg = 2, K4b = 3, Json = 4, SensorDataJson = 5, DSTraw = 6, CSTraw = 7, Compressed = 8 };
// control message type
public enum ControlMessageType : int { GetSensorData = 0, KeepAlive = 1, Disconnect = 2, GetDST = 3, GetCST = 4 }
// network message data
internal class NetMessageData
{
public NetMessageType msgType;
public FrameEncodeType encType;
public int frameWidth;
public int frameHeight;
public ulong timestamp;
public byte[] frameData;
private const int headerSize = 2 * sizeof(byte) + 2 * sizeof(ushort) + sizeof(ulong);
private const int compHeaderSize = 1 + sizeof(int); // compressed data header
private ILZ4Compressor compressor = null;
private ILZ4Decompressor decompressor = null;
public long timeCreated;
public NetMessageData()
{
timeCreated = System.DateTime.UtcNow.Ticks;
}
public NetMessageData(NetMessageType msgType, FrameEncodeType encType)
{
this.msgType = msgType;
this.encType = encType;
this.timeCreated = System.DateTime.UtcNow.Ticks;
}
public NetMessageData(NetMessageType msgType, FrameEncodeType encType, int frameWidth, int frameHeight, ulong timestamp)
{
this.msgType = msgType;
this.encType = encType;
this.frameWidth = frameWidth;
this.frameHeight = frameHeight;
this.timestamp = timestamp;
}
public void SetData(byte[] data)
{
frameData = data;
}
public void SetData(ushort[] data)
{
int frameLen = data.Length * sizeof(ushort);
frameData = new byte[frameLen];
KinectInterop.CopyBytes(data, sizeof(ushort), frameData, sizeof(byte));
}
public void SetCompressor(ILZ4Compressor compressor)
{
this.compressor = compressor;
}
public void SetDecompressor(ILZ4Decompressor decompressor)
{
this.decompressor = decompressor;
}
public void CompressData()
{
if (compressor != null && frameData != null && encType != FrameEncodeType.Compressed)
{
byte[] compressBuffer = new byte[frameData.Length + compHeaderSize];
compressBuffer[0] = (byte)encType;
byte[] elemBytes = System.BitConverter.GetBytes(frameData.Length);
elemBytes.CopyTo(compressBuffer, 1);
int compSize = compressor.Compress(frameData, 0, frameData.Length, compressBuffer, compHeaderSize) + compHeaderSize;
//if (msgType == NetMessageType.Depth)
// Debug.Log(" compress: " + msgType + " - " + encType + ", ts: " + timestamp + ", frameLen: " + frameData.Length + ", compLen: " + compSize);
encType = FrameEncodeType.Compressed;
frameData = new byte[compSize];
System.Buffer.BlockCopy(compressBuffer, 0, frameData, 0, compSize);
compressBuffer = null;
}
}
public void DecompressData()
{
if(decompressor != null && frameData != null && frameData.Length > compHeaderSize && encType == FrameEncodeType.Compressed)
{
encType = (FrameEncodeType)frameData[0];
int frameSize = System.BitConverter.ToInt32(frameData, 1);
byte[] decompressBuffer = new byte[frameSize];
int decompSize = decompressor.Decompress(frameData, compHeaderSize, decompressBuffer, 0, frameData.Length - compHeaderSize);
frameData = decompressBuffer;
decompressBuffer = null;
}
}
public byte[] WrapMessage()
{
if (frameData == null)
return null;
if (compressor != null)
{
CompressData();
}
int msgOffset = sizeof(int);
int msgLength = headerSize + frameData.Length;
byte[] msgBytes = new byte[msgOffset + msgLength];
byte[] lenBytes = System.BitConverter.GetBytes(msgLength);
lenBytes.CopyTo(msgBytes, 0);
msgBytes[msgOffset] = (byte)msgType; msgOffset++;
msgBytes[msgOffset] = (byte)encType; msgOffset++;
byte[] elemBytes = System.BitConverter.GetBytes((ushort)frameWidth);
elemBytes.CopyTo(msgBytes, msgOffset); msgOffset += sizeof(ushort);
elemBytes = System.BitConverter.GetBytes((ushort)frameHeight);
elemBytes.CopyTo(msgBytes, msgOffset); msgOffset += sizeof(ushort);
elemBytes = System.BitConverter.GetBytes(timestamp);
elemBytes.CopyTo(msgBytes, msgOffset); msgOffset += sizeof(ulong);
frameData.CopyTo(msgBytes, msgOffset); msgOffset += frameData.Length;
return msgBytes;
}
public void UnwrapMessage(byte[] message)
{
int msgOffset = sizeof(int);
msgType = (NetMessageType)message[msgOffset]; msgOffset++;
encType = (FrameEncodeType)message[msgOffset]; msgOffset++;
frameWidth = System.BitConverter.ToUInt16(message, msgOffset); msgOffset += sizeof(ushort);
frameHeight = System.BitConverter.ToUInt16(message, msgOffset); msgOffset += sizeof(ushort);
timestamp = System.BitConverter.ToUInt64(message, msgOffset); msgOffset += sizeof(ulong);
int frameSize = message.Length - msgOffset;
frameData = new byte[frameSize];
System.Array.Copy(message, msgOffset, frameData, 0, frameSize);
if(decompressor != null)
{
DecompressData();
}
}
}
// udp state to pass to async methods
public struct UdpState
{
public UdpClient uc;
public System.Net.IPEndPoint ep;
}
}