123 lines
4.1 KiB
C#
123 lines
4.1 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
|
|
public class OptitrackVisualizer : MonoBehaviour
|
|
{
|
|
[Header("OptiTrack 설정")]
|
|
public OptitrackRawDataReceiver dataReceiver;
|
|
|
|
[Header("시각화 설정")]
|
|
public bool showGizmos = true;
|
|
public float gizmoSize = 0.05f;
|
|
public float handGizmoScale = 0.1f; // 손 기즈모 크기 비율 (1 = 100%)
|
|
public Color boneColor = Color.red;
|
|
public bool drawBoneConnections = true;
|
|
public Color connectionColor = Color.yellow;
|
|
|
|
private OptitrackSkeletonDefinition skeletonDef;
|
|
private Dictionary<int, Transform> boneTransforms = new Dictionary<int, Transform>();
|
|
private List<(Transform, Transform)> boneConnections = new List<(Transform, Transform)>();
|
|
|
|
void Start()
|
|
{
|
|
if (dataReceiver == null)
|
|
{
|
|
dataReceiver = FindFirstObjectByType<OptitrackRawDataReceiver>();
|
|
if (dataReceiver == null)
|
|
{
|
|
Debug.LogError("OptitrackRawDataReceiver를 찾을 수 없습니다.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 스켈레톤 정의 가져오기
|
|
skeletonDef = dataReceiver.StreamingClient.GetSkeletonDefinitionByName(dataReceiver.SkeletonAssetName);
|
|
if (skeletonDef == null) return;
|
|
|
|
// 본 Transform 생성
|
|
foreach (var bone in skeletonDef.Bones)
|
|
{
|
|
GameObject boneObj = new GameObject(bone.Name);
|
|
boneTransforms[bone.Id] = boneObj.transform;
|
|
}
|
|
|
|
// 본 계층 구조 설정
|
|
foreach (var bone in skeletonDef.Bones)
|
|
{
|
|
Transform boneTransform = boneTransforms[bone.Id];
|
|
|
|
if (bone.ParentId == 0)
|
|
{
|
|
boneTransform.SetParent(transform, false);
|
|
}
|
|
else if (boneTransforms.TryGetValue(bone.ParentId, out Transform parentTransform))
|
|
{
|
|
boneTransform.SetParent(parentTransform, false);
|
|
boneConnections.Add((parentTransform, boneTransform));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (dataReceiver == null || skeletonDef == null) return;
|
|
|
|
// 최신 스켈레톤 상태 가져오기
|
|
OptitrackSkeletonState skelState = dataReceiver.StreamingClient.GetLatestSkeletonState(skeletonDef.Id);
|
|
if (skelState == null) return;
|
|
|
|
// 각 본의 위치와 회전 업데이트
|
|
foreach (var bone in skeletonDef.Bones)
|
|
{
|
|
if (boneTransforms.TryGetValue(bone.Id, out Transform boneTransform))
|
|
{
|
|
if (skelState.BonePoses.TryGetValue(bone.Id, out OptitrackPose pose))
|
|
{
|
|
boneTransform.localPosition = pose.Position;
|
|
boneTransform.localRotation = pose.Orientation;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnDrawGizmos()
|
|
{
|
|
if (!showGizmos || !Application.isPlaying || skeletonDef == null) return;
|
|
|
|
// 본 기즈모 그리기
|
|
Gizmos.color = boneColor;
|
|
foreach (var bone in skeletonDef.Bones)
|
|
{
|
|
if (boneTransforms.TryGetValue(bone.Id, out Transform transform))
|
|
{
|
|
float size = gizmoSize;
|
|
string boneName = bone.Name.ToLower();
|
|
|
|
// 손과 손가락 기즈모 크기 조절
|
|
if (boneName.Contains("hand") ||
|
|
boneName.Contains("thumb") ||
|
|
boneName.Contains("index") ||
|
|
boneName.Contains("middle") ||
|
|
boneName.Contains("ring") ||
|
|
boneName.Contains("pinky"))
|
|
{
|
|
size *= handGizmoScale;
|
|
}
|
|
|
|
Gizmos.DrawWireSphere(transform.position, size);
|
|
}
|
|
}
|
|
|
|
// 본 연결선 그리기
|
|
if (drawBoneConnections)
|
|
{
|
|
Gizmos.color = connectionColor;
|
|
|
|
foreach (var (parent, child) in boneConnections)
|
|
{
|
|
Gizmos.DrawLine(parent.position, child.position);
|
|
}
|
|
}
|
|
}
|
|
} |