Houdini 18.0 群衆シミュレーション

エージェントプリミティブ

群衆シミュレーションの要員である動く"アクター"であるエージェントについて説明します。

On this page

概要

エージェントプリミティブは一種のパックプリミティブであり、通常では群衆シミュレーションのキャラクタ(エージェント)の表現に使用します。 他のタイプのパックプリミティブと同様に、エージェントプリミティブは単一ポイントを含んでいるので、たいていの状況ではパーティクルとして扱うことができます。

エージェント定義

エージェントプリミティブには、いくつかのデータの参照が記録されており、それらの参照がエージェントのコピー間で共有されていて、 エージェント定義 として参照されることが多いです。 エージェント定義は次のコンポーネントで構成しています: リグ, シェイプライブラリ, 一連のレイヤー, 一連のクリップ, オプションの一連のトランスフォームグループ。 エージェントの現在のレイヤー、トランスフォーム、チャンネル値は、エージェントをアンパックした時に生成されるジオメトリを決定します。

一連のエージェントプリミティブをディスクに保存した時、(パックジオメトリプリミティブと同様に)エージェント定義のコンポーネントもジオメトリファイルに埋め込まれます。 エージェント定義の各コンポーネントを別々にディスクに保存して、エージェントプリミティブから 外部参照 として扱うこともできます。 これによって、例えば群衆シミュレーションからフレームシーケンスを保存する時に大幅に冗長なデータを減らすことができます。 そのような場合では、(パックディスクプリミティブと同様に)エージェント定義のコンポーネント(例えば、シェイプライブラリ)のパスのみがジオメトリファイルに記録されます。 Agent ROPを使用すれば、既存エージェントプリミティブのエージェント定義をディスクに書き出したり、キャラクタリグまたはFBXファイルからエージェント定義を作成することができます。

リグ

リグには、エージェントのトランスフォーム階層(名前の付いたトランスフォームのツリー)とチャンネルが記録されています。 各トランスフォームは、単一の親を持っているか、または階層のルートのどちらかです。 各チャンネルは(チャンネルがアニメーションクリップ内に存在しない時に使用される)デフォルト値を持つことができ、オプションでリグ内のトランスフォームと関連付けることができます。

File Format
VEX Functions
HOM

リグは、JSON形式で記録されています。 階層は、親からその子のリストまでのマップとして表現されており、トランスフォーム名は任意の順番で表わすことができます。

{
    "rig_version": 1,
    "transforms": {
        "root": ["LUpperArm", "RUpperArm"],
        "LUpperArm": ["LLowerArm"],
        "LLowerArm": [],
        "RUpperArm": ["RLowerArm"],
        "RLowerArm": [],
    },
    "channels": {
        "blendshape1": {
            "default_value": 0,
            "transform": ""
        },
        "blendshape2": {
            "default_value": 0,
            "transform": ""
        },
        "RLowerArm.channel1": {
            "default_value": 0,
            "transform": "RLowerArm"
        }
    }
}

以下のVEX関数を使用することで、エージェントのリグに関する情報を照会することができます:

以下のHOMクラスとメソッドを使用することで、エージェントのリグに関する情報を照会したり、エージェントのリグを作成することができます:

シェイプライブラリ

シェイプライブラリには、エージェントで使用可能なジオメトリの集合体(シェイプ)が備わっています。 シェイプライブラリ内の各シェイプは、固有の名前を持ちます。

File Format
HOM

各シェイプはパックプリミティブとして保存されており、namePrimitiveアトリビュートにはシェイプの名前が含まれていて、シェイプのジオメトリはパックプリミティブの中身です。 シェイプライブラリそのものは、通常のgeo/bgeo形式で単一ジオメトリファイルとしてディスクに保存されます。

shapelib_includes文字列配列Detailアトリビュートを使用することで、シェイプライブラリを読み込む時に含めたい追加シェイプライブラリを指定することができます。 このアトリビュートはタプルサイズが2である必要があり、そこには短縮パス(例えば、$HIPまたは$JOBを基準としたパス)とシェイプライブラリファイルの絶対パスのペアを含めます。

以下のHOMクラスとメソッドを使用することで、エージェントのシェイプライブラリに関する情報を照会したり、シェイプライブラリを修正することができます:

レイヤー

レイヤーはエージェントのジオメトリを制御します: エージェントをアンパックした時に、シェイプライブラリからどのシェイプを使用するかどうか、さらにそれらのシェイプをどのようにトランスフォームまたは変形するべきかどうか。

