KINDNICK_URP/Assets/Scripts/iFacialMocap/UnityRecieve_iFacialMocap.cs
2025-04-25 21:14:54 +09:00

263 lines
5.6 KiB
C#

using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
using System;
using System.Threading;
using System.Collections.Generic;
using System.Globalization;
public class UnityRecieve_iFacialMocap : MonoBehaviour
{
static UdpClient udp;
Thread thread;
SkinnedMeshRenderer meshTarget;
List<SkinnedMeshRenderer> meshTargetList;
string faceObjGrpName = "";
string objectNames = "";
List<GameObject> objectArray;
private string messageString = "";
public int LOCAL_PORT = 50003;
// Start is called
void Start()
{
udp = new UdpClient(LOCAL_PORT);
udp.Client.ReceiveTimeout = 4;
thread = new Thread(new ThreadStart(ThreadMethod));
thread.Start();
}
// Update is called once per frame
void Update()
{
try
{
string[] strArray1 = messageString.Split('=');
if (strArray1.Length == 2)
{
//blendShapes)
foreach (string message in strArray1[0].Split('|'))
{
string[] strArray2 = message.Split('-');
if (strArray2.Length == 1)
{
string[] strArray3 = strArray2[0].Split('!');
if (strArray3[0] == "faceObjGrp")
{
if (faceObjGrpName != strArray3[1])
{
faceObjGrpName = strArray3[1];
meshTargetList = new List<SkinnedMeshRenderer>();
GameObject faceObjGrp = GameObject.Find(faceObjGrpName);
if (faceObjGrp != null)
{
List<GameObject> list = GetAllChildren.GetAll(faceObjGrp);
foreach (GameObject obj in list)
{
meshTarget = obj.GetComponent<SkinnedMeshRenderer>();
if (meshTarget != null)
{
if(HasBlendShapes(meshTarget)==true)
{
meshTargetList.Add(meshTarget);
}
}
}
}
}
}
}
else if (strArray2.Length == 2)
{
string mappedShapeName = strArray2[0];
float weight = float.Parse(strArray2[1], CultureInfo.InvariantCulture);
for (int i = 0; i < meshTargetList.Count; i++)
{
int index = meshTargetList[i].sharedMesh.GetBlendShapeIndex(mappedShapeName);
if (index > -1)
{
meshTargetList[i].SetBlendShapeWeight(index, weight);
}
}
}
}
string objectNamesNow = GetCombineNames(strArray1[1]);
if (objectNamesNow != objectNames)
{
UpdateObjectArray(strArray1[1]);
}
int objectArrayIndex = 0;
//jointNames
foreach (string message in strArray1[1].Split('|'))
{
string[] strArray2 = message.Split('#');
if (strArray2.Length == 2)
{
string[] commaList = strArray2[1].Split(',');
string[] objNameList = commaList[3].Split(':');
for (int j = 0; j < objNameList.Length; j++)
{
if (objectArray[objectArrayIndex] != null)
{
if (strArray2[0].Contains("Position"))
{
objectArray[objectArrayIndex].transform.localPosition = new Vector3(float.Parse(commaList[0], CultureInfo.InvariantCulture), float.Parse(commaList[1], CultureInfo.InvariantCulture), float.Parse(commaList[2], CultureInfo.InvariantCulture));
}
else
{
objectArray[objectArrayIndex].transform.localEulerAngles = new Vector3(float.Parse(commaList[0], CultureInfo.InvariantCulture), float.Parse(commaList[1], CultureInfo.InvariantCulture), float.Parse(commaList[2], CultureInfo.InvariantCulture));
}
}
objectArrayIndex++;
}
}
}
}
}
catch
{ }
}
void ThreadMethod()
{
//Process once every 5ms
long next = DateTime.Now.Ticks + 50000;
long now;
while (true)
{
try
{
IPEndPoint remoteEP = null;
byte[] data = udp.Receive(ref remoteEP);
messageString = Encoding.ASCII.GetString(data);
}
catch
{
}
do
{
now = DateTime.Now.Ticks;
}
while (now < next);
next += 50000;
}
}
private string GetCombineNames(string strArray)
{
StringBuilder sb = new StringBuilder("");
foreach (string message in strArray.Split('|'))
{
if (message != "")
{
string[] strArray1 = message.Split('#');
string[] commaList = strArray1[1].Split(',');
sb.Append(commaList[3]);
sb.Append(",");
}
}
return sb.ToString();
}
private void UpdateObjectArray(string strArray)
{
objectArray = new List<GameObject>();
foreach (string message in strArray.Split('|'))
{
if (message != "")
{
string[] strArray1 = message.Split('#');
string[] commaList = strArray1[1].Split(',');
string[] objNameList = commaList[3].Split(':');
for (int i = 0; i < objNameList.Length; i++)
{
GameObject bufObj = GameObject.Find(objNameList[i]);
objectArray.Add(bufObj);
}
}
}
}
public string GetMessageString()
{
return messageString;
}
void OnApplicationQuit()
{
thread.Abort();
}
public void StopUDP()
{
udp.Close();
thread.Abort();
}
void Stop()
{
try
{
StopUDP();
}
catch (IOException)
{
}
}
private bool HasBlendShapes(SkinnedMeshRenderer skin)
{
if (!skin.sharedMesh)
{
return false;
}
if (skin.sharedMesh.blendShapeCount <= 0)
{
return false;
}
return true;
}
}
public static class GetAllChildren
{
public static List<GameObject> GetAll(this GameObject obj)
{
List<GameObject> allChildren = new List<GameObject>();
allChildren.Add(obj);
GetChildren(obj, ref allChildren);
return allChildren;
}
public static void GetChildren(GameObject obj, ref List<GameObject> allChildren)
{
Transform children = obj.GetComponentInChildren<Transform>();
if (children.childCount == 0)
{
return;
}
foreach (Transform ob in children)
{
allChildren.Add(ob.gameObject);
GetChildren(ob.gameObject, ref allChildren);
}
}
}