コンテンツにスキップ

CompArc(4) リファレンス・ペイロード

コンポジションアークの説明もこれでラスト。
最後はリファレンスとペイロードについて。

リファレンスとは

まず、コンポジションアークの「リファレンス」とはどういう機能かというと
ざっくり言うと、別のレイヤー(usdファイル)のルート直下にある指定プリム以下を
指定のプリムに接続する機能のことを言います。

まず、このようなusdファイルを準備します。

#usda 1.0
(
    defaultPrim = "RootGrp"
)

def "RootGrp"
{
    def Sphere "Sphere"{}
}

中身はこんな感じ。
defaultPrimが指定されたSphere1つだけのファイルです。
このファイルをリファレンスで読み込んでみます。

#usda 1.0

def "Grp"{
    def "RefA" ( prepend references = @ref_data.usda@){}
    def "RefB" ( prepend references = @ref_data.usda@){}
    def "RefC" ( prepend references = @ref_data.usda@){}
}

試しに同じファイルを複数読み込んでみます。

結果、3つSphereができあがってることが分かります。

どういう状況になっているかというと、
リファレンス先で定義している prepend referencd = ~~~ つきのプリムが
リファレンスしたいファイルのdefaultPrimに置き換わるようになります。

上の例でいうと、 RootGrpが RefAという名前になって
RootGrp以下のプリムがすべてマージされ、

こうなります。(RefB,Cも同様)

今まで説明したサブレイヤーや継承、バリアントと大きく違うのは
指定がプリムではなくレイヤー(USDファイル)指定であること。
構造すべてを合成するのではなく、あるプリムに対して別のレイヤーを合成するというのが
異なります。

ペイロードとは

実質最後のコンポジションアークですが、これは実質リファレンスと動作は同じで、
あるプリムに対して指定のレイヤーのデフォルトプリムを接続します。

では、リファレンスとはなにが違うかというと

usdviewのHelpを見るととてもわかりやすいのですが
--unloaded フラグのHelpにある「Do not load payloads」の通り
ペイロードで読まれているものは、指定のフラグ付きでロードした場合「アンロード状態」
でシーンが開きます。

試しに、キッチンセットを --unloadedフラグ付きで読み込んでみると
なにも表示されません。

#usda 1.0
(
    defaultPrim = "Ball"
    upAxis = "Z"
)

def Xform "Ball" (
    assetInfo = {
        asset identifier = @./assets/Ball/Ball.usd@
        string name = "Ball"
    }
    kind = "component"
    payload = @./Ball_payload.usd@</Ball>
)
{
}

何故かというと、キッチンセットのアセットの途中にかならずペイロードでのロードが
含まれているからです。

なぜこんな機能があるのかというと、
複雑なステージになると、1ステージで数百・数千のUSDで構成されることもあるそうで
「ステージ内のある1つのレイヤーのみ調整したい」
という場合、全シーンをロードすると時間がかかってしまいます。

ので、ペイロードフラグを入れているものはロードしない状態にしておき
開いてから、作業をしたいアセットのみ表示してから
保存する...のようなワークフローを可能にしているらしいです。

指定のプリムをロードする

リファレンスは、指定のレイヤー内のルート以下プリムを指定する必要があります。
特に指定されていない場合は「デフォルトプリム」をロードするようになります。

では、デフォルトプリムの指定がされていない場合はどうなるかというと、

エラーが表示され、

正しくロードできなくなりました。
これは、どのプリムをリファレンスすれば良いかが分からなくなってしまうからです。

その指定する方法の1つがデフォルトプリムの指定でしたが

では、このような
1つのレイヤーにいろいろなプリムが入っていて
それらを選択して読み込みたい場合はどうすれば良いか。

#usda 1.0

def "Grp"{
    def "RefA" ( prepend references = @ref_data.usda@</RootSphere>){}
    def "RefB" ( prepend references = @ref_data.usda@</RootCube>){}
    def "RefC" ( prepend references = @ref_data.usda@</RootCylinder>){}
}

その場合は、このように、

</PrimName>

読み込みたいレイヤー指定の後にSdfPathを指定することで
指定のSdfPathのプリムをリファレンスすることが出来ます。

他のコンポジションとの組み合わせ(バリアントとの組み合わせ)

コンポジションアークのプリムとアトリビュート合成の解決順序は
Local Inherits Variants Reference の順なので
リファレンスは4番目になります。(実質一番弱い)

では、今回のリファレンスも他と組み合わせたときにどうなるかを確認してみます。

#usda 1.0

def "testPrim" (
    variants = {
        string hogehoge = "Sphere"
    }
    prepend variantSets = "hogehoge"
)
{
    variantSet "hogehoge" = {
        "Sphere" {
            def "RootSphere"(prepend references = @ref_data.usda@</RootSphere>){}

        }
        "Cube" {
            def "RootCube"(prepend references = @ref_data.usda@</RootCube>){}

        }
        "Cylinder" {
            def "RootCylinder"(prepend references = @ref_data.usda@</RootCylinder>){}
        }
    }
}

前回のバリアントに対して、リファレンス構造をつけてみます。

こうすると、どのようになるかというと
リファレンスのロードの前に、まずバリアントによるスイッチが選択されるようになります。
その後に、バリアント内にあるリファレンスがロードされます。

もしこの解決順序が逆の場合
リファレンス3つが読み込まれるので、バリアントが効かなくなります。
リファレンスをスイッチングできるようにするための解決順序が
V→Rなのかなぁと
挙動を調べているときに気がつきました。

リファレンス先のサブレイヤー

V→Rの順序の確認はできましたが
では、リファレンス先にコンポジションアークがあった場合はどうなるのか確認してみます。

#usda 1.0

(
    defaultPrim="SubA"
)

def "SubA"
{
    string name = "Hoge"
}

まず、こんな感じの SubA.usda を作成し

#usda 1.0
(
    subLayers = [
        @subA.usda@
    ]
)

サブレイヤーで合成。
このファイルを ref_SubLayer.usda とします。

#usda 1.0

def "Grp"{
    def "SubLayer" ( prepend references = @ref_SubLayer.usda@</SubA>){}
}

そのファイルをリファレンスでロードしてみると、

リファレンス先のサブレイヤーが合成され、その結果をリファレンスすることができました。
このように、リファレンス先に対してコンポジションがあった場合は
リファレンス内でLIVR...の順でプリムやアトリビュートの解決を行い
その結果をリファレンスするようになります。
リファレンス先は、1つのローカルデータ扱いになる感じ。

このあたりは、Mayaのリファレンス機能にちかいものがあって
ある構造(Joint構造・Mesh構造、リギング済みアセットデータなど)をシーンにリファレンスでロードするように
USD内にアセットロードする時などに役に立ちます。


最終更新日: 2019-11-24 03:29:28