レイヤーは、一連の シェイプバインド で構成されています。これは、シェイプライブラリからシェイプをリグ内のトランスフォームに取り付けます(例えば、"sword_1"というシェイプを"RHand"トランスフォームに取り付けます)。 各シェイプバインドには、そのシェイプの境界ボックスのスケール係数、シェイプをアンパックした時に使用するデフォーマを指定することもできます。 シェイプバインドにデフォーマが指定されていなかった場合、そのシェイプバインドは Static で、そのシェイプは取り付けられているジョイントによってトランスフォームされるだけです。

File Format
VEX Functions
HOM

レイヤーは、静的または変形のシェイプバインドを別々のリストにしてJSON形式で記録されています。

{
    "version": 1,
    "name": "soldier_display",
    "static": [
        {
            "transform": "LLowerArm",
            "shape": "shield",
            "bounds_scale": 1,
            "deformer": ""
        },
        {
            "transform": "RLowerArm",
            "shape": "sword",
            "bounds_scale": 1,
            "deformer": ""
        }
    ],
    "deforming": [
        {
            "transform": "",
            "shape": "skin",
            "bounds_scale": 1,
            "deformer": "linearskinning"
        }
    ]
}

以下のVEX関数を使用することで、エージェントのレイヤーに関する情報を照会したり、エージェントのレイヤーを変更することができます:

以下のHOMクラスとメソッドを使用することで、エージェントのレイヤーに関する情報を照会したり、エージェントのレイヤーを作成または変更することができます:

デフォーマ

シェイプバインドで利用可能なデフォーマタイプがいくつかあります。

スキニング

これらのデフォーマは、Bone Deform SOPSkinning Method オプションに相当します。 シェイプのジオメトリは、静止ポーズになっていて、且つ、ジオメトリがリグ内のトランスフォームによってどのように影響を受けるのかを示したcaptureアトリビュートが含まれている必要があります。 ジオメトリは、それらのcaptureアトリビュートとエージェントの現行トランスフォームに基づいて変形します。

  • linearskinning

    Bone Deform SOPLinear Skinning メソッドに相当します。 これが標準で最も高速なメソッドであり、現在のところ、ビューポートでのGPUスキニングで使用できる唯一のメソッドです。

  • dualquatskinning

    Bone Deform SOPDual Quaternion Skinning メソッドに相当します。

  • dualquatblendskinning

    Bone Deform SOPBlend Dual Quaternion and Linear Skinning メソッドに相当します。 ブレンドアトリビュートの名前は、deformDualQuaternionBlendAttrib Detailアトリビュートで指定します。

ブレンドシェイプ

エージェントのチャンネル値で指定されたウェイトを使って一連の入力シェイプ間をブレンドします。 これは、Blend Shapes SOPによる処理に相当します。

シェイプのジオメトリがベースシェイプとして解釈され、blendshape_shapenames文字列配列Detailアトリビュートによって追加入力(シェイプライブラリ内の別々のシェイプ)を指定します。 blendshape_channels文字列配列Detailアトリビュートには、各ブレンドシェイプ入力で使用する(エージェントのリグで定義されている)チャンネル名を指定します。 エージェントのそれらのチャンネルの値がブレンドシェイプのウェイトとして使用されます。

ポイント番号によるマッチングの代わりに、id Pointアトリビュートを使って異なる入力間のポイントをマッチングさせることができます。 これは、Blend Shapes SOPPoint ID Attribute オプションに相当し、id Pointアトリビュートを使用することで、一部のポイントセットだけを変形させるといった疎らなブレンドシェイプを行なうことができます。 blendshape_ptidattr文字列Detailアトリビュートをベースシェプに追加することで、idのデフォルト値を上書きすることができます。 同様に、blendshape_primidattr文字列Detailアトリビュートを使用することで、 Primitive ID Attribute パラメータ(デフォルトでは空っぽの文字列)を指定することができます。

blendshape_attribs文字列Detailアトリビュートを使用することで、ブレンドさせるアトリビュートを指定することができます(Blend Shapes SOPAttributes パラメータに相当します)。 デフォルトの挙動では、ポイントポジション(P)だけをブレンドします。

さらに、各ブレンドシェイプ入力は、 中間 シェイプ(補間の挙動を調整できるように特定のウェイトで適用される補正形状)を定義することができます。 中間シェイプは、プライマリシェイプのジオメトリ上のblendshape_shapenames文字列配列Detailアトリビュートで指定します。 そして、blendshape_inbetweenweights 浮動小数点配列Detailアトリビュートには、それぞれの中間シェイプに該当するウェイトを指定します。 中間シェイプは1のウェイト(プライマリシェイプが適用されるウェイト)または0のウェイトを持つことができません。

  • blendshape

    Blend Shapesデフォーマをジオメトリに適用します。

  • blendshape+linearskinning, blendshape+dualquatskinning, blendshape+dualquatblendskinning

    これらのデフォーマは、blendshapeデフォーマの後にスキニングデフォーマのどれかを適用します。

HOM
HDK

以下のHOMクラスとメソッドを使用することで、シェイプデフォーマの情報を照会したり、シェイプデフォーマを選択することができます。

カスタムデフォーマは、HDKでGU_AgentShapeDeformerをサブクラス化することで実装することができます。 デフォーマは、GUregisterAgentShapeDeformer()エントリーポイントからGU_AgentLayer::registerDeformer()をコールすることで登録されます。

クリップ

クリップには、エージェントのトランスフォームチャンネル値の駆動に使用することができるアニメーションデータが備わっています。

File Format
VEX Functions
HOM

クリップは、通常の.bclip形式で保存されます。

エージェントのトランスフォームのチャンネルは、ローカル空間で記録され、その名前はtransform_name:channelの形式になっています。channelt[xyz], r[xyz], s[xyz]です。

Note

[srt]チャンネルには、各ジョイントの完全なローカルトランスフォームを記述しており、プリトランスフォームがあった場合、ソースアニメーションのオブジェクトの[srt]チャンネルには一致しません。

以下のVEX関数を使用することで、エージェントのクリップに関する情報を照会したり、エージェントのクリップを変更することができます:

以下のHOMクラスとメソッドを使用することで、エージェントのクリップに関する情報を照会したり、エージェントのクリップを作成または変更することができます:

トランスフォームグループ

トランスフォームグループは、エージェントのリグ内のトランスフォームとチャンネルの名前付きサブセットです。 エージェントのスケルトンの部分にクリップを適用する時に、このトランスフォームグループを使用することができます。 0から1までのウェイト値をグループの各トランスフォームに割り当てることもできます。

File Format
VEX Functions
HOM

トランスフォームグループは、JSON書式で保存します。

{
    "version": 2,
    "name": "upper_arms",
    "members": [
        {
            "name": "LUpperArm",
            "weight": 1
        },
        {
            "name": "RUpperArm",
            "weight": 1
        }
    ],
    "channels": [
        {
            "name": "arm_blendshape_L"
        },
        {
            "name": "arm_blendshape_R"
        }
    ]
}

以下のVEX関数を使用することで、エージェントのトランスフォームグループに関する情報を照会することができます:

以下のHOMクラスとメソッドを使用して、トランスフォームグループに関する情報を照会したり、トランスフォームグループを作成することができます:

エージェント毎のデータ

トランスフォーム

概要
VEX Functions
HOM

各エージェントには、一連の 現行トランスフォーム が記録されています(リグ内の各トランスフォームの4×4マトリックス)。 トランスフォームは、エージェントの現行アニメーションクリップで駆動させたり、手動で制御することもできます。 これらのトランスフォームは、agentworldtransformsagentlocaltransformsのPrimitive Intrinsicsからアクセスすることができます。

他のタイプのパックプリミティブと同様に、エージェントは、自身の位置を決めるための全体的なトランスフォーム(これは、PorientのPointアトリビュートで制御します)も持ちます。

以下のHOMメソッドを使用することで、エージェントのトランスフォームを読み込んだり、修正することができます:

チャンネル値

概要
VEX Functions
HOM

各エージェントには、一連の チャンネル値 (リグ内のチャンネル毎に浮動小数点)が格納されています。 チャンネル値は、エージェントの現行アニメーションクリップで駆動させたり、手動で制御することもできます。

チャンネル値は主にBlend Shapesデフォーマで使用しますが、他のアプリケーション用に利用することもできます。

これらのチャンネル値は、agentchannelvalues Primitive Intrinsicからアクセスすることができます。

以下のVEX関数を使用することで、エージェントのチャンネル値を読み込んだり修正することができます:

以下のHOMメソッドを使用することで、エージェントのチャンネル値を読み込んだり修正することができます:

クリップ

Overview
VEX Functions
HOM

Each agent has a list of current animation clips from its agent definition. The lists of clips, clip times, and blend weights are used to drive the agent’s stored transforms and channel values. These properties are accessible through the following primitive intrinsics:

  • agentclipnames: A list of animation clip names.

  • agentcliptimes: A list of the times that the clips should be sampled at.

  • agentclipweights: A list of the blend weights for the animation clips. The weights will be normalized before blending.

The following primitive intrinsics extend the basic animation blending model to describe a tree structure for layering and blending animation clips. Each layer has a blend mode, and one or more input poses that each have an associated weight. The output of the layer is a new pose computed from its inputs. An input pose can either be a pose sampled from a clip, or the pose produced by another layer.

  • agentcliptransformgroups: Specifies the name of the transform group to use for each clip. This is used to apply clips to a subset of the transforms or channels in the rig.

  • agentcliplayerids: Specifies the layer index (into agentcliplayermodes) that each clip is an input for.

  • agentcliplayermodes: Specifies the blend mode for each layer (the length of this list controls the number of layers in the hierarchy). The valid values are 0 (the default interpolate blend mode) and 1 (additive blend mode). The additive blend mode applies a percentage (controlled by the blend weight) of the other clips' translations and rotations to the first input clip, rather than interpolating between the inputs.

  • agentcliplayerweights: Specifies the blend weight for each layer. Like agentclipweights, this is used when the layer’s output is used as the input for another layer, and so the weight is unused for the topmost layer.

  • agentcliplayerparents: Similar to agentcliplayerids, specifies the layer index that the layer is an input for. The topmost layer has a parent index of -1.

The following VEX functions can be used to read or modify an agent’s current clips:

The following HOM methods can be used to read or modify an agent’s current clips:

レイヤー

概要
VEX Functions
HOM

各エージェントは、そのエージェント定義からの 現行レイヤー を持ちます。このレイヤーは、エージェントをアンパックした時に使用されるジオメトリであり、ビューポートに表示されたり、レンダリングされます。

さらに、エージェントには Collisionレイヤー を持たせることができます。このレイヤーは、エージェントを簡易的に表示させる必要がある時(例えば、Bullet Solverを使ったラグドールシミュレーション)に使用されます。 Collisionレイヤーは、それが存在すれば、エージェントの境界ボックスを決定する時にも使用されます。

現行レイヤーとコリジョンレイヤーは、agentcurrentlayeragentcollisionlayerのPrimitive Intrinsicsからアクセスすることができます。

以下のVEX関数を使用することで、エージェントの現行レイヤーを読み込んだり、修正することができます:

以下のHOMメソッドを使用することで、エージェントの現行レイヤーを読み込んだり、修正することができます:

境界ボックス

エージェントにCollisionレイヤーがあれば、エージェントの境界ボックスを計算する時に、そのレイヤーが使用されます。 Collisionレイヤーが設定されていなければ、代わりにエージェントの現行レイヤーが使用されます。 レイヤーの境界ボックスは、そのレイヤーに参照されている各シェイプの境界ボックスを結合することで計算されます。

静的シェイプの場合、そのシェイプの境界ボックスは、そのシェイプバインドの境界スケールで拡張されてから、そのシェイプとバインドされているジョイントに応じてトランスフォームされます。 変形シェイプの場合、そのシェイプの境界ボックスは、Capture Weightに参照されているジョイントの位置から計算されてから、そのシェイプバインドの境界スケールで拡張されます。

See also

群衆シミュレーション

はじめよう

  • 基本

    Houdiniにおける群衆シミュレーションの考え方の概要を説明します。

  • セットアップ

    群衆シミュレーションのセットアップと編集の方法

動くパーツ

  • エージェント

    群衆シミュレーションの要員である動く"アクター"であるエージェントについて説明します。

  • ステート

    各エージェントのアニメーションや仕草を制御する仮想的な"雰囲気"。

  • トリガー

    エージェントの状態を変更する条件を指定する方法です。

  • キャッシュ

    群衆シミュレーションの効率的なキャッシュ化と読み込みのTips。

挙動

外観

  • 多様性

    エージェントに異なる外観と行動を作成することで、より現実的な群衆を作成する方法。

  • 布の取り付け

    Vellum Clothをエージェントシェイプジオメトリの一部として追加/拘束すれば、エージェントの動きに基づいて布をシミュレーションすることができます。

地形

  • 足の着地

    エージェントのアニメーションを地形に適応させて滑りを回避するためのセットアップ方法。

  • 地形

    エージェントが歩く地形ジオメトリを指定する方法です。

  • 障害物

    エージェントが回避する障害物を設定する方法です。