123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562 |
- //======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using System;
- public class SkeletonHandler : ScriptableObject
- {
- // For Skeleton Display
- private const int
- // JointType
- JointType_Head = 26,
- JointType_Neck = 3,
- JointType_ClavicleRight = 11,
- JointType_ShoulderRight = 12,
- JointType_ElbowRight = 13,
- JointType_WristRight = 14,
- JointType_ClavicleLeft = 4,
- JointType_ShoulderLeft = 5,
- JointType_ElbowLeft = 6,
- JointType_WristLeft = 7,
- JointType_HipRight = 22,
- JointType_KneeRight = 23,
- JointType_AnkleRight = 24,
- JointType_FootRight = 25,
- JointType_HeelRight = 33,
- JointType_HipLeft = 18,
- JointType_KneeLeft = 19,
- JointType_AnkleLeft = 20,
- JointType_FootLeft = 21,
- JointType_HeelLeft = 32,
- JointType_EyesRight = 30,
- JointType_EyesLeft = 28,
- JointType_EarRight = 30,
- JointType_EarLeft = 29,
- JointType_SpineBase = 0,
- JointType_SpineNaval = 1,
- JointType_SpineChest = 2,
- JointType_Nose = 27,
- jointCount = 34;
- // List of bones (pair of joints). Used for Skeleton mode.
- private static readonly int[] bonesList = new int[] {
- JointType_SpineBase, JointType_HipRight,
- JointType_HipLeft, JointType_SpineBase,
- JointType_SpineBase, JointType_SpineNaval,
- JointType_SpineNaval, JointType_SpineChest,
- JointType_SpineChest, JointType_Neck,
- JointType_EarRight, JointType_EyesRight,
- JointType_EarLeft, JointType_EyesLeft,
- JointType_EyesRight, JointType_Nose,
- JointType_EyesLeft, JointType_Nose,
- JointType_Nose, JointType_Neck,
- // left
- JointType_SpineChest, JointType_ClavicleLeft,
- JointType_ClavicleLeft, JointType_ShoulderLeft,
- JointType_ShoulderLeft, JointType_ElbowLeft, // LeftUpperArm
- JointType_ElbowLeft, JointType_WristLeft, // LeftLowerArm
- JointType_HipLeft, JointType_KneeLeft, // LeftUpperLeg
- JointType_KneeLeft, JointType_AnkleLeft, // LeftLowerLeg6
- JointType_AnkleLeft, JointType_FootLeft,
- JointType_AnkleLeft, JointType_HeelLeft,
- JointType_FootLeft, JointType_HeelLeft,
- // right
- JointType_SpineChest, JointType_ClavicleRight,
- JointType_ClavicleRight, JointType_ShoulderRight,
- JointType_ShoulderRight, JointType_ElbowRight, // RightUpperArm
- JointType_ElbowRight, JointType_WristRight, // RightLowerArm
- JointType_HipRight, JointType_KneeRight, // RightUpperLeg
- JointType_KneeRight, JointType_AnkleRight, // RightLowerLeg
- JointType_AnkleRight, JointType_FootRight,
- JointType_AnkleRight, JointType_HeelRight,
- JointType_FootRight, JointType_HeelRight
- };
- // List of joint that will be rendered as a sphere in the Skeleton mode
- private static readonly int[] sphereList = new int[] {
- JointType_SpineBase,
- JointType_SpineNaval,
- JointType_SpineChest,
- JointType_Neck,
- JointType_HipLeft,
- JointType_HipRight,
- JointType_ClavicleLeft,
- JointType_ShoulderLeft,
- JointType_ElbowLeft,
- JointType_WristLeft,
- JointType_KneeLeft,
- JointType_AnkleLeft,
- JointType_FootLeft,
- JointType_HeelLeft,
- JointType_ClavicleRight,
- JointType_ShoulderRight,
- JointType_ElbowRight,
- JointType_WristRight,
- JointType_KneeRight,
- JointType_AnkleRight,
- JointType_FootRight,
- JointType_HeelRight,
- JointType_EyesLeft,
- JointType_EyesRight,
- JointType_EarRight,
- JointType_EarLeft,
- JointType_Nose
- };
- // List of available colors for Skeletons
- private Color[] colors = new Color[]{
- new Color( 232.0f / 255.0f, 176.0f / 255.0f,59.0f / 255.0f),
- new Color(175.0f / 255.0f, 208.0f / 255.0f,25.0f / 255.0f),
- new Color(102.0f / 255.0f / 255.0f, 205.0f / 255.0f,105.0f / 255.0f),
- new Color(185.0f / 255.0f, 0.0f / 255.0f,255.0f / 255.0f),
- new Color(99.0f / 255.0f, 107.0f / 255.0f,252.0f / 255.0f),
- new Color(252.0f / 255.0f, 225.0f / 255.0f, 8.0f / 255.0f),
- new Color(167.0f / 255.0f, 130.0f / 255.0f, 141.0f / 255.0f),
- new Color(194.0f / 255.0f, 72.0f / 255.0f, 113.0f / 255.0f)
- };
- public Vector3[] joints = new Vector3[jointCount];
- GameObject skeleton;
- public GameObject[] bones;
- public GameObject[] spheres;
- // Index of bone parent
- private static readonly int[] parentsIdx = new int[]{
- -1,
- 0,
- 1,
- 2,
- 2,
- 4,
- 5,
- 6,
- 7,
- 8,
- 7,
- 2,
- 11,
- 12,
- 13,
- 14,
- 15,
- 14,
- 0,
- 18,
- 19,
- 20,
- 0,
- 22,
- 23,
- 24,
- 3,
- 26,
- 26,
- 26,
- 26,
- 26
- };
- // Bones output by the ZED SDK (in this order)
- private static HumanBodyBones[] humanBone = new HumanBodyBones[] {
- HumanBodyBones.Hips,
- HumanBodyBones.Spine,
- HumanBodyBones.UpperChest,
- HumanBodyBones.Neck,
- HumanBodyBones.LeftShoulder,
- HumanBodyBones.LeftUpperArm,
- HumanBodyBones.LeftLowerArm,
- HumanBodyBones.LeftHand, // Left Wrist
- HumanBodyBones.LastBone, // Left Hand
- HumanBodyBones.LastBone, // Left HandTip
- HumanBodyBones.LeftThumbDistal,
- HumanBodyBones.RightShoulder,
- HumanBodyBones.RightUpperArm,
- HumanBodyBones.RightLowerArm,
- HumanBodyBones.RightHand, // Right Wrist
- HumanBodyBones.LastBone, // Right Hand
- HumanBodyBones.LastBone, // Right HandTip
- HumanBodyBones.RightThumbDistal,
- HumanBodyBones.LeftUpperLeg,
- HumanBodyBones.LeftLowerLeg,
- HumanBodyBones.LeftFoot,
- HumanBodyBones.LeftToes,
- HumanBodyBones.RightUpperLeg,
- HumanBodyBones.RightLowerLeg,
- HumanBodyBones.RightFoot,
- HumanBodyBones.RightToes,
- HumanBodyBones.Head,
- HumanBodyBones.LastBone, // Nose
- HumanBodyBones.LastBone, // Left Eye
- HumanBodyBones.LastBone, // Left Ear
- HumanBodyBones.LastBone, // Right Eye
- HumanBodyBones.LastBone, // Right Ear
- // HumanBodyBones.LastBone, // Left Heel
- // HumanBodyBones.LastBone, // Right Heel
- };
- private GameObject humanoid;
- private Dictionary<HumanBodyBones, RigBone> rigBone = null;
- private Dictionary<HumanBodyBones, Quaternion> rigBoneTarget = null;
- private Dictionary<HumanBodyBones, Quaternion> default_rotations = null;
- private List<GameObject> sphere = new List<GameObject>();// = GameObject.CreatePrimitive (PrimitiveType.Sphere);
- private Vector3 targetBodyPosition = new Vector3(0.0f, 0.0f, 0.0f);
- public Quaternion targetBodyOrientation = Quaternion.identity;
- private float heightOffset = 0.5f;
- /// <summary>
- /// Sets the smooth factor.
- /// </summary>
- /// <param name="smooth">Smooth.</param>
- public void SetHeightOffset(float offset)
- {
- heightOffset = offset;
- }
- /// <summary>
- /// Create the avatar control
- /// </summary>
- /// <param name="h">The height.</param>
- public void Create(GameObject h)
- {
- humanoid = (GameObject)Instantiate(h, Vector3.zero, Quaternion.identity);
- var invisiblelayer = LayerMask.NameToLayer("tagInvisibleToZED");
- //humanoid.layer = invisiblelayer;
- foreach (Transform child in humanoid.transform)
- {
- child.gameObject.layer = invisiblelayer;
- }
- // Init list of bones that will be updated by the data retrieved from the ZED SDK
- rigBone = new Dictionary<HumanBodyBones, RigBone>();
- rigBoneTarget = new Dictionary<HumanBodyBones, Quaternion>();
- default_rotations = new Dictionary<HumanBodyBones, Quaternion>();
- foreach (HumanBodyBones bone in humanBone)
- {
- if (bone != HumanBodyBones.LastBone)
- {
- rigBone[bone] = new RigBone(humanoid, bone);
- if (h.GetComponent<Animator>())
- {
- default_rotations[bone] = humanoid.GetComponent<Animator>().GetBoneTransform(bone).localRotation;
- }
- }
- rigBoneTarget[bone] = Quaternion.identity;
- }
- }
- public void Destroy()
- {
- GameObject.Destroy(humanoid);
- GameObject.Destroy(skeleton);
- rigBone.Clear();
- rigBoneTarget.Clear();
- Array.Clear(bones, 0, bones.Length);
- Array.Clear(spheres, 0, spheres.Length);
- }
- /// <summary>
- /// Function that handles the humanoid position, rotation and bones movement
- /// </summary>
- /// <param name="position_center">Position center.</param>
- private void setHumanPoseControl(Vector3 rootPosition, Quaternion rootRotation, Quaternion[] jointsRotation)
- {
- // Store any joint local rotation (if the bone exists)
- if (rigBone[HumanBodyBones.Hips].transform)
- {
- rigBoneTarget[HumanBodyBones.Hips] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.Hips)];
- }
- if (rigBone[HumanBodyBones.Hips].transform)
- {
- rigBoneTarget[HumanBodyBones.Spine] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.Spine)];
- }
- if (rigBone[HumanBodyBones.UpperChest].transform)
- {
- rigBoneTarget[HumanBodyBones.UpperChest] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.UpperChest)];
- }
- if (rigBone[HumanBodyBones.RightShoulder].transform)
- {
- rigBoneTarget[HumanBodyBones.RightShoulder] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.RightShoulder)];
- }
- if (rigBone[HumanBodyBones.RightUpperArm].transform)
- {
- rigBoneTarget[HumanBodyBones.RightUpperArm] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.RightUpperArm)];
- }
- if (rigBone[HumanBodyBones.RightLowerArm].transform)
- {
- rigBoneTarget[HumanBodyBones.RightLowerArm] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.RightLowerArm)];
- }
- if (rigBone[HumanBodyBones.RightHand].transform)
- {
- rigBoneTarget[HumanBodyBones.RightHand] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.RightHand)];
- }
- if (rigBone[HumanBodyBones.LeftShoulder].transform)
- {
- rigBoneTarget[HumanBodyBones.LeftShoulder] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.LeftShoulder)];
- }
- if (rigBone[HumanBodyBones.LeftUpperArm].transform)
- {
- rigBoneTarget[HumanBodyBones.LeftUpperArm] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.LeftUpperArm)];
- }
- if (rigBone[HumanBodyBones.LeftLowerArm].transform)
- {
- rigBoneTarget[HumanBodyBones.LeftLowerArm] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.LeftLowerArm)];
- }
- if (rigBone[HumanBodyBones.LeftHand].transform)
- {
- rigBoneTarget[HumanBodyBones.LeftHand] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.LeftHand)];
- }
- if (rigBone[HumanBodyBones.Neck].transform)
- {
- rigBoneTarget[HumanBodyBones.Neck] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.Neck)];
- }
- if (rigBone[HumanBodyBones.Head].transform)
- {
- rigBoneTarget[HumanBodyBones.Head] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.Head)];
- }
- if (rigBone[HumanBodyBones.RightUpperLeg].transform)
- {
- rigBoneTarget[HumanBodyBones.RightUpperLeg] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.RightUpperLeg)];
- }
- if (rigBone[HumanBodyBones.RightLowerLeg].transform)
- {
- rigBoneTarget[HumanBodyBones.RightLowerLeg] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.RightLowerLeg)];
- }
- if (rigBone[HumanBodyBones.RightFoot].transform)
- {
- rigBoneTarget[HumanBodyBones.RightFoot] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.RightFoot)];
- }
- if (rigBone[HumanBodyBones.LeftUpperLeg].transform)
- {
- rigBoneTarget[HumanBodyBones.LeftUpperLeg] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.LeftUpperLeg)];
- }
- if (rigBone[HumanBodyBones.LeftLowerLeg].transform)
- {
- rigBoneTarget[HumanBodyBones.LeftLowerLeg] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.LeftLowerLeg)];
- }
- if (rigBone[HumanBodyBones.LeftFoot].transform)
- {
- rigBoneTarget[HumanBodyBones.LeftFoot] = jointsRotation[Array.IndexOf(humanBone, HumanBodyBones.LeftFoot)];
- }
- // Store global transform (to be applied to the Hips joint).
- targetBodyOrientation = rootRotation;
- targetBodyPosition = rootPosition;
- }
- // Init skeleton display
- public void initSkeleton(int person_id)
- {
- bones = new GameObject[bonesList.Length / 2];
- spheres = new GameObject[sphereList.Length];
- skeleton = new GameObject();
- skeleton.name = "Skeleton_ID_" + person_id;
- float width = 0.025f;
- Color color = colors[person_id % colors.Length];
- for (int i = 0; i < bones.Length; i++)
- {
- GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
- cylinder.GetComponent<Renderer>().material.color = color;
- cylinder.transform.parent = skeleton.transform;
- bones[i] = cylinder;
- }
- for (int j = 0; j < spheres.Length; j++)
- {
- GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
- sphere.GetComponent<Renderer>().material.color = color;
- sphere.transform.localScale = new Vector3(width * 2, width * 2, width * 2);
- sphere.transform.parent = skeleton.transform;
- spheres[j] = sphere;
- }
- }
- // Update skeleton display with new SDK data
- void updateSkeleton()
- {
- float width = 0.025f;
- for (int j = 0; j < spheres.Length; j++)
- {
- if (ZEDSupportFunctions.IsVector3NaN(joints[sphereList[j]]))
- {
- spheres[j].transform.position = Vector3.zero;
- spheres[j].SetActive(false);
- }
- else
- {
- spheres[j].transform.position = joints[sphereList[j]];
- spheres[j].SetActive(true);
- }
- }
- for (int i = 0; i < bones.Length; i++)
- {
- Vector3 start = spheres[Array.IndexOf(sphereList, bonesList[2 * i])].transform.position;
- Vector3 end = spheres[Array.IndexOf(sphereList, bonesList[2 * i + 1])].transform.position;
- if (start == Vector3.zero || end == Vector3.zero)
- {
- bones[i].SetActive(false);
- continue;
- }
- bones[i].SetActive(true);
- Vector3 offset = end - start;
- Vector3 scale = new Vector3(width, offset.magnitude / 2.0f, width);
- Vector3 position = start + (offset / 2.0f);
- bones[i].transform.position = position;
- bones[i].transform.up = offset;
- bones[i].transform.localScale = scale;
- }
- }
- /// <summary>
- /// Sets the avatar control with joint position.
- /// </summary>
- /// <param name="jt">Jt.</param>
- /// <param name="position_center">Position center.</param>
- public void setControlWithJointPosition(Vector3[] jointsPosition, Quaternion[] jointsRotation, Quaternion rootRotation, bool useAvatar)
- {
- joints = jointsPosition;
- humanoid.SetActive(useAvatar);
- skeleton.SetActive(!useAvatar);
- if (useAvatar)
- {
- setHumanPoseControl(jointsPosition[0], rootRotation, jointsRotation);
- }
- else
- {
- updateSkeleton();
- }
- }
- void PropagateRestPoseRotations(int parentIdx, Dictionary<HumanBodyBones, RigBone> outPose, Quaternion restPosRot, bool inverse)
- {
- for (int i = 0; i < humanBone.Length; i++)
- {
- if (humanBone[i] != HumanBodyBones.LastBone && outPose[humanBone[i]].transform)
- {
- Transform outPoseTransform = outPose[humanBone[i]].transform;
- if (parentsIdx[i] == parentIdx)
- {
- Quaternion restPoseRotation = default_rotations[humanBone[i]];
- Quaternion restPoseRotChild = new Quaternion();
- if (parentsIdx[i] != -1)
- {
- Quaternion jointRotation = restPosRot * outPoseTransform.localRotation;
- outPoseTransform.localRotation = jointRotation;
- if (!inverse)
- {
- restPoseRotChild = restPosRot * restPoseRotation;
- }
- else
- {
- restPoseRotChild = Quaternion.Inverse(restPoseRotation) * restPosRot;
- }
- }
- else
- {
- restPoseRotChild = restPosRot;
- }
- PropagateRestPoseRotations(i, outPose, restPoseRotChild, inverse);
- }
- }
- }
- }
- /// <summary>
- /// Set Humanoid position. Called in Update() function
- /// </summary>
- public void MoveAvatar()
- {
- // Put in Ref Pose
- foreach (HumanBodyBones bone in humanBone)
- {
- if (bone != HumanBodyBones.LastBone)
- {
- if (rigBone[bone].transform)
- {
- rigBone[bone].transform.localRotation = default_rotations[bone];
- }
- }
- }
- PropagateRestPoseRotations(0, rigBone, default_rotations[0], false);
- for (int i = 0; i < humanBone.Length; i++)
- {
- if (humanBone[i] != HumanBodyBones.LastBone && rigBone[humanBone[i]].transform)
- {
- if (parentsIdx[i] != -1)
- {
- Quaternion newRotation = rigBoneTarget[humanBone[i]] * rigBone[humanBone[i]].transform.localRotation;
- rigBone[humanBone[i]].transform.localRotation = newRotation;
- }
- }
- }
- PropagateRestPoseRotations(0, rigBone, Quaternion.Inverse(default_rotations[0]), true);
- // Apply global transform
- if (rigBone[HumanBodyBones.Hips].transform)
- {
- var animator = humanoid.GetComponent<Animator>();
- // There is an offset between the joint "Hips" and the equivalent in the ZED SDK. This offset compensates it.
- Vector3 offset = new Vector3(0, (animator.GetBoneTransform(HumanBodyBones.Hips).position.y - animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg).position.y), 0);
- rigBone[HumanBodyBones.Hips].transform.position = targetBodyPosition + offset + new Vector3(0, heightOffset, 0);
- rigBone[HumanBodyBones.Hips].transform.rotation = targetBodyOrientation;
- }
- }
- /// <summary>
- /// Update Engine function (move this avatar)
- /// </summary>
- public void Move()
- {
- MoveAvatar();
- }
- }
|