using System.Collections.Generic; using Passer; using Passer.Humanoid.Tracking; using UnityEngine; namespace Passer.Humanoid { [System.Serializable] [CreateAssetMenu(menuName = "Humanoid/Pose", fileName = "HumanoidPose",order = 103)] public class Pose : ScriptableObject { public virtual float GetConfidence() { return 0; } #region Bones /// /// The bones affected by this pose /// public List bonePoses; public BonePose CheckBone(Bone boneId, bool useSideBones = false) { BonePose bone; if (useSideBones) { SideBone sideBone = BoneReference.HumanoidSideBone(boneId); bone = GetSideBone(sideBone); } else bone = GetBone(boneId); if (bone == null) bone = AddBone(boneId, useSideBones); return bone; } public BonePose GetBone(Bone boneId) { if (bonePoses != null) for (int i = 0; i < bonePoses.Count; i++) { if (bonePoses[i].boneRef.boneId == boneId) return bonePoses[i]; } return null; } public BonePose GetSideBone(SideBone sideBoneId) { if (bonePoses != null) for (int i = 0; i < bonePoses.Count; i++) { if (bonePoses[i].boneRef.sideBoneId == sideBoneId) return bonePoses[i]; } return null; } public BonePose AddBone(Bone _boneId, bool useSideBones = false) { BonePose newBonePose = new BonePose(); SideBone sideBone = BoneReference.HumanoidSideBone(_boneId); if (sideBone == SideBone.None) { newBonePose.boneRef = new BoneReference() { type = BoneType.AllBones, boneId = _boneId }; } else { newBonePose.boneRef = new BoneReference() { type = BoneType.SideBones, boneId = _boneId, }; newBonePose.boneRef.side = newBonePose.boneRef.isLeftSideBone ? Side.Left : Side.Right; } newBonePose.translation = Vector3.zero; newBonePose.rotation = Quaternion.identity; bonePoses.Add(newBonePose); return newBonePose; } #endregion #region Blendshapes /// /// The blendshapes affected by this pose /// public List blendshapePoses; public BlendshapePose CheckBlendshape(SkinnedMeshRenderer renderer, int blendshapeId) { BlendshapePose blendshape = GetBlendshape(renderer, blendshapeId); if (blendshape == null) blendshape = AddBlendshape(renderer, blendshapeId); return blendshape; } public BlendshapePose GetBlendshape(SkinnedMeshRenderer renderer, int blendshapeId) { if (blendshapePoses != null) { for (int i = 0; i < blendshapePoses.Count; i++) { if (blendshapePoses[i].renderer == renderer && blendshapePoses[i].blendshapeId == blendshapeId) return blendshapePoses[i]; } } return null; } public BlendshapePose AddBlendshape(SkinnedMeshRenderer _renderer, int _blendshapeId) { BlendshapePose blendshapePose = new BlendshapePose() { renderer = _renderer, blendshapeId = _blendshapeId }; blendshapePoses.Add(blendshapePose); return blendshapePose; } #endregion public void Cleanup() { if (bonePoses != null) bonePoses.RemoveAll(bonePose => bonePose == null || (!bonePose.setTranslation && !bonePose.setRotation && !bonePose.setScale)); if (blendshapePoses != null) blendshapePoses.RemoveAll(blendshapePose => blendshapePose == null || blendshapePose.value == 0); } /// Update the pose with the current bone positions public virtual void UpdatePose(HumanoidControl humanoid) { UpdatePose(humanoid, Bone.Hips); UpdatePose(humanoid, Bone.Head); UpdatePose(humanoid, Bone.LeftHand); UpdatePose(humanoid, Bone.RightHand); UpdatePose(humanoid, Bone.LeftFoot); UpdatePose(humanoid, Bone.RightFoot); Cleanup(); } private void UpdatePose(HumanoidControl humanoid, Bone boneId) { BonePose poseTargetBone = CheckBone(boneId); poseTargetBone.UpdateTranslation(humanoid); poseTargetBone.UpdateRotation(humanoid); } public void Show(HumanoidControl humanoid, float value = 1) { ShowBlendshapes(humanoid, value); ShowBones(humanoid, value); } public void Show(HumanoidControl humanoid, Side showSide, float value = 1) { ShowBlendshapes(humanoid, value); ShowBones(humanoid, showSide, value); } public void ShowAdditive(HumanoidControl humanoid, Side showSide, float value = 1) { //ShowBlendshapesAdditive(humanoid, value); ShowBonesAdditive(humanoid, showSide, value); } public void ShowBones(HumanoidControl humanoid, float value) { if (bonePoses == null) return; foreach (BonePose bonePose in bonePoses) bonePose.ShowPose(humanoid, value); } public void ShowBones(HumanoidControl humanoid, Side showSide, float value) { if (bonePoses == null) return; foreach (BonePose bonePose in bonePoses) bonePose.ShowPose(humanoid, showSide, value); } public void ShowBonesAdditive(HumanoidControl humanoid, Side showSide, float value) { if (bonePoses == null) return; foreach (BonePose bonePose in bonePoses) bonePose.ShowPoseAdditive(humanoid, showSide, value); } public void ShowBlendshapes(HumanoidControl humanoid, float value) { if (blendshapePoses == null) return; foreach (BlendshapePose blendshapePose in blendshapePoses) blendshapePose.ShowPose(humanoid, value); } public float GetScore(HumanoidControl humanoid, Side side) { if (bonePoses == null) return 0; float score = 0; float n = 0; foreach (BonePose bonePose in bonePoses) { score += bonePose.GetScore(humanoid, side); n++; } if (n == 0) return 0; else return score / n; } } }