Skip to content

Instantly share code, notes, and snippets.

@nekomimi-daimao
Created September 27, 2023 14:58
Show Gist options
  • Select an option

  • Save nekomimi-daimao/5dd0fafc1bd7cde5b27e5d9e3d32c317 to your computer and use it in GitHub Desktop.

Select an option

Save nekomimi-daimao/5dd0fafc1bd7cde5b27e5d9e3d32c317 to your computer and use it in GitHub Desktop.

Revisions

  1. nekomimi-daimao created this gist Sep 27, 2023.
    67 changes: 67 additions & 0 deletions HumanPoseAccessor.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    using UnityEngine;

    namespace SerializeAnimation.PoseAccessor
    {
    public sealed class HumanPoseAccessor : MonoBehaviour
    {
    [SerializeField]
    private Animator animator;

    private HumanPoseHandler _humanPoseHandler;

    public bool Initialized => _humanPoseHandler != null && animator != null && animator.isHuman;
    public Transform Ts { get; private set; }
    public Animator Animator => animator;

    private void OnEnable()
    {
    if (animator == null)
    {
    return;
    }

    Init(animator);
    }

    private void OnDisable()
    {
    _humanPoseHandler?.Dispose();
    _humanPoseHandler = null;
    }

    public void Init(Animator humanAnimator)
    {
    animator = humanAnimator;
    if (animator == null || !animator.isHuman)
    {
    return;
    }

    Ts = transform;
    var animTs = animator.transform;
    if (animTs.parent != Ts)
    {
    var currentParent = animTs.parent;
    animTs.parent = Ts;
    Ts.parent = currentParent;
    }

    animTs.localPosition = Vector3.zero;
    animTs.localRotation = Quaternion.identity;
    animTs.localScale = Vector3.one;

    _humanPoseHandler = new HumanPoseHandler(animator.avatar, animTs);
    }

    public void GetPose(out HumanPose humanPose)
    {
    humanPose = default;
    _humanPoseHandler.GetHumanPose(ref humanPose);
    }

    public void SetPose(ref HumanPose humanPose)
    {
    _humanPoseHandler.SetHumanPose(ref humanPose);
    }
    }
    }
    56 changes: 56 additions & 0 deletions HumanPoseSerializable.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    using System;
    using System.Buffers;
    using MemoryPack;
    using UnityEngine;

    namespace SerializeAnimation.Serializer
    {
    [MemoryPackable]
    public readonly partial struct HumanPoseSerializable
    {
    public readonly Vector3 BodyPosition;

    public readonly Quaternion BodyRotation;

    // 95
    public readonly float[] Muscles;

    public HumanPoseSerializable(Vector3 bodyPosition, Quaternion bodyRotation, float[] muscles)
    {
    BodyPosition = bodyPosition;
    BodyRotation = bodyRotation;
    Muscles = muscles;
    }

    public byte[] Serialize()
    {
    return MemoryPackSerializer.Serialize(this);
    }

    public static HumanPoseSerializable Deserialize(in ReadOnlySpan<byte> buffer)
    {
    return MemoryPackSerializer.Deserialize<HumanPoseSerializable>(buffer);
    }

    public static HumanPoseSerializable Deserialize(in ReadOnlySequence<byte> buffer)
    {
    return MemoryPackSerializer.Deserialize<HumanPoseSerializable>(buffer);
    }

    [MemoryPackIgnore]
    public HumanPose HumanPose => new HumanPose
    {
    bodyPosition = BodyPosition,
    bodyRotation = BodyRotation,
    muscles = Muscles,
    };
    }

    public static class ExtensionHumanPose
    {
    public static HumanPoseSerializable ToSerializable(this HumanPose humanPose)
    {
    return new HumanPoseSerializable(humanPose.bodyPosition, humanPose.bodyRotation, humanPose.muscles);
    }
    }
    }
    81 changes: 81 additions & 0 deletions HumanPoseSerializableByte.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,81 @@
    using System;
    using System.Buffers;
    using MemoryPack;
    using UnityEngine;

    namespace SerializeAnimation.Serializer
    {
    [MemoryPackable]
    public readonly partial struct HumanPoseSerializableByte
    {
    private const float ConvertRatio = 100f;

    public readonly Vector3 BodyPosition;

    public readonly Quaternion BodyRotation;

    // 95
    public readonly sbyte[] Muscles;

    public HumanPoseSerializableByte(Vector3 bodyPosition, Quaternion bodyRotation, sbyte[] muscles)
    {
    BodyPosition = bodyPosition;
    BodyRotation = bodyRotation;
    Muscles = muscles;
    }

    public static HumanPoseSerializableByte Create(Vector3 bodyPosition, Quaternion bodyRotation, float[] muscles)
    {
    var m = new sbyte[muscles.Length];
    for (var i = 0; i < muscles.Length; i++)
    {
    m[i] = (sbyte)(muscles[i] * ConvertRatio);
    }

    return new HumanPoseSerializableByte(bodyPosition, bodyRotation, m);
    }

    public byte[] Serialize()
    {
    return MemoryPackSerializer.Serialize(this);
    }

    public static HumanPoseSerializableByte Deserialize(in ReadOnlySpan<byte> buffer)
    {
    return MemoryPackSerializer.Deserialize<HumanPoseSerializableByte>(buffer);
    }

    public static HumanPoseSerializableByte Deserialize(in ReadOnlySequence<byte> buffer)
    {
    return MemoryPackSerializer.Deserialize<HumanPoseSerializableByte>(buffer);
    }

    [MemoryPackIgnore]
    public HumanPose HumanPose
    {
    get
    {
    var muscles = new float[Muscles.Length];
    for (var i = 0; i < Muscles.Length; i++)
    {
    muscles[i] = Muscles[i] / ConvertRatio;
    }

    return new HumanPose
    {
    bodyPosition = BodyPosition,
    bodyRotation = BodyRotation,
    muscles = muscles,
    };
    }
    }
    }

    public static class ExtensionHumanPoseByte
    {
    public static HumanPoseSerializableByte ToSerializableByte(this HumanPose humanPose)
    {
    return HumanPoseSerializableByte.Create(humanPose.bodyPosition, humanPose.bodyRotation, humanPose.muscles);
    }
    }
    }