using CScript.Entity;
using CScript.Net;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
namespace CScript.Utilities
{
public static class AppUtil
{
///
///
///
///
///
public static byte[] ParseData(NetMeshData netMeshData)
{
//1 colorList 标识1个字节 长度两个字节 内容 长度*2个字节
//2 sideVertexList
//3 frontVertexList
//4 uvList
//5 texture
//6 frontTriangles
//7 sideTriangles
int tempInfoLength = 0;
List infos = new List();
byte colorSigh = (byte)1;
byte[] colorLength = BitConverter.GetBytes(netMeshData.netColorList.Count);
//List colorBytes =new List(netMeshData.colorList);
//infos.Add(colorSigh);
//infos.AddRange(colorLength);
//infos.AddRange(colorBytes);
byte sideVertexSigh = (byte)2;
tempInfoLength = netMeshData.netSideVertexList.Count * 4;
byte[] sideVertexLength = BitConverter.GetBytes(tempInfoLength);
List sideVertexBytes = new List(tempInfoLength);
for (int i = 0, count = netMeshData.netSideVertexList.Count; i < count; i++)
{
sideVertexBytes.AddRange(BitConverter.GetBytes(netMeshData.netSideVertexList[i]));
}
infos.Add(sideVertexSigh);
infos.AddRange(sideVertexLength);
infos.AddRange(sideVertexBytes);
byte frontVertexSigh = (byte)3;
tempInfoLength = netMeshData.netFrontVertexList.Count * 4;
byte[] frontVertexLength = BitConverter.GetBytes(tempInfoLength);
List frontVertexBytes = new List(tempInfoLength);
for (int i = 0, count = netMeshData.netFrontVertexList.Count; i < count; i++)
{
frontVertexBytes.AddRange(BitConverter.GetBytes(netMeshData.netFrontVertexList[i]));
}
infos.Add(frontVertexSigh);
infos.AddRange(frontVertexLength);
infos.AddRange(frontVertexBytes);
byte uvSigh = (byte)4;
tempInfoLength = netMeshData.netUvList.Count * 4;
byte[] uvLength = BitConverter.GetBytes(tempInfoLength);
List uvBytes = new List(tempInfoLength);
for (int i = 0, count = netMeshData.netUvList.Count; i < count; i++)
{
uvBytes.AddRange(BitConverter.GetBytes(netMeshData.netUvList[i]));
}
infos.Add(uvSigh);
infos.AddRange(uvLength);
infos.AddRange(uvBytes);
byte photoSigh = (byte)5;
//byte[] photoByte = netMeshData.texture.EncodeToPNG();
//byte[] photoLength = BitConverter.GetBytes(photoByte.Length);
byte[] photoLength = BitConverter.GetBytes(netMeshData.netTexture.Count);
infos.Add(photoSigh);
infos.AddRange(photoLength);
//infos.AddRange(photoByte);
infos.AddRange(netMeshData.netTexture);
byte frontTriangleSigh = (byte)6;
tempInfoLength = netMeshData.netFrontTriangles.Count * 4;
byte[] frontTriangleLength = BitConverter.GetBytes(tempInfoLength);
List frontTriangleBytes = new List(tempInfoLength);
for (int i = 0, count = netMeshData.netFrontTriangles.Count; i < count; i++)
{
frontTriangleBytes.AddRange(BitConverter.GetBytes(netMeshData.netFrontTriangles[i]));
}
infos.Add(frontTriangleSigh);
infos.AddRange(frontTriangleLength);
infos.AddRange(frontTriangleBytes);
byte sideTriangleSigh = (byte)7;
tempInfoLength = netMeshData.netSideTriangles.Count * 4;
byte[] sideTriangleLength = BitConverter.GetBytes(tempInfoLength);
List sideTriangleBytes = new List(tempInfoLength);
for (int i = 0, count = netMeshData.netSideTriangles.Count; i < count; i++)
{
sideTriangleBytes.AddRange(BitConverter.GetBytes(netMeshData.netSideTriangles[i]));
}
infos.Add(sideTriangleSigh);
infos.AddRange(sideTriangleLength);
infos.AddRange(sideTriangleBytes);
int total = infos.Count;
List allInfos = new List();
byte infoSigh = 101;
allInfos.Add(infoSigh);
allInfos.AddRange(BitConverter.GetBytes(total));
allInfos.AddRange(infos);
return allInfos.ToArray();
}
public static NetMeshData ParseBinary(byte[] message)
{
int index = 0;
NetMeshData netMeshData = new NetMeshData();
byte messageID = message[index];
if (messageID == 101)
{
//0 是id 101
int infoLenght = BitConverter.ToInt32(message, 0);
byte[] totalLenth = new byte[4];
index += 1;//1
//1-4 包内容长度
Array.Copy(message, index, totalLenth, 0, 4);
index += 4;//5
int totalCount = BitConverter.ToInt32(totalLenth, 0);
// 5 color 标识
byte colorSign = message[index];
index += 1;
if (colorSign == 1)
{
//byte[] colorLength = new byte[4];
//Array.Copy(message, index, colorLength, 0, 4);
//index += 4;
//int colorCount = BitConverter.ToInt32(colorLength, 0);
//Debug.LogError(message[index] +"_" +message[index+1]);
// netMeshData.colorList = new byte[colorCount];
// Array.Copy(message, index, netMeshData.colorList, 0, colorCount);
// index += colorCount;
}
// sideVertexList
byte sideVertexSign = message[index];
if (sideVertexSign == 2)
{
int[] sideVertexInfos = GetInfoValues(message, ref index);
netMeshData.netSideVertexList.AddRange(sideVertexInfos);
}
// frontVertexList
byte frontVertexSign = message[index];
if (frontVertexSign == 3)
{
int[] frontVertexInfos = GetInfoValues(message, ref index);
netMeshData.netFrontVertexList.AddRange(frontVertexInfos);
}
//uvList
byte uvVertexSign = message[index];
if (uvVertexSign == 4)
{
int[] uvInfos = GetInfoValues(message, ref index);
netMeshData.netUvList.AddRange(uvInfos);
}
// texture
byte textureSign = message[index];
if (textureSign == 5)
{
index += 1;
byte[] textureLength = new byte[4];
Array.Copy(message, index, textureLength, 0, 4);
index += 4;
int textureCount = BitConverter.ToInt32(textureLength, 0);
byte[] tempBytes = new byte[textureCount];
Array.Copy(message, index, tempBytes, 0, textureCount);
// netMeshData.texture = ByteToTex2d(tempBytes);
netMeshData.netTexture.AddRange(tempBytes);
index += textureCount;
}
//frontTriangles
byte frontTrianglesSign = message[index];
if (frontTrianglesSign == 6)
{
int[] frontTrianglesInfos = GetInfoValues(message, ref index);
netMeshData.netFrontTriangles.AddRange(frontTrianglesInfos);
}
//sideTriangles
byte sideTrianglesSign = message[index];
if (sideTrianglesSign == 7)
{
int[] sideTrianglesInfos = GetInfoValues(message, ref index);
netMeshData.netSideTriangles.AddRange(sideTrianglesInfos);
}
return netMeshData;
}
return null;
}
private static int[] GetInfoValues(byte[] message, ref int index)
{
byte[] tempLength = new byte[4];
index++;
Array.Copy(message, index, tempLength, 0, 4);
index += 4;
int tempCount = BitConverter.ToInt32(tempLength, 0);
int[] tempInfos = new int[tempCount / 4];
for (int i = 0; i < tempCount / 4; i++)
{
byte[] tempBytes = new byte[4];
Array.Copy(message, index, tempBytes, 0, 4);
index += 4;
//Debug.LogError(i+" "+ index);
tempInfos[i] = BitConverter.ToInt32(tempBytes, 0);
}
return tempInfos;
}
private static T[] GetValues(byte[] byteData, int byteByteLength)
{
Type t = typeof(T);
int index = 0;
int valueLength = byteData.Length / byteByteLength;
T[] tempByteValue = new T[valueLength];
for (int i = 0; i < valueLength; i++)
{
if (t == typeof(Int32))
{
tempByteValue[i] = (T)(object)BitConverter.ToInt32(byteData, index);
}
else if (t == typeof(Int16))
{
tempByteValue[i] = (T)(object)BitConverter.ToInt16(byteData, index);
}
else if (t == typeof(Int64))
{
tempByteValue[i] = (T)(object)BitConverter.ToInt64(byteData, index);
}
else if (t == typeof(UInt16))
{
tempByteValue[i] = (T)(object)BitConverter.ToUInt16(byteData, index);
}
else if (t == typeof(UInt32))
{
tempByteValue[i] = (T)(object)BitConverter.ToUInt32(byteData, index);
}
else if (t == typeof(UInt64))
{
tempByteValue[i] = (T)(object)BitConverter.ToUInt64(byteData, index);
}
index += byteByteLength;
}
return tempByteValue;
}
public static T BytesToIntX(byte[] byteData, int offset, int byteByteLength) where T : IComparable
{
int mask = 0xff;
long temp = 0;
for (int i = 0; i < byteByteLength; i++)
{
temp |= (byteData[offset + i] & mask) << (8 * i);
}
return (T)Convert.ChangeType(temp, typeof(T));
}
public static T BytesToIntX(List byteData, int offset, int byteByteLength) where T : IComparable
{
int mask = 0xff;
long temp = 0;
for (int i = 0; i < byteByteLength; i++)
{
temp |= (byteData[offset + i] & mask) << (8 * i);
}
return (T)Convert.ChangeType(temp, typeof(T));
}
public static NetMessage UnpackMessage(byte[] packet)
{
NetMessage message = null;
using (MemoryStream ms = new MemoryStream(packet))
{
message = ProtoBuf.Serializer.Deserialize(ms);
}
return message;
}
public static Texture2D tex;
public static Texture2D ByteToTex2d(byte[] bytes, int w = 512, int h = 512)
{
if (tex == null)
{
tex = new Texture2D(w, h);
}
tex.LoadImage(bytes);
return tex;
}
public static T Clone(T RealObject)
{
using (Stream objectStream = new MemoryStream())
{
//利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream, RealObject);
objectStream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(objectStream);
}
}
//static double[,] YUV2RGB_CONVERT_MATRIX = new double[3, 3] { { 1, 0, 1.4022 }, { 1, -0.3456, -0.7145 }, { 1, 1.771, 0 } };
//public static byte[] ConvertYUV2RGB(byte[] yuvFrame, int width, int height)
//{
// int uIndex = width * height;
// int vIndex = uIndex + ((width * height) >> 2);
// int gIndex = width * height;
// int bIndex = gIndex * 2;
// int temp = 0;
// byte[] rgbFrame = new byte[width * height * 3];
// for (int y = 0; y < height; y++)
// {
// for (int x = 0; x < width; x++)
// {
// //R分量
// temp = (int)(yuvFrame[y * width + x] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[0, 2]);
// rgbFrame[y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
// // G分量
// temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 1] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 2]);
// rgbFrame[gIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
// // B分量
// temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[2, 1]);
// rgbFrame[bIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
// }
// }
// return rgbFrame;
//}
public static void Nv420_to_rgb(Mat y, Mat nv, Mat rgb)
{
MatOfByte uuvv =new MatOfByte( Mat.zeros(nv.size(), CvType.CV_8UC1));
byte[] dptr = uuvv.toArray();
byte[] sptr =new MatOfByte(nv).toArray();
for (int i = 0; i < uuvv.rows() * uuvv.cols(); ++i)
{
if (i % 2 == 0)
dptr[i / 2] = sptr[i];
else
dptr[(i - 1) / 2 + uuvv.rows() * uuvv.cols() / 2] = sptr[i];
}
Mat yuv = new Mat((int)(y.rows() * 1.5f), y.cols(), CvType.CV_8UC1);
y.copyTo(yuv.submat(new OpenCVForUnity.CoreModule.Rect(0, 0, y.cols(), y.rows())));
uuvv.copyTo(yuv.submat(new OpenCVForUnity.CoreModule.Rect(0, y.rows(), y.cols(), y.rows() / 2)));
Imgproc.cvtColor(yuv, rgb, Imgproc.COLOR_YUV2BGR_I420);
}
}
}