
hand의 Joint를 어떻게 가져왔고, 어떤 보정이 이루어졌는지 알아보기 위해 해당 에셋의 HandCursor 코드를 분석함 !
using UnityEngine;
using UnityEngine.UI;
namespace LightBuzz.Kinect4Azure
{
public enum CursorHand
{
Automatic, // 자동
Left, // 왼손
Right // 오른손
}
public class HandCursor : MonoBehaviour
{
[SerializeField] private CursorHand _hand = CursorHand.Automatic; // Automatic, Left, Right 중 기본
[SerializeField][Range(0, 1)] private float _smoothing = 0.25f; // 스무딩
[SerializeField][Range(0, 10)] private float _scaleX = 1.0f; // X 크기
[SerializeField][Range(0, 10)] private float _scaleY = 1.0f; // Y 크기
private Image _cursorImage;
private Vector2 _previous = Vector2.zero;
public CursorHand Hand
{
get => _hand;
set => _hand = value;
}
private void Start()
{
_cursorImage = GetComponent<Image>(); // 시작했을 때, 손의 이미지 가져옴
}
public void Load(Body body, UniformImage image)
{
if (body == null) return;
if (image == null) return;
int width = image.Width; // 이미지 가로
int height = image.Height; // 이미지 세로
Joint elbowLeft = body.Joints[JointType.ElbowLeft]; // 왼쪽 팔꿈치
Joint elbowRight = body.Joints[JointType.ElbowRight]; // 오른쪽 팔꿈치
Joint wristLeft = body.Joints[JointType.WristLeft]; // 왼쪽 손목
Joint wristRight = body.Joints[JointType.WristRight]; // 오른쪽 손목
Vector2D shoulderLeft = body.Joints[JointType.ShoulderLeft].PositionColor; // 왼쪽 어깨 2D 좌표
Vector2D shoulderRight = body.Joints[JointType.ShoulderRight].PositionColor; // 오른쪽 어깨 2D 좌표
Vector2D shoulder = Vector2D.Zero;
Vector2D elbow = Vector2D.Zero;
Vector2D wrist = Vector2D.Zero;
switch (_hand)
{
case CursorHand.Left: // 왼쪽
{
shoulder = shoulderLeft;
elbow = elbowLeft.PositionColor;
wrist = wristLeft.PositionColor;
}
break;
case CursorHand.Right: // 오른쪽
{
shoulder = shoulderRight;
elbow = elbowRight.PositionColor;
wrist = wristRight.PositionColor;
}
break;
case CursorHand.Automatic: // 자동
{
// Y축은 아래로 향할수록 커짐 => 더 위에 있는 것으로 잡은듯 ❓왜 이렇게 했을까❓
shoulder = wristLeft.PositionColor.Y < wristRight.PositionColor.Y ? shoulderLeft : shoulderRight; // 왼쪽 손목 Y값 < 오른쪽 손목의 Y값 => shoulder = 왼쪽 손목
elbow = wristLeft.PositionColor.Y < wristRight.PositionColor.Y ? elbowLeft.PositionColor : elbowRight.PositionColor;
wrist = wristLeft.PositionColor.Y < wristRight.PositionColor.Y ? wristLeft.PositionColor : wristRight.PositionColor;
}
break;
default:
break;
}
float distance = Calculations.Distance(shoulderLeft, shoulderRight); // 왼쪽-오른쪽 어깨 사이의 거리
float minX = shoulder.X - distance; // minX : 특정 어깨의 X좌표-distance
if (minX < 0.0f) minX = 0.0f; // 값이 최소 0.0f
float maxX = shoulder.X + distance; // maxX : 특정 어깨의 X좌표+distance
if (maxX > width) maxX = width; // 값 최대 이미지 가로
float minY = shoulder.Y - distance;
if (minY < 0.0f) minY = 0.0f;
float maxY = shoulder.Y + distance;
if (maxY > height) maxY = height;
float factorX = minX != maxX ? (wrist.X - minX) / (maxX - minX) : 0.0f;
float factorY = minY != maxY ? (wrist.Y - minY) / (maxY - minY) : 0.0f;
float x = width * factorX * _scaleX;
float y = height * factorY * _scaleY;
float angle = 90.0f - Calculations.Rotation(elbow, wrist, Axis.Z);
if (wrist.X > elbow.X) angle = -angle;
Vector3 position = Vector2.Lerp(_previous, new Vector2(x, y), _smoothing); // 선형보간법 적용, z=0으로 position 설정
Vector3 rotation = new Vector3(0.0f, 0.0f, angle);
Vector3 scale = new Vector3(1.0f, 1.0f, 1.0f);
_previous = position;
_cursorImage.transform.localPosition = image.GetPosition(position);
_cursorImage.transform.localRotation = UnityEngine.Quaternion.Euler(rotation);
_cursorImage.transform.localScale = scale;
}
}
}
'📑 공부 > 💡 연구' 카테고리의 다른 글
[전통춤 모션캡쳐 연구] mocopi using Unity (0) | 2023.09.12 |
---|---|
[전통춤 모션캡쳐 연구] mocopi 조사 (0) | 2023.09.12 |
[전통춤 모션캡쳐 연구] Azure Kinect for Unity3D 에셋 이용하기 (0) | 2023.07.23 |
[전통춤 모션캡쳐 연구] Unity에서 Kinect 실행하기 (0) | 2023.07.18 |
[전통춤 모션캡쳐 연구] Azure Kinect Body Tracking (C#) (0) | 2023.07.13 |