irtual Chara開発 - その5


店舗接客などに使える仮想のキャラクターが扱えるアプリ開発をしました。そちらの説明はこちらになります。
https://qiita.com/NestVisual/items/fe4dd168178e27156682

環境:
Windows 10
Unity 2018.4.1
RealSense D435i

キャラのアニメーション:

利用者の骨格が検出されなかったり、カメラと利用者の距離が遠すぎたり近すぎたりなど、様々な理由で骨格トラッキングが反映されないときに、モデルはその場で止まってしまいます。これは人形のように見えます。そして、モデルが不自然な状態にある場合は特に悪い。

これを変更するには、まずモデルの四肢の回転を元の状態にリセットしました。Quaternion.Lerp() メソッドを使用すると、スムーズに動きましたが、人間らしくありませんでした。人間は完全に静止していることはほとんどないので、少しだけ揺れる待機状態のループ再生アニメーションが必要だと思いました。

最大の問題は、モデルのトラッキング反映ポーズから、アニメーションの開始ポーズまでを自然に移動させることでした。単純にアニメーションを再生するだけでは、急に変化してしまいます。

現行のプロジェクトでは、アニメーションはすぐに再生されます。そして、再生前の四肢の回転を保存します。これからLateUpdate()でまたLerp()を使用して、関節の回転を設定します。これを行うには、Quaternion.Slerp()を使用します。これは2つの回転と、それらの影響を決定するブレンド比を受け取ります。この比率は、アニメーションの再生が始まったからの経過時間を基準にしています。保存した回転の影響が徐々に少なくなっていきます。

sample1.cs
private void LateUpdate()
{ BlendToMecanim(); }

/// <summary> トラッキング反映からスムーズにMecanimにブレンド移行。Mecanimによってオーバーライドされないように、LateUpdateで呼ぶ </summary>
private void BlendToMecanim()
{
    _animator.SetBool("Idle", false);
    if (STATE != ControlState.BLEND_TO_ANIM)    return;

    // Mecanimに移行したら過ごした時間
    float timePassed = Time.time - reflectTrackingEndTime;                             
    // どれぐらい最後のトラッキングポーズを表す
    float trackingBlendRatio = 1.0f - timePassed / trackingToMecanimBlendTime; 
    // 0から1まで
    trackingBlendRatio = Mathf.Clamp01(trackingBlendRatio);

    // 関節をtrackingBlendRatioぐらいで最後のトラッキング回転にオフセットする
    foreach (KeyValuePair<nuitrack.JointType, Quaternion> rotation in _jointRotationsBeforeMecanim)
    {
        ModelJoint modelJoint = _jointsRigged[rotation.Key];
        modelJoint.bone.rotation = Quaternion.Slerp(modelJoint.bone.rotation, rotation.Value, trackingBlendRatio);
    }

    if (trackingBlendRatio == 0)    STATE = ControlState.ANIMATED;
}

上記プログラムでは、カメラのトラッキングデータを、キャラのアニメーションに反映させます。同じシステムを他のアニメーションにも使用ができます。例えば、複雑な手のジェスチャーのようなトラッキングが難しいものです。BlendToMechAnimメソッドがUpdate()ではなくLateUpdate()で呼ばれるのは、アニメーションの次のフレームが更新されたの後に回転を設定するためです。Updateを使用した場合、アニメーションはブレンドされた回転を上書きしてしまいます。同じスクリプトには 「ControlState」という列挙もあります。これはキャラクターが骨格トラッキング、Unityでのアニメーション(mecanim)、mecanimに向かってブレンドされているときの状態を持っています。

次回はフェイストラッキングで顔を操るに関して投稿します。それではまた