ジョイントチェーンのダイナミクス

キャラクタの「揺れもの」の表現で「ジョイント(ボーン)チェーン」に対してダイナミクスを設定するという手法は、いろいろなソフトで使われています。MMDの「物理演算」とか、最近だとUnityのダイナミックボーンとかが有名ですね。

CINEMA 4Dにはジョイントチェーンに対して使えるダイナミクスが複数あるのですが、設定の手軽さから〈IKダイナミクス〉が選ばれることが多いようです。ところが! 実際に! 使ってみると! 〈IKダイナミクス〉は設定でコントロールできる「幅」がかなり狭く、どうやっても「いい感じ」に揺らすことができないケースが結構あるのです。

ジョイントチェーンを揺らす別な手段としては〈スプラインダイナミクス〉もあります。こちらは設定がやや複雑で最初のハードルは高いのですが、〈IKダイナミクス〉よりもパラメータが多く、表現の幅は格段に広くなります。ただし〈スプラインダイナミクス〉は〈ヘアモジュール〉の一部なので、CINEMA 4D Studioでしか使えません(そもそも高度なキャラクタ機能の多くはStudio限定ではありますが)。

この記事では、2つの「ジョイントチェーンのダイナミクス」を比較、検証してみたいと思います。まあ先に結論から言うと「ちゃんと揺らしたいならスプラインダイナミクスがおすすめ」です。

このポニーテールを動かします

 

サンプルファイル

サンプルファイルはこちらになります(解凍するとc4dファイルが3つ入っています):20190113_joint_dyn_samples.zip

始めに説明するキャラクタのポニーテールを揺らすセットアップのサンプルファイルは「20190113_ponytail_dynamics.c4d」になります。1つのファイルに全パターンの設定が含まれていて、それぞれの設定を〈テイク〉で切り替えるようになっています。ファイルを開いたら説明に対応するテイクに切り替えつつご覧ください。

なお前述のように〈スプラインダイナミクス〉はStudio限定の機能なので、他のエディションでは〈IKダイナミクス〉のほうしか動きません。

ファイルの設定はテイクで切り替える

ほかの2つのファイルは後述の〈IKダイナミクス〉と〈スプラインダイナミクス〉でそれぞれ〈衝突判定〉のテストで使っているファイルです。

IKダイナミクスの例

まず〈IKダイナミクス〉のほうから紹介します。

〈IKダイナミクス〉は普通の〈IKタグ〉にある〈ダイナミクス〉オプションです。基本的には、動かすジョイントチェーンに〈IKタグ〉を設定して(〈ゴール〉はなし)、〈ダイナミクス〉の〈有効に〉スイッチをオンにするだけです。

今回のポニーテールのようなものは、キャラクタ本体にめりこまないよう〈衝突判定〉を有効にし、〈衝突対象〉のオブジェクトをリストに登録します。この例ではダミーのポリゴンオブジェクト(キャラクタの上半身のピンク色のパーツ)をそのまま該当するジョイントの子として配置しています。〈スキン〉で変形するオブジェクトを〈衝突対象〉にすると〈X優先順位〉の関係で少しややこしいことになるので今回は避けました。また、〈衝突判定〉の〈半径〉をポニーテールのオブジェクトの太さに合わせて「2cm」としました。

〈IKダイナミクス〉のセットアップ

なお、〈IKダイナミクス〉を「揺れもの」に使う場合、通常は〈位置〉は固定して〈角度〉のみ動かします。回転するのは〈IKタグ〉が設定されているジョイントの「次のジョイントから」になります。つまり最初の〈ボーン〉は動きません。

IKダイナミクスでジョイントが動く範囲

他のパラメータはデフォルトのままで、とりあえず動かしたのがテイク「IK_dyn_default」です。

結果を見ると、ジョイントチェーンに対する〈重力〉の影響が強すぎて、真下に向かって下がりっぱなしですね。動作も全体的にガチャガチャしていて、一部で〈衝突判定〉が失敗してキャラクタ本体を突き抜けています。

チェーンが真下に下がりすぎで、ガチャガチャしている

 

とりあえず〈重力〉を「-0.5cm」まで小さくしたのがテイク「IK_dyn_tuned_1」です。〈IKダイナミクス〉の〈重力〉のデフォルトは「-9.81cm」となっていて、何か意味ありげな数値なのですが、物理的に正確というわけではないようです。よく考えると「-9.81m/s」じゃなく「-9.81cm」ですし。なんだこの単位。

変更後の結果です。〈重力〉を小さくしただけですが、無理がかからなくなったためか、だいぶまともになっています。ですが、「慣性」による行ったり来たりの往復運動がほとんどなく、「動いて元に戻る」だけなので物足りない感じはします。

〈重力〉を小さくしたらだいぶまともに

 

あと心配なのは、動作がまだ多少ガチャガチャしているのと、〈衝突判定〉の「突き抜け」が起きる可能性です。これらは、〈詳細〉にある〈ステップ〉の値を上げることで改善されます。CINEMA 4Dのヘルプでは〈ステップ〉について以下のように説明されています。

ステップ [1..100]

これはサブフレームの数です。アニメーションの各フレームは、このサブフレームに分けられ、ダイナミクスの計算に用いられます。ステップの設定値が大きいほど、計算精度も増します。特に、衝突検知によって速い動きを計算する場合に用いると便利です。

〈IKダイナミクス〉に限らず、一般にダイナミクスで〈衝突判定〉を行う場合は1フレームに1回の計算だけでは不足で、複数回の「サブフレームステップ」で計算するのがセオリーになっています。

そこで〈ステップ〉を「3」に上げてみたのがテイク「IK_dyn_tuned_2」です。

結果はこのようになりました。動きが全体的にモッサリしてしまいましたね。一応、キャラクタ本体の動きに追従してはいますが、元々弱かった「慣性」がほとんどなくなり、全然「揺れている」感じではなくなってしまいました。むしろ動物の尻尾のような、揺れに抵抗して自律的に姿勢を維持しようとしている動きのようにも見えます。

〈ステップ〉を「3」に上げたら動きがモッサリに

 

実は〈IKダイナミクス〉には、〈ステップ〉を上げると動作が鈍くモッサリした感じになってしまうという、不可解な挙動があります。しかも、この変化は他のパラメータでは相殺できないようです。かなりしつこく検証しましたが、元々〈IKダイナミクス〉のパラメータはごく少ないので、どうにもなりませんでした(どうにかする方法をご存じの方がいらっしゃいましたら是非教えてください)。

という具合に〈IKダイナミクス〉は、〈ステップ〉を上げないと精度が悪く、〈ステップ〉を上げると動作がモッサリしてしまうというジレンマを抱えているようです。モッサリした動きを「いい感じ」にするためには、〈フォース〉による外力で強引に動かしたり、手作業でジョイントにアニメーションを追加したり、数秒あるいは数フレームの間隔でパラメータをアニメーションさせるといった手当てが必要になってきます。

〈衝突判定〉が不要だったり、チェーンのジョイント数が少ない(2つや3つなど)、「揺れ」ではなく単調な「遅延」だけでもよいという場合には〈IKダイナミクス〉でもOKなのですが、この例のポニーテールぐらいだとギリギリな感じです。これより複雑な状況ではシミュレーションより手作業の修正の比率のほうが多くなってしまう可能性が高いので、〈IKダイナミクス〉の使用はおすすめできません。

 

スプラインダイナミクスの例

ではもう一方の〈スプラインダイナミクス〉のほうを見てみましょう。

こちらはジョイントチェーンに〈IK-スプライン〉タグを設定し、そのタグから〈スプラインダイナミクス〉タグがついている〈スプラインオブジェクト〉を参照するというセットアップになります。〈IK-スプライン〉では通常は〈ハンドル〉と呼ばれるコントロールオブジェクトを設定しますが、この場合は〈スプライン〉はダイナミクスで動かされるので〈ハンドル〉は設定しません。

〈スプラインダイナミクス〉で使用する〈スプラインオブジェクト〉は、〈IK-スプライン〉の対象となるジョイントチェーンから変換して作成すると簡単です。チェーンの根元から終端までのジョイントを選択して〈キャラクタ〉メニューの〈変換〉にある〈ジョイントをスプラインに〉を実行し、作成された〈スプラインオブジェクト〉の〈タイプ〉や〈補間法〉などのパラメータを任意に変更します。今回はやっていませんが、〈スプラインオブジェクト〉のポイント数とポイントの間隔もかなり重要で、試行錯誤して調整したほうが良い結果が得られます。

また、この〈スプラインオブジェクト〉は〈IK-スプライン〉の対象となるジョイントチェーンと同じ階層に置きます。

〈スプラインダイナミクス〉のセットアップ

〈スプラインダイナミクス〉の設定はこうなっています。一見して〈IKダイナミクス〉よりもパラメータが多いのがわかりますね。ここでは〈衝突半径〉のみポニーテールの太さに合わせて「2」に変更し、それ以外はデフォルトのままになっています。〈スプラインダイナミクス〉の〈衝突判定〉はデフォルトでオンですが、〈衝突判定〉の対象となるオブジェクトは、タグのほうで登録するのではなく、オブジェクトに〈ヘア衝突〉タグをつけることで設定されます。

〈スプラインダイナミクスタグ〉の設定

〈スプラインダイナミクス〉では対象となる〈スプラインオブジェクト〉の一部をオブジェクトのローカル座標に対して固定する必要がありますが(固定しないと全体が落ちていきます)、その設定は〈固定〉の〈セット〉ボタンで行います。〈スプラインオブジェクト〉の任意のポイントを選択してこのボタンを押すと、そのポイントが固定されます。固定されたポイントはピンク色でマークされます。

〈スプラインオブジェクト〉の「角度」を保持するには、少なくとも2つのポイントを固定する必要があります。1つしか固定していない場合は、そのポイントを中心に全体が回ってしまいます。この例では根元から2つのポイントを固定しました。これで動く範囲は〈IKダイナミクス〉のときと同じになります。

〈スプラインダイナミクス〉で動く範囲

〈衝突半径〉以外のパラメータがデフォルトのままの例がテイク「spline_dynamics_default」です。

動いている様子を見ると、かなり派手に揺れていますね。〈IKダイナミクス〉と見比べてみると、こちらの動きには「慣性」がちゃんと作用していて現実味があります。実際に頭にヒモをつけて振り回したらこうなるよなあという感じです。

かなり派手に揺れている

 

動きを少し抑えるためにパラメータを調整します。〈抗力〉は空気抵抗のように、動きを減衰させます。〈固さ〉を上げると〈スプラインオブジェクト〉が曲がりにくくなります。〈静止状態を保つ〉は、〈スプラインオブジェクト〉を初期状態に復帰させるようにジワジワと働く力です。

〈詳細〉にある〈ステップ〉と〈反復〉は計算精度のパラメータです。〈ステップ〉は前述の「サブフレームステップ」ですが、デフォルトが「3」あって十分そうなのでこのままにしておきます。〈反復〉はシミュレーションの反復計算をする回数で、これが足りないと〈特性〉で指定したパラメータが反映される前に計算が打ち切られる恐れがあります。ヘルプによると「経験則として、ヘアセグメントの数と同じ値を使用してください。」とあるので、〈スプラインオブジェクト〉のセグメント数と同じにしておきます(ポイントが7つあるのでセグメントは6)。〈ステップ〉と〈反復〉はシミュレーションの全体的な挙動に影響するので、他のパラメータを細かく調整する前にまず確定しておくのが定石です。

パラメータを調整

以上のようにパラメータを調整したのがテイク「spline_dyn_tuned_1」です。

動きがだいぶ落ち着きました。密度の低い物体が空気抵抗を受けつつ揺れているような印象です。これでもまだ〈IKダイナミクス〉に比べると軽快に揺れていますね。〈ステップ〉は「3」ですが衝突もガチャガチャしておらず精度は十分なようです。

だいぶ落ち着いた

 

もう少しパラメータをいじってみます。〈静止状態を混合〉は〈スプラインオブジェクト〉の「初期状態」をブレンドするパラメータで、この値を上げると相対的に〈スプラインダイナミクス〉の影響は小さくなります。既に有効にしてある〈静止状態を保つ〉はダイナミクス計算の「過程」においてその都度ジワジワと働く「元に戻す力」ですが、〈静止状態を混合〉のほうはシミュレーションの「結果」に対して単純にブレンドされるようです。

〈静止状態を混合〉を上げる

結果はさらに動きが緩慢になり、〈IKダイナミクス〉の〈ステップ〉が「1」のときの動きに近い感じになりました。やろうと思えばあえてモッサリした動きにもでき、しかもいじるパラメータは1つだけです。

動きがさらに緩慢になった

 

〈スプラインダイナミクス〉では他にも、ポイント毎に異なる〈質量〉(Mass)を設定することができたり、〈スプラインオブジェクト〉のポイントの間隔を変更して「曲がりやすさ」を部分的に調整できたり(これはとても効きます)と、シミュレーションのセットアップの段階でできることの幅がかなり広くなっています。〈剛体〉モードでは挙動がバネ的なものに変わります。

また、前述の〈静止状態を混合〉〈静止状態を保つ〉の値はアニメーションできるので、アニメーション全体の中で動きの激しい時間帯のみこれらの値を上げ、ダイナミクスの動きを抑制するというようなことも可能です。こういった「手作業による介入」も〈IKダイナミクス〉より自由度が高いです。

〈IKダイナミクス〉のほうは「なんちゃってシミュレーション」で、〈スプラインダイナミクス〉が「ガチのシミュレーション」だと言ってもいいかもしれません。

 

〈衝突判定〉の挙動の比較

紹介した2つのダイナミクスでは、〈衝突判定〉の働く範囲はいずれも〈半径〉という値で設定しますが、実際の挙動はどうなんでしょうか。そちらもテストしてみました。

テストはチェーンの長さに対して〈半径〉が「細め」と「太め」の2パターンがあり、ジョイントの〈軸〉の表示サイズが〈衝突判定〉の〈半径〉と等しくなるよう設定されています。また〈衝突判定〉の対象のオブジェクトがジョイントの〈軸〉に当たるパターンと、〈軸〉と〈軸〉の中間(ボーンの真ん中)に当たるパターンとを用意しました。

まず〈IKダイナミクス〉のほう。サンプルファイルは「20190113_IK-dyn_collision.c4d」です。

〈衝突判定〉にエラーがないよう、〈ステップ〉は「10」まで上げてあります。

結果を見ると、〈衝突判定〉は〈軸〉に対しては指定された〈半径〉の球体として判定されているようですが、〈ボーン〉の部分は太さがゼロの「線」で判定されていて、チェーンの「芯」まで入り込んでしまっています。また、複数の〈軸〉に対して〈衝突判定〉が検知された場合、片方が突き抜けて内側に入り込み、それが抜け出るときに「逆向き」に引っ掛かるようなガチャガチャした挙動を見せています。

もうひとつ気になることがあり、根元から2番目までのジョイントは本来は動かないのですが、〈衝突判定〉だけは行われて矛盾が生じており、結果的にジョイントチェーンの一部が伸び縮みしています。

〈IKダイナミクス〉の衝突判定

 

そしてこちらが〈スプラインダイナミクス〉のほうです。サンプルファイルは「20190113_spline-dyn_collision.c4d」です。

〈IK-スプライン〉では、ジョイントの〈軸〉と制御する〈スプラインオブジェクト〉のポイントの数や位置を一致させなくてもいいのですが、〈IKダイナミクス〉との比較のため、両者が一致するように設定してあります。また、チェーンが揺れすぎない程度に〈抗力〉を大きくしてあります。〈ステップ〉はデフォルトの「3」のままです。

〈IKダイナミクス〉と同様に、〈軸〉の部分は球体として判定されているようです。〈軸〉と〈軸〉の間では〈衝突判定〉が中に入り込んでいますが、「線」よりもやや広い範囲で衝突が検知されているようです。若干、当たりがソフトなようにも思えますね。複数の〈軸〉に対して〈衝突判定〉が検知された場合には「突き抜け」が起きて多少ガタついていますが、逆向きに「抜け出る」ときには〈衝突判定〉はされていないようです。

また、〈固定〉されているポイントに対しては〈衝突判定〉が行われずに完全にすり抜けていて、該当する位置のジョイントは固定されたままです。

〈スプラインダイナミクス〉の衝突判定

 

両者を比較してみると、〈衝突判定〉の挙動は〈スプラインダイナミクス〉のほうがずっと安定しています。〈IKダイナミクス〉ではかなりガチャガチャする状況があり、〈ステップ〉が「10」まで上げてあってもこの挙動ということは、これは計算誤差ではなく元々そういうアルゴリズムで動いていて、設定変更による改善は期待薄ではないかと思われます。

 

まとめ

〈IKダイナミクス〉は簡単なセットアップ向きです。最初の設定が手軽で、パラメータが少ないので扱いも簡単です。反面、設定の自由度が低く、また元々が「慣性によって繰り返し揺れる」という挙動はしない設計になっているようです。構成するジョイント数が少ない、〈衝突判定〉がシビアでない、あるいは「単調な遅延のみで十分」といったケースでは有望な手法だと思われます。

〈スプラインダイナミクス〉のほうは高度なセットアップ向きです。最初の設定に少し手間がかかり、パラメータが多く取り扱いにわかりにくいところがあります。その分、設定の自由度は高く、デフォルトの「完全にヒモ」の状態から、空気抵抗を受けて緩やかに揺れるようなものまで、幅広い表現が可能です。精度の高いシミュレーション、繊細な表現など、要求水準の高いケースに取り組むのに向いていると思われます。

 

余談

今回紹介した手法は、いずれも1本につながった「ヒモ」状の物体をシミュレーションするものです。面積のある「布」状のもの、あるいは容積のある「袋」状のものには向いていません。それらの場合は〈クロス〉や〈ソフトボディ〉を使うのが妥当です。

〈クロス〉や〈ソフトボディ〉で複雑なメッシュを扱う場合には、モデルの「実体」でシミュレーションを行うのではなく、シミュレーションに最適化したプロキシメッシュを別途用意し、〈メッシュデフォーマ〉を介して「実体」にデフォーメーションを伝達するといった工夫が必要です。また、いったんシミュレーションのキャッシュを取らないとアニメーションの他の要素と噛み合わないケースも多々あります。運用に当たって必要なノウハウが大幅に増えるので、いきなりチャレンジするのではなく、入念なR&Dを行うための作業期間を確保したうえで臨んだほうがよいと思います。

 

おまけ(追記)

「揺れもの」で比較すると〈IKダイナミクス〉の存在意義が危うく感じられますが、IKに〈ゴール〉を設定するのが本来の使い方だと考えるべきかもしれません。長いチェーンに設定したIKを通常どおり〈ゴール〉で動かすと印象は変わってきます。

サンプルファイル:20190115_IK-dyn-goal.zip

動作はこんな感じになります。

IKに〈ゴール〉を設定した〈IKダイナミクス〉

 

こういう動作でれば、あまり揺れ続けずにすぐに落ち着くほうが使いやすいでしょうか。チェーンの終端が〈ゴール〉からずれっぱなしなので、節足動物の脚のようなものだと接地の確保に工夫が必要ですが、宙に浮いている触手などであれば上手い具合にフワフワした印象になると思います。