On this page |
概要 ¶
エージェントを、アニメーションによる制御ではなく、リジッドボディシミュレーションにより制御されたステート(状態)へ遷移させたい場合があります。 例えば、エージェントが死亡する場合、胴体と手足が衝突によりあちこち打撃を受けながら、地面に落ちるようにしたいといった場合です。
ラグドールのシーンのセットアップ ¶
Simulateシェルフツールを使用すれば、簡単に基本的な群衆シミュレーションシーンをセットアップすることができます。 その後は、目的に応じてネットワークを調整してください。
-
Crowds シェルフタブの Simulateツールを⌃ Ctrl + クリックします。このツールは、Houdiniに組み込まれているmocapbiped1キャラクタを使用して自動的にエージェントと群衆ソースネットワークを構築します。
Simulateシェルフツールから生成された群衆シミュレーションネットワーク (
crowd_sim
): -
プレイバー上の Playボタンをクリックして、そのシミュレーションを再生します。すると、エージェントが立ち止まった状態から歩き出します。
-
現在のシーンだと、エージェントは“stand”状態から“walk”状態にしか遷移しないです。さらにトリガーを追加して、エージェントを“walk”状態から“ragdoll”状態に遷移させます。
-
crowd_sim
ネットワークの中に入って、下図のようにCrowd Trigger DOPとCrowd Transition DOPを追加して接続します。 -
この新しく追加したCrowd Trigger DOPでは、 Type を Current State Duration に設定します。
-
この新しく追加したCrowd Transition DOPでは、 Input State を
walk
に、 Output State をragdoll
に設定します。
-
-
シミュレーションを再生します。すると、エージェントは立った状態、歩いた状態に加えて、エージェントとの干渉物がないために落下する状態がシーンに加わりました。
-
エージェントとの干渉物となる地面(Ground Plane DOP)を追加します。そのGround Plane DOPの出力を
merge_static_collisions
ノードに接続します。 -
シミュレーションを再生します。すると、エージェントは立った状態、歩いた状態からラグドールとして地面に落下するようになりました。
ラグドール用のエージェントセットアップ ¶
Simulateシェルフツールは、エージェント定義ネットワーク (mocapbiped1_setup
)、群衆シミュレーション内のエージェントを定義したジオメトリネットワーク(crowdsource
)をセットアップします。
このエージェント定義ネットワーク内のラグドール固有の情報は以下のとおりです:
-
コリジョンシェイプ(Agent Collision Layer SOP) - エージェントがラグドールに変わった瞬間にサーフェスと衝突させるのに使用されるエージェントスケルトンを囲んだ単純なジオメトリを定義します。
-
ジョイント構成(Agent Configure Joints SOP) - 各ジョイントの動きの範囲を指定します。
コリジョンシェイプ ¶
コリジョンシェイプは、エージェントがラグドールに変わった瞬間にサーフェスと衝突させるのに使用されるエージェントスケルトンを囲んだ単純なジオメトリを定義します。
-
エージェント定義ネットワーク内で、Agent Collision Layerノードを選択して、そのディスプレイフラグを有効にします。
-
ビューポートの左側にある Show Handleツールを有効にします。
-
ビューポート内で青いマーカーをクリックして、エージェントのその部分にコリジョンシェイプを追加します。青いマーカーをクリックしていくと、Agent Collision Layerノードの Collision Shapes パラメータのリストにコリジョンシェイプが追加されていきます。
-
ビューポート内でコリジョンシェイプハンドルを使用するか、または、パラメータエディタでAgent Collision Layerノードの Collision Shapes パラメータを編集することで、コリジョンシェイプの位置、向き、サイズを変更することができます。
-
マウスカーソルをビューポート内に移動させてZを押すと、コリジョンシェイプとして使用できるシェイプを循環させて切り替えることができます。または、Agent Collision Layerノードから各コリジョンシェイプの Shape パラメータでシェイプを変更することができます。
Note
すべての指ジョイントを別々にシミュレーションする必要がないのであれば、手全体で1個のコリジョンシェイプを使用するのが良いでしょう。 これは、手(例えば、手首)の親ジョイントにコリジョンシェイプを取り付けて、その手が覆われるようにコリジョンシェイプを調整すれば良いです。 子ジョイント(指)が手首ジョイントの動きを継承できるように親ジョイントにコリジョンシェイプを取り付けることが肝です。
シミュレーションさせるジョイントを少なくすれば、コリジョンシェイプとジョイント制限のセットアップや構成の手間が減り、さらにはパフォーマンスが良くなります。
To... | Do this |
---|---|
ジョイントに割り当てられているコリジョンシェイプを変更する |
|
コリジョンシェイプを削除する。 |
ビューポート内で、赤いマーカーをクリックしてDeleteを押します。 |
ジョイントの構成 ¶
Agent Configure Jointsノードでは、各ジョイントの動きの範囲を指定します。 例えば、キャラクタの肘が後ろに曲がらないように設定したりします。
-
エージェント定義ネットワーク内で、Agent Configure Jointsノードを選択して、ディスプレイフラグを有効にします。
-
ビューポート内で、エージェントのジョイント制限を加えたい箇所の青いマーカーをクリックします。青いマーカーをクリックすると、Agent Configure Jointsノードの Joint Limits パラメータのリストにジョイント制限が追加されます。
Note
ビューポートの上部にあるツールバーには、 Limit Selection to Collision Layer オプションがあります。 このオプションを有効にすると、(既にAgent Collision Layer SOPで定義済みの)コリジョンシェイプが取り付けられているジョイントマーカーのみが表示され選択できるようになります。 一般的には、コリジョンシェイプが取り付けられているジョイントにしかジョイント制限を付けないです。
まず最初にコリジョンシェイプをセットアップしてからジョイント制限を設定する場合、(コリジョンシェイプが取り付けられている)関係のあるジョイントのみが表示されるように Limit Selection to Collision Layer を有効にします。 反対に、まず最初にジョイント制限を設定する場合、スケルトン内のどのジョイントも選択できるように Limit Selection to Collision Layer を無効にしてください。
-
ビューポート内でジョイント制限ハンドルを使用するか、または、パラメータエディタでAgent Configure Jointsノードの Joint Limits パラメータを編集することで、ジョイント制限を調整することができます。
To... | Do this |
---|---|
ジョイント制限を削除する。 |
ビューポート内で、(ジョイント制限が設定済みのジョイントであることを示した)赤いマーカーをクリックしてDeleteを押します。 |
(肘や膝などの)ヒンジを作成する。 |
Up Rotation Range パラメータまたは Out Rotation Range パラメータに対して、最小値と最大値を |
ジョイントグループ ¶
エージェントに対して名前の付いたジョイントグループを作成することができるので、エージェントの一部またはそれ以外の部分に対してラグドール効果を適用することができます。
-
Agent Configure Joints SOPの後にAgent Transform Group SOPを配置します。
-
パラメータエディタで、 Transform Groups マルチパラメータを使って、新しいグループを作成します。各グループに対して:
-
Name にジョイントグループの名前を設定します。例えば、
upper_body
。 -
Root Transforms で、そのグループとなるルートジョイント(s)を選択します。各ルートとその子孫がグループに追加されます。
-
Blend into Group を有効にすることで、そのグループに適用されるラグドール効果の量(例えば、剛性)を制御するランプを取得し、そのランプをルートジョイントから“一番外側の”ジョイントまで適用することができます。
-
Show Guide Geometry を有効にすることで、選択したジョイントに球が描画され、どのジョイントがグループの一部なのかを確認することができます。 Guides タブでこの球のサイズを変更することができます。エージェントを Wireframe で表示することで、もっと簡単にガイドジオメトリを確認することができます。
-
テスト ¶
Agent Collision Layerノード、Agent Configure Jointsノード、Agent Transform Groupノードのどれかの後にTest Simulation Ragdollノードを配置することができます。 このTest Simulation Ragdollノードのディスプレイフラグを有効にして、プレイバーの Playをクリックすると、重力のあるラグドール状態でエージェントのシンプルなシミュレーションを再生することができます。
Tip
このノードを使用することで、ジョイント制限が正しくセットアップされているかどうかを確認することができます。 Constraints タブの Allow Initial Violation of Limits パラメータを無効にします。 スケルトンの初期状態がジョイント制限の外側にある場合、テストシミュレーションを開始すると、ジョイントが即座に飛び出し、問題のある場所を示してくれます。
To... | Do this |
---|---|
エージェントを様々な方向に投げた時のそのエージェントの反応をテストする。 |
|
DOPでのラグドール ¶
群衆シミュレーションネットワークでは、エージェントがラグドールになっている時のステート、そのエージェントをラグドールに変えるトリガーを設定することができます。
ラグドールのステート(状態) ¶
Crowd State DOPの RBD Ragdoll パラメータを以下のどれかに設定することで、特定の状態にあるエージェントをラグドールにするかどうかを選択することができます:
Active
エージェントは、アニメーションクリップに追従することなくラグドールとしてシミュレーションされます。
Animated Static
エージェントはラグドールにならず、その動きはアニメーションクリップに追従します。 エージェントは他のシミュレーションオブジェクトに影響を与えることができます(例えば、歩いている時に物を蹴散らすなど)が、シミュレーションオブジェクトはエージェントに影響を与えません。
Ignore
エージェントはラグドールにならず、どのリジッドボディダイナミクスオブジェクトにも当たりません。
詳細はCrowd State DOPを参照してください。
ragdollステートへのトリガー ¶
Crowd Trigger DOPを使用して、エージェントをラグドールに変えるトリガーを設定することができます。 このトリガーを使用することで、例えば、歩いているエージェントが大きな石に当たった時にラグドールに変えることができます。
To... | Do this |
---|---|
エージェントがRBDオブジェクトに当たった時にステートトランジション(状態遷移)を発動させる。 |
|
エージェントが他のエージェントに当たった時にステートトランジション(状態遷移)を発動させる。 |
Crowd Trigger DOPの DOP Impact Objects パラメータのオブジェクトの1つとして群衆オブジェクト(上記のネットワークの |
ラグドール効果 ¶
エージェントがラグドールステート (Crowd State DOPの RBD Ragdoll パラメータを Active に設定)になると、そのエージェントに以下のようなラグドール効果を適用することができます:
-
粘着性のある衝突 - 衝突中にオブジェクトがエージェントに引っ付くように設定することができます。
-
剛性 - エージェントのポーズの変化に対する抵抗を制御します。
-
部分的なラグドール - エージェントの一部をシミュレーションさせ、残りの部分をアニメーションクリップに追従させることができます。
-
モーター(運動作用) - ジョイントをアニメーションクリップによって部分的に駆動させつつも、シミュレーションフォースに反応させることができます。
詳細はCrowd State DOPを参照してください。
Sticky Collisions(粘着性のある衝突) ¶
エージェントの群れに向かって矢が放たれる場面を考えてみましょう。 エージェントは矢に当たるとラグドールに変わり地面に倒れます。 この場合では、その矢がエージェントに引っ付いたままにして、その矢が跳ね返らず落ちないようにしたいことでしょう。 ここで、Sticky Collisions(粘着性のある衝突)の出番です。
Sticky Collisions(粘着性のある衝突)は、エージェントのステート毎に設定することができます。 例えば、エージェントがwalkステートの時は矢が引っ付いていて、ragdollステートの時は矢が引っ付かないようにSticky Collisions(粘着性のある衝突)を設定することができます。 これは、Crowd State DOPの Sticky Collisions セクション内のパラメータを設定することで行なうことができます。
他にも、エージェントで発生したSticky Collisionsの回数に基づいて、エージェントの新しい挙動(新しいステート)を発動させることができます。 Crowd Trigger DOPには、エージェントで発生したSticky Collisionsの回数を数えるオプションが用意されており、そのオプションを使用することで新しい挙動を発動させることができます。
以下の動画では、エージェントに当たった矢がそのエージェントに引っ付いたままになっています。 エージェントにSticky Collisionsが2回当たると、walkステートからragdollステートに遷移しています。
Sticky CollisionsはBullet Solverの機能でもあります。 そのため、上記の例では、エージェントを粘着性があるようにしましたが、矢も粘着性があるようにすることができます。 RBD Configure SOPを使用することで、RBDオブジェクト(矢)を粘着性があるようにすることができます。 複数のオブジェクトに対してSticky Collisionsの設定をした場合、その設定はお互いにオーバーライドされてしまいます。 例えば、衝突衝撃の閾値が高いオブジェクトの設定が優先されることになります。 RBD Configure SOPとCrowd State DOPで共通のSticky Collisions設定に関する詳細は、Bullet SolverのSticky Collisionsを参照してください。
To... | Do this |
---|---|
エージェントの特定のパーツを粘着性があるように設定する。 |
Crowd State DOPの Sticky Collisions セクションで、粘着性があるようにしたいジョイントのグループ名を Group パラメータに設定します。エージェントのジョイントグループの作成方法は、ジョイントグループを参照してください。 |
エージェントの粘着性を制御する |
Crowd State DOPの Min Collision Impulse パラメータは、オブジェクトがエージェントに引っ付くコリジョンの最小の衝撃を定義します。 この値が大きいほどオブジェクトがエージェントに引っ付きにくくなります。 オブジェクトをエージェントに引っ付けるには、 Min Collision Impulse を0以上に設定しなければなりません。 |
各エージェントに引っ付け可能なオブジェクトの数を制限する |
Crowd State DOPの Max Collision Objects per Shape パラメータに、粘着性があるものとして指定されているエージェントジョイントグループの各コリジョンシェイプに引っ付け可能なオブジェクトの数を設定します。 エージェントのコリジョンシェイプを定義する方法は、コリジョンシェイプを参照してください。 エージェントのコリジョンシェイプを表示するには、Crowd Object DOPの Bullet Data タブで:
例えば、粘着性があるように指定されたジョイントグループが 下図では、エージェントの上半身のコリジョンシェイプを表示しています。 Max Collision Objects per Shape を2に設定すると、エージェントには同じコリジョンシェイプに対して既に2個のオブジェクトが当たって引っ付いているので、下側の赤い矢はエージェントに引っ付かなくなっています。 |
オブジェクトが揺れないようにする |
デフォルトでは、Bullet SolverはSticky Collisions用の接着拘束を作成します。 これによって、衝突しているオブジェクト間に完全に固定された取り付けが生成されます。 この拘束タイプをソフト拘束に切り替えると、エージェントに当たったオブジェクトはアンカーポイント(接触点)基準に揺れることが許容されるようになります。 この挙動を回避したいのであれば、Crowd State DOPの Max Collision Points を上げて、オブジェクトとエージェントの間にもっとたくさんの接触点を追加してください。 |
特定のオブジェクトのみがエージェントに引っ付くことができるようにする |
Crowd State DOPの Collision Ignore に、エージェントに引っ付けたくないオブジェクトを設定します。 ここで指定されたオブジェクトはエージェントと衝突できますが、引っ付くことはありません。 Collision Ignore には、以下の指定をすることができます:
|
エージェントで発生したSticky Collisionsの回数に基づいて、新しい挙動を発動させる。 |
例えば、 Transform Group に 下図では、緑色のエージェントが歩行ステートになっていて、上半身にまだSticky Collisionsが2回発生していません。 右側では数フレーム後に、黄色のエージェントは上半身にはSticky Collisionsが2回発生してラグドールに変わっています。 |
トラブルシューティング ¶
以下の動画では、歩行エージェントがラグドールエージェントと衝突した時に、ラグドールエージェントを支えている拘束を無効にしています。 Sticky Collisionsは歩行エージェントに対して有効になっています。
接着拘束 は、Sticky Collisions用にBullet Solverによって作成されます。 エージェントが衝突すると、Bullet Solverはエージェントをお互いに引っ付ける接着拘束を作成します。
この接着拘束が作成されるときは、その接着拘束はDOP群衆シミュレーションネットワーク内の 拘束ネットワーク の1つに追加されます。
拘束ネットワークは、一緒に拘束したい剛体オブジェクトの組を定義します。
この場合だと、DOPネットワークには2個のConstraint Network DOPs(ragdoll_constraints
とrbd_to_agent_constraints
)が含まれています。
ragdoll_constraints
拘束ネットワーク
エージェント間の拘束を定義します。 2番目の入力には接着拘束が接続されていません(後ほど、これが重要である理由が分かります)。
rbd_to_agent_constraints
拘束ネットワーク
矢とエージェント間の拘束を定義します。 2番目の入力には接着拘束が接続されています。
Sticky Collision拘束の追加先となる拘束ネットワークを決めるBullet Solverのロジックは、Bullet Solver DOPの Sticky Collisions パラメータで制御します(上図のネットワークでいうと、このBullet SolverはRigid Body Solver DOP (rigidbodysolver1
)で、 Solver Engine パラメータが Bullet に設定されています)。
この例では、Bullet Solverは、次のことが理由で、Sticky Collision拘束をragdoll_constraints
拘束ネットワークに追加しました:
-
衝突は2体のリジッドボディ(エージェント)間で発生し、それらのリジッドボディはどちらもCrowd Object(
crowdobject1
)内にあったこと。且つ
-
Bullet Solverの Use Internal Constraint Networks パラメータが有効だったこと。これによって、Sticky Collision拘束が衝突オブジェクト(エージェント)間の拘束ネットワーク(
ragdoll_constraints
)に追加されるようになったこと。
拘束ネットワークの2番目の入力には、適切な拘束タイプが接続されている必要があります。
この場合では、Sticky Collisionsから生成された接着拘束はragdoll_constraints
拘束ネットワークに追加されましたが、
(rbd_to_agent_constraints
とは異なり)ragdoll_constraints
には接着拘束が接続されませんでした。
これが原因でragdoll_constraints
でエラーが発生し、次に、ラグドールを支えていたconetwist拘束が無効になりました。
解決策
あなたが求める挙動に応じて、いくつか解決策があります:
-
エージェント同士を引っ付けたくない場合、歩行エージェントが他のエージェントとの衝突を無視するように設定します -
walk
ステートのCrowd State DOPの Collision Ignore をcrowdobject1
(エージェント)に設定します。 -
(矢とエージェント間、2体のエージェント間の)すべてのSticky Collision拘束を
rbd_to_agent_constraints
拘束ネットワーク内に入れたい場合、Bullet Solverの Use Internal Constraint Networks をオフにします。オフにしなかった場合、Sticky Collision拘束はragdoll_constraints
拘束ネットワークに追加されます。DOPネットワークにさらに拘束ネットワークを追加している場合、Bullet Solverの External Constraint Network を
rbd_to_agent_constraints
に設定することで、Sticky Collision拘束がrbd_to_agent_constraints
に追加されるように明示的に指定することができます。 -
2体のエージェント間のSticky Collision拘束を
ragdoll_constraints
拘束ネットワーク内に入れたい場合、接着拘束をragdoll_constraints
の2番目の入力に接続するか、または、新しいSticky Collision拘束を別の拘束タイプ(ハード拘束とかソフト拘束)に切り替えるSOP Solverを追加します。
Note
Sticky Collision拘束の格納先となる拘束ネットワークを決定することがワークフローの選択肢となります。
しかし、上記の例では、ragdoll_constraints
拘束ネットワークの Attach Internal Constraints to Objects パラメータがデフォルトでオンになっています。
これは、ragdoll_constraints
拘束ネットワークには2体のエージェント間の拘束のみ含めることができて、矢とエージェント間の拘束を含めることができないことを意味します。
詳細は、Bullet SolverとConstraint Networkを参照してください。
Stiffness(剛性) ¶
Stiffnessが有効になっていると、エージェントはラグドールに変わった時に現行ポーズの維持を試みます。 Stiffnessが無効になっていると、エージェントはragdollステートでは、だらりと垂れたような挙動になります。
To... | Do this |
---|---|
Stiffnessを有効にする。 |
|
剛性を強くする。 |
Crowd State DOPの Stiffness セクション内の Stiffness パラメータを上げます。 この Stiffness パラメータは、 Stiffness Value が Constant に設定されている時に利用可能です。 |
エージェントの特定の部位の剛性を強くする。 |
Crowd State DOPの Stiffness セクション内の Group パラメータに、剛性を強くさせたいジョイントのグループを設定します。 エージェントのジョイントグループの作成方法は、ジョイントグループを参照してください。 |
エージェントが現行ステートでいる最初の数秒間の剛性を制御する。 |
|
Partial Ragdoll(部分的ラグドール) ¶
Partial Ragdollが有効になっていると、エージェントのラグドールにしたい部分を指定することができます。 そして、そのエージェントの残りの部分はアニメーションクリップに追従します。 例えば、下半身は歩行クリップでアニメーションさせ、上半身はラグドールにしてシミュレーションオブジェクトから衝突反応させるようにすることができます。
以下の動画では、エージェントの上半身がSticky Collisionsの条件を満たすとラグドールに変わっているのに対して、下半身は歩行アニメーションクリップに基づいて歩き続けています。
To... | Do this |
---|---|
エージェントの特定の部分をラグドールに指定する。 |
|
エージェントのラグドールでない部分で生成するアニメーションクリップを指定する。 |
|
アニメーションクリップの速度を上げる。 |
|
Tip
エージェントがragdollステートに遷移した時に足が滑っているように見える場合、 Clip Playback セクション内の Type を Locomotive に変更してください。 これによって、エージェントの動きがクリップのロコモーションデータでガイドされるようになります。 Type が In-Place に設定されている場合、エージェントの動きは大元のパーティクルによって完全に駆動されるため、エージェントの足の位置がステップ毎に地面に着地せずに滑ってしまいます。
Motors(運動作用) ¶
Motors(運動作用)が有効になっていると、エージェントのジョイントがアニメーションクリップによって部分的に駆動されつつ、シミュレーションフォースに反応するようになります。
以下の動画では、エージェントがラグドールに変わっても、まだエージェントの足は歩行アニメーションクリップによって部分的に駆動されています。
To... | Do this |
---|---|
Motors(運動作用)を有効にする。 |
|
アニメーションクリップの効果を強くする。 |
Crowd State DOPの Motors セクション内の Motor Strength パラメータを上げます。 この Motor Strength パラメータは、 Strength Value が Constant に設定されている時に利用可能です。 |
アニメーションクリップによって部分的に駆動されるエージェントの特定の部分を指定する。 |
Crowd State DOPの Motors セクション内の Group パラメータに、クリップで部分的にアニメーションさせたいジョイントのグループを設定します。 エージェントのジョイントグループの作成方法は、ジョイントグループを参照してください。 |
エージェントが現行ステートでいる最初の数秒間のアニメーションクリップの効果を制御する。 |
|
手足の分離 (上級) ¶
-
crowd source geometry network内のAgent Constraint Networkノードは、各エージェントのすべてのジョイントに対してすべてのコンストレイントを表した一連のポリラインを作成します。群衆シミュレーションネットワークの
ragdoll_constraints
Constraint Network DOPは、これらのコンストレイントをシミュレーションにインポートし、Bullet Solverがそれらのコンストレイントを維持するためのフォースを適用します。Multiple SolverにSOP Solverを追加することで、それらの拘束をシミュレーションの一部として変更することができます(例えば、コンストレイントラインを削除することで手足を分離することができます)。 これらの拘束は、Crowd Objectの
ConstraintGeometry
サブデータに格納されているので、SOP Solverの Data Name パラメータをデフォルト値(Geometry
)からConstraintGeometry
に変更してください。 -
ラグドールのエージェントがある場合(それらのステートの RBD Ragdoll が Active )やラグドールに切り替わるかもしれないエージェントがある場合( RBD Ragdoll が Animated Static )、ラグドールソルバは、使用できるコンストレイントにアトリビュートを追加して、コンストレイントの変更をトリガーします。
SOP Solverネットワークの
relationship_geometry
ノードをクリックして Spreadsheet を選び、そのアトリビュートを確認します。 -
torque
Primitiveアトリビュートには、現行のタイムステップでコンストレイントを維持するためにソルバが使用する必要があったフォース(つまり、ジョイントでのフォースの量)を含んでいます。衝撃時に手足を分離させるために、
torque
が一定の限界を超えた箇所のコンストレイントラインを削除するPrimitive Wrangleをセットアップします:if (f@torque > 50) removeprim(0, @primnum, /* andpoints */ 1);
-
エージェントに変形ジオメトリがある場合、分離されたパーツは離れますが、スキンはその分離されたパーツ上で引き伸ばされます。分離されたエージェントに対して、別のスキンジオメトリを持つ代替レイヤーに切り替える必要があります。