動いているモデルの衝突方法について
https://www.youtube.com/watch?v=sE9_evw3Sik今回は動いているモデルの衝突をダイナミクスで実現する方法をご紹介します。
まずはダイナミクスによる衝突の基本をご紹介します。サンプルシーンには床と壁、そして30フレームで移動する赤いボックスが用意されています。この赤いボックスが移動して壁と衝突し、床に落ちるという表現を行ってみたいと思います。ダイナミクスの場合、ダイナミクスの影響を与えることがあっても、自身が影響を受けることなく静止状態にあるモデルをスタティックに設定します。このため、床と壁それぞれをスタティックに設定してみます。次にダイナミクスの影響を受ける赤いボックスはアクティブ(リジッド)へと設定し、シミュレーションを行ってみます。
再生してみると、赤いボックスはあらかじめ設定しておいた動きに沿うことなく、開始時点から重力の影響を受けて落下します。これはシーンの開始時点からダイナミクスの影響を受けているためです。最初は設定しているアニメーション通りに移動し、壁にぶつかった時点ではじめてダイナミクスの影響を受けるように設定しましょう。そのためには、ダイナミクスのタブにあるスリープ > ウェイクオンを開始から衝突フォースへと変更します。これにより、衝突を感知した時点からダイナミクスの影響を受けるようになります。シミュレーションで確認してみましょう。
すると、ボックスは壁をすり抜けてしまい、壁に衝突していないことがわかります。衝突が検知されていないということです。この衝突を検知するには、衝突する相手もリジッドなダイナミクスである必要があります。このため、壁のメッシュを選択し、ダイナミクスのタブからスタティックのオプションをオフにします。もう一度シミュレーションしてみると、ボックスが壁に衝突するようになりましたが、同時に壁自身もその衝撃で吹っ飛ぶようになりました。
これを修正するためには、壁が多少の衝撃ではぐらつかないぐらい、質量を重く設定してみます。質量 > 質量ソースをローカル質量へと変更し、1000Tほどに設定してみます。再度シミュレーションしてみると、ボックスが壁に衝突するという望み通りのシミュレーションが完成しました。
ではさらに複数のモデルの組み合わせの場合を考えてみましょう。こちらのサンプルシーンでは、複数のパーツを組み合わせて作ったシンプルな車のモデルが、先ほどのシーンのように壁にぶつかるような動きをつけてあります。こちらのシーンにダイナミクスの設定を行ってみましょう。床にはスタティック、壁にはリジッドを設定し、車のパーツをすべて選択したらすべてに対して同じ設定を行うということで複合を設定してみます。壁は質量を1000Tに設定し、複合の設定がつけられている車のパーツを選択したら、ウェイクオンを衝突フォースへと設定し、シミュレーションを行ってみます。
先ほどの原理ではこれでうまく動作するはずですが、再生してみると開始後すぐにパーツがダイナミクスの影響を受け、その場でばらばらになってしまいます。これは車のパーツがくっついているために、壁に衝突する前に、既に車のパーツ同士で衝突が発生しているとみなされ、シーン開始と共にダイナミクスの影響を受けることになるためです。この場合の回避法はいくつかありますが、単純にこのサンプルシーンのように、パーツとパーツの間に隙間があるような状態で組まれているのであれば、衝突におけるマージンの値を0に設定することにより、パーツ間の衝突は発生しなくなります。
このように組み合わせているモデルの隙間を物理的に開けることができれば問題ありませんが、冒頭で見せたサンプルシーンのように、隙間なくパーツが組まれている場合には、上記のような衝突フォースでのダイナミクスの開始という手段が取れないため、いくつか疑似的な手法を取ることになるかと思います。
ひとつはウェイクオンを衝突フォースではなく、ダイナミクスを開始するフレームを手動で設定する方法があります。この場合、衝突するであろうフレームを設定することで、そのフレームからダイナミクスを発生させることができますが、衝突してパーツが崩れるのではなく、その瞬間から崩れだすという形になるため、若干動きが不自然になる可能性があります。
またもう一つの手法では、衝突フォースを使うのですが、トランスフォームによるちょっとしたトリックを使います。デフォルトの状態ですと、やはり開始時点で衝突を検知し、そのままダイナミクスの演算が開始されてしまいます。この場合、大切なのはパーツ間に隙間を作るということですので、組み合わせているパーツのスケールを小さく設定してみます。パーツをすべて選択し、トランスフォームのスケールの値を40%ほどに落とした状態で、シミュレーションを行ってみます。満足がいく動きを得られたら、逆にスケールの値を100%に戻します。100%の大きさで正しいシミュレーションした結果ではないため、床や壁にめり込んだり、パーツ同士がめり込んだりといったことがありますが、大体の動きを疑似的にダイナミクスで計算させて、あとから修正を施すといった場合には便利に使える手法です。
ダイナミクスはあくまで表現したい動きを作るための手段と考えて、常に絶対正確なシミュレーションを生成させることを考えるよりも、そのダイナミクスの結果を利用して理想のシーンへと近づけるための手法を考えていくと良いかと思います。