MotionCapture/Assets/Behaviours/BoneBehaviour.cs

84 lines
2.6 KiB
C#

using System.Collections.Generic;
using Models;
using UnityEngine;
namespace Behaviours
{
public class BoneBehaviour : MonoBehaviour
{
private readonly UdpListener _listener = new UdpListener();
private Dictionary<HumanBodyBones, RotationNode> _rotationNodes;
private Animator _animator;
private void Start()
{
_animator = GetComponent<Animator>();
CreateRotationNodes();
_listener.AddHandler(OnReceive);
_listener.Connect(5000);
}
private void Update()
{
foreach (var node in _rotationNodes)
{
_animator.GetBoneTransform(node.Key).rotation = node.Value.Rotation;
}
}
private void OnDisable()
{
_listener.DisConnect();
}
private void OnReceive(List<PoseLandmark> landmarks)
{
// 计算腰部
var frontLeft = Vector3.Cross(
landmarks[PoseLandmarkType.RightHip].Vector3 - landmarks[PoseLandmarkType.LeftHip].Vector3,
landmarks[PoseLandmarkType.RightShoulder].Vector3 - landmarks[PoseLandmarkType.LeftHip].Vector3);
var frontRight = Vector3.Cross(
landmarks[PoseLandmarkType.LeftShoulder].Vector3 - landmarks[PoseLandmarkType.RightHip].Vector3,
landmarks[PoseLandmarkType.LeftHip].Vector3 - landmarks[PoseLandmarkType.LeftHip].Vector3);
var front = frontLeft + frontRight;
front.Normalize();
var oldRotation = _rotationNodes[HumanBodyBones.Hips];
_rotationNodes[HumanBodyBones.Hips] = new RotationNode(
oldRotation.UnityName,
oldRotation.Rotation,
Quaternion.LookRotation(front));
}
private void CreateRotationNodes()
{
_rotationNodes = new Dictionary<HumanBodyBones, RotationNode>();
var bonesArray = new[]
{
HumanBodyBones.Hips,
HumanBodyBones.LeftUpperArm,
HumanBodyBones.LeftLowerArm,
HumanBodyBones.RightUpperArm,
HumanBodyBones.RightLowerArm,
HumanBodyBones.LeftUpperLeg,
HumanBodyBones.LeftLowerLeg,
HumanBodyBones.RightUpperLeg,
HumanBodyBones.RightLowerLeg
};
foreach (var bone in bonesArray)
{
var rotation = _animator.GetBoneTransform(bone).rotation;
_rotationNodes.Add(bone, new RotationNode(bone, rotation, rotation));
}
}
}
}