summaryrefslogtreecommitdiff
path: root/Assets/ThirdParty/VRM/VRM/UniHumanoid/Scripts/HumanPoseTransfer.cs
blob: 8597a27b5602031aa4cb97770e04c3125c0a57ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using UnityEngine;


namespace UniHumanoid
{
    public class HumanPoseTransfer : MonoBehaviour
    {
        public enum HumanPoseTransferSourceType
        {
            None,
            HumanPoseTransfer,
            HumanPoseClip,
        }

        [SerializeField]
        public HumanPoseTransferSourceType SourceType;

        [SerializeField]
        public Avatar Avatar;

        #region Standalone
        public HumanPose CreatePose()
        {
            var handler = new HumanPoseHandler(Avatar, transform);
            var pose = default(HumanPose);
            handler.GetHumanPose(ref pose);
            return pose;
        }
        public void SetPose(HumanPose pose)
        {
            SetPose(Avatar, transform, pose);
        }
        public static void SetPose(Avatar avatar, Transform transform, HumanPose pose)
        {
            var handler = new HumanPoseHandler(avatar, transform);
            handler.SetHumanPose(ref pose);
        }
        public static void SetTPose(Avatar avatar, Transform transform)
        {
            var humanPoseClip = Resources.Load<HumanPoseClip>(HumanPoseClip.TPoseResourcePath);
            var pose = humanPoseClip.GetPose();
            HumanPoseTransfer.SetPose(avatar, transform, pose);
        }
        #endregion

        private void Reset()
        {
            var animator = GetComponent<Animator>();
            if (animator != null)
            {
                Avatar = animator.avatar;
            }
        }

        [SerializeField]
        public HumanPoseTransfer Source;

        [SerializeField]
        public HumanPoseClip PoseClip;

        [ContextMenu("Set T-Pose")]
        void SetTPose()
        {
            if (Avatar == null) return;
            SetTPose(Avatar, transform);
        }

        HumanPoseHandler m_handler;
        public void OnEnable()
        {
            var animator = GetComponent<Animator>();
            if (animator != null)
            {
                Avatar = animator.avatar;
            }

            Setup();
        }

        public void Setup()
        {
            if (Avatar == null)
            {
                return;
            }
            m_handler = new HumanPoseHandler(Avatar, transform);
        }

        HumanPose m_pose;

        int m_lastFrameCount = -1;

        public bool GetPose(int frameCount, ref HumanPose pose)
        {
            if (PoseClip != null)
            {
                pose = PoseClip.GetPose();
                return true;
            }

            if (m_handler == null)
            {
                pose = m_pose;
                return false;
            }

            if (frameCount != m_lastFrameCount)
            {
                m_handler.GetHumanPose(ref m_pose);
                m_lastFrameCount = frameCount;
            }
            pose = m_pose;
            return true;
        }

        private void Update()
        {
            switch (SourceType)
            {
                case HumanPoseTransferSourceType.None:
                    break;

                case HumanPoseTransferSourceType.HumanPoseTransfer:
                    if (Source != null && m_handler != null)
                    {
                        if (Source.GetPose(Time.frameCount, ref m_pose))
                        {
                            m_handler.SetHumanPose(ref m_pose);
                        }
                    }
                    break;

                case HumanPoseTransferSourceType.HumanPoseClip:
                    if (PoseClip != null)
                    {
                        var pose = PoseClip.GetPose();
                        m_handler.SetHumanPose(ref pose);
                    }
                    break;
            }
        }
    }
}