У меня есть модель человеческой руки в Unity.
Мне нужно вычислить положение каждого сустава пальца, используя вращение предыдущего сустава. В модели это изображается как объект — запястье, следующие 5 суставов каждого пальца — его дочерний объект, и так далее, пока не дойдете до кончиков пальцев.
I Мне удалось сделать это в Unity, и я добавил код ниже. Сейчас я пытаюсь преобразовать его в код Python, чтобы, когда мне будут заданы вращения, я мог рисовать точки в matplotlib для реконструкции руки.
Я предоставлю любая другая необходимая информация.
Вот код:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using TMPro;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
public class PositionToRotationQtr : MonoBehaviour
{
public static int jointCount = 18;
public GameObject lHand, rHand;
public TextMeshPro lText, rText, lDistText, rDistText;
public Dictionary lRotations = new Dictionary();
public Dictionary rRotations = new Dictionary();
public Dictionary lDistFromPrev = new Dictionary();
public Dictionary rDistFromPrev = new Dictionary();
public List lJoints, rJoints;
public GameObject[] lPoints = new GameObject[jointCount];
public GameObject[] rPoints = new GameObject[jointCount];
// Start is called before the first frame update
void Start()
{
if (lHand == null)
lHand = GameObject.Find("OculusHand_L");
if (rHand == null)
rHand = GameObject.Find("OculusHand_R");
for (int i = 0; i < jointCount; i++)
{
lPoints = GameObject.CreatePrimitive(PrimitiveType.Sphere);
lPoints.GetComponent().material.color = Color.blue;
lPoints.transform.localScale = new Vector3(0.005f, 0.005f, 0.005f);
rPoints = GameObject.CreatePrimitive(PrimitiveType.Sphere);
rPoints.GetComponent().material.color = Color.blue;
rPoints.transform.localScale = new Vector3(0.005f, 0.005f, 0.005f);
}
MapJoints();
}
// Update is called once per frame
void Update()
{
UpdateData();
//PrintData();
CalcHandsQtr();
}
void UpdateData()
{
lRotations.Clear();
rRotations.Clear();
lDistFromPrev.Clear();
rDistFromPrev.Clear();
//int counter = 0;
//lPoints[counter++].transform.position = lJoints[0][0].transform.position;
foreach (Transform[] joints in lJoints)
{
if (joints.Length == 1)
lRotations.Add(joints[0].name, joints[0].rotation.eulerAngles);
else
{
for (int i = 0; i < joints.Length; i++)
{
//lPoints[counter++].transform.position = joints.transform.position;
lRotations.Add(joints.name.ToString(), joints.rotation.eulerAngles);
if (i == 0)
lDistFromPrev.Add(joints.name, Vector3.Distance(lJoints[0][0].position, joints[i].position));
else
lDistFromPrev.Add(joints[i].name, Vector3.Distance(joints[i - 1].position, joints[i].position));
}
}
}
//counter = 0;
//rPoints[counter++].transform.position = rJoints[0][0].transform.position;
foreach (Transform[] joints in rJoints)
{
if (joints.Length == 1)
rRotations.Add(joints[0].name, joints[0].rotation.eulerAngles);
else
{
for (int i = 0; i < joints.Length; i++)
{
//rPoints[counter++].transform.position = joints[i].transform.position;
rRotations.Add(joints[i].name.ToString(), joints[i].rotation.eulerAngles);
if (i == 0)
rDistFromPrev.Add(joints[i].name, Vector3.Distance(rJoints[0][0].position, joints[i].position));
else
rDistFromPrev.Add(joints[i].name, Vector3.Distance(joints[i - 1].position, joints[i].position));
}
}
}
}
void PrintData()
{
string lData = "\n Left Hand Rotations:\n", rData = "\n Right Hand Rotations:\n";
foreach (KeyValuePair rotation in lRotations)
lData += " " + rotation.Key + ": " + rotation.Value.ToString() + "\n";
foreach (KeyValuePair rotation in rRotations)
rData += " " + rotation.Key + ": " + rotation.Value.ToString() + "\n";
string lDistData = "\n Left Hand Distances:\n", rDistData = "\n Right Hand Distances:\n";
foreach (KeyValuePair distance in lDistFromPrev)
lDistData += " " + distance.Key + ": " + distance.Value.ToString() + "\n";
foreach (KeyValuePair distance in rDistFromPrev)
rDistData += " " + distance.Key + ": " + distance.Value.ToString() + "\n";
lText.text = lData;
rText.text = rData;
lDistText.text = lDistData;
rDistText.text = rDistData;
}
void MapJoints()
{
Transform lWrist = lHand.transform.Find("b_l_wrist");
Transform[] lThumb = {
lWrist.Find("b_l_thumb0"),
lWrist.Find("b_l_thumb0/b_l_thumb1"),
lWrist.Find("b_l_thumb0/b_l_thumb1/b_l_thumb2"),
lWrist.Find("b_l_thumb0/b_l_thumb1/b_l_thumb2/b_l_thumb3") };
Transform[] lIndex = {
lWrist.Find("b_l_index1"),
lWrist.Find("b_l_index1/b_l_index2"),
lWrist.Find("b_l_index1/b_l_index2/b_l_index3") };
Transform[] lMiddle = {
lWrist.Find("b_l_middle1"),
lWrist.Find("b_l_middle1/b_l_middle2"),
lWrist.Find("b_l_middle1/b_l_middle2/b_l_middle3") };
Transform[] lRing = {
lWrist.Find("b_l_ring1"),
lWrist.Find("b_l_ring1/b_l_ring2"),
lWrist.Find("b_l_ring1/b_l_ring2/b_l_ring3") };
Transform[] lPinky = {
lWrist.Find("b_l_pinky0"),
lWrist.Find("b_l_pinky0/b_l_pinky1"),
lWrist.Find("b_l_pinky0/b_l_pinky1/b_l_pinky2"),
lWrist.Find("b_l_pinky0/b_l_pinky1/b_l_pinky2/b_l_pinky3") };
Transform rWrist = rHand.transform.Find("b_r_wrist");
Transform[] rThumb = {
rWrist.Find("b_r_thumb0"),
rWrist.Find("b_r_thumb0/b_r_thumb1"),
rWrist.Find("b_r_thumb0/b_r_thumb1/b_r_thumb2"),
rWrist.Find("b_r_thumb0/b_r_thumb1/b_r_thumb2/b_r_thumb3") };
Transform[] rIndex = {
rWrist.Find("b_r_index1"),
rWrist.Find("b_r_index1/b_r_index2"),
rWrist.Find("b_r_index1/b_r_index2/b_r_index3") };
Transform[] rMiddle = {
rWrist.Find("b_r_middle1"),
rWrist.Find("b_r_middle1/b_r_middle2"),
rWrist.Find("b_r_middle1/b_r_middle2/b_r_middle3") };
Transform[] rRing = {
rWrist.Find("b_r_ring1"),
rWrist.Find("b_r_ring1/b_r_ring2"),
rWrist.Find("b_r_ring1/b_r_ring2/b_r_ring3") };
Transform[] rPinky = {
rWrist.Find("b_r_pinky0"),
rWrist.Find("b_r_pinky0/b_r_pinky1"),
rWrist.Find("b_r_pinky0/b_r_pinky1/b_r_pinky2"),
rWrist.Find("b_r_pinky0/b_r_pinky1/b_r_pinky2/b_r_pinky3") };
lJoints = new List{
new Transform[] { lWrist }, lThumb, lIndex, lMiddle, lRing, lPinky};
rJoints = new List{
new Transform[] { rWrist }, rThumb, rIndex, rMiddle, rRing, rPinky};
}
void CalcHandsQtr()
{
int pointCount = 0;
foreach (Transform[] joints in lJoints)
{
if (joints.Length == 1)
continue;
Vector3 p0 = joints[0].position; // Starting position (global)
lPoints[pointCount++].transform.position = p0; // Update first point position
// Use global rotation to calculate the next joint positions
for (int i = 1; i < joints.Length; i++)
{
// Get the previous joint's global rotation
Quaternion globalRotation = joints[i - 1].rotation;
// Get the vector pointing in the direction of the next joint (in local space)
Vector3 localDirection = new Vector3(lDistFromPrev[joints[i].name], 0, 0);
// Transform the local direction to global space
Vector3 globalDirection = globalRotation * localDirection * (-1);
// Calculate the next joint position
Vector3 pNext = p0 + globalDirection;
lPoints[pointCount++].transform.position = pNext;
// Update the current position for the next iteration
p0 = pNext;
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/789 ... -to-python
Преобразование вычислений кватернионов Unity в Python ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение