チュートリアル 12: vrFieldAccess を使用した低レベルのフィールド アクセス

チュートリアル 12: vrFieldAccess を使用した低レベルのフィールド アクセス」のビデオでは、次の内容について説明します。

サンプル スクリプトをダウンロードする

サンプル スクリプトに移動する

チュートリアルの PDF をダウンロードする

ビデオ キャプション: VRED Pro の Python スクリプティング チュートリアルの最後のビデオへようこそ。Christopher といいます。本日は、VRED のノード アトリビュート エディタで vrFieldAccess API を使用してフィールドの読み取りと操作を行うする方法を説明します。

メニューを使用して VRED でノード アトリビュート エディタを開くと、任意のタイプのノードに使用されるすべての内部データにアクセスできます。たとえば、シーングラフに含めることができるノードだけでなく、マテリアル ノード、ライト ノード、シーンプレート ノードなども含めることができます。ノード アトリビュート エディタでシーングラフ ノードを調べると、移動、回転、スケールなど、現在のすべてのトランスフォーム値を確認できます。マテリアルの場合、ノード アトリビュート エディタには、拡散光色やバンプ マップなど、すべてのカラー コンポーネントのデータとテクスチャが表示されます。

通常、VRED は標準インタフェースを介してこのデータの大部分を公開しているため、ノード アトリビュート エディタを使用してこの情報にアクセスする必要はありません。また、ノード アトリビュート エディタで任意の値を編集することは安全ではないため、カメラのパース行列を手動で変更することは不適切な場合があります。

ただし、場合によっては便利なこともあります。たとえば、Python を使用してマテリアルを動的に作成する場合に、拡散光色などのパラメータを設定するには、フィールド アクセス API を使用するのが唯一の方法です。別の例として、あるプロジェクトで、受信するビデオ ストリームの解像度のサイズに合ったディスプレイ画面を動的に生成する必要があり、これを実現するには、フィールド アクセス API を介してビデオ ストリームの解像度を読み取る必要がありました。

まず、簡単な例を示します。マテリアルを作成し、その拡散反射光色を明るい赤に設定します。ノード アトリビュート エディタで他のマテリアルを調べると、diffuseColor フィールドがこの処理を行っていることが分かります。マウス カーソルを値の右側に移動すると、VRED で内部的に使用されるデータ タイプも表示されます。この場合、データ タイプは 3 つのコンポーネントを持つベクトルになります。

このため、まず fields メソッドを使用してノードのフィールドにアクセスしてから、set メソッドを使用して値を設定します。この例では、RGB 値を diffuseColor フィールドに書き込むことができる getVector3f メソッドを使用しています。スクリプトを実行してマテリアル エディタを再ロードすると、拡散反射光色が明るい赤に設定された新しいマテリアルが表示されます。

詳しく見てみましょう。ノード アトリビュート エディタの最初のレベルにアクセスするのは簡単でした。でも、フィールド アクセス グラフの下位レベルにアクセスするにはどうしたらよいでしょうか。マテリアルのバンプ マップ テクスチャのテクスチャ解像度を読み取るとします。この操作を行うには、まず、目的のフィールドが含まれている各フィールド コンテナにアクセスする必要があります。この例では、「colorComponentData」、「bumpComponent」、「image」です。

まず、マテリアルとそのフィールドを取得します。次に、フィールド コンテナから次のフィールド コンテナに移動して、実際にデータが格納されているフィールド コンテナにアクセスします。この操作を行うには、getFieldContainer メソッドを使用し、vrFieldAccess クラス コンストラクタ内で戻り値をパラメータとして使用します。最後のフィールド コンテナ「bumpImageComponent」に到達すると、解像度のフィールドにアクセスできるようになります。この例では、解像度は 1024 x 1024 です。

ほとんどの場合、実行できる操作は、ノード内の既存フィールドの読み取りと操作に限定されます。ただし、ある程度はノードに任意のデータを追加することもできます。これは、データ準備用の複雑なプラグインなどを開発する場合に役立ちます。では、この方法について説明しましょう。

次のスクリプトでは、アタッチメント ノードの「ValuePair」を使用して文字列データのリストを書き込む方法と、「key」フィールドと「value」フィールドを使用してデータを格納する方法を示します。キー値のペアを 2 つのリストに分割してアタッチメントに保存したので、後で取得することができます。

ここでは、Python の zip 関数を使用して、キー値ペアの元のリストを再構築します。しかし、value ペアのアタッチメントに、データが既に格納されているノードがいくつかあることに注意してください。そのため、このメソッドを使用する場合は、誤ってこのデータを変更しないように何らかの対策を実施します。

データ タイプと、正しいデータ タイプを使用しているか確認する方法について簡単に示します。場合によっては、整数が 8 ビット、16 ビット、符号付き、符号なしのいずれであるかが不明なことがあります。また、C や C++ を扱ったことがない場合は、何をすればよいかわからないかもしれません。ノード アトリビュート エディタの value フィールドの上にカーソルを合わせると、実際に使用される内部データ タイプが表示されます。これにより、フィールドに値を読み書きする場合に使用する必要があるメソッドについてのヒントが得られます。ここで行うのは、ドキュメント内で全文検索を実行し、ノード アトリビュート エディタでデータ タイプに一致するメソッドを見つけることです。間違ったメソッドを使用すると、エラー メッセージが表示されます。そのため、使用するメソッドを必ずテストして、問題がないことを確認してください。

今日の説明はこれで終わりです。参加していただき、ありがとうございましたこれは、VRED Pro 向けの Python スクリプティング チュートリアル シリーズの最後のビデオです。興味がある場合は、新しい VRED Core に関する Python チュートリアルもご覧ください。それでは、またお会いしましょう。


Python サンプル コード

これは、「チュートリアル 12: vrFieldAccess を使用した低レベルのフィールド アクセス」のビデオに付随する Python のサンプル スクリプトです。

ヒント:

以下のファイルが含まれた ZIP ファイルをダウンロードするには、ここをクリックしてください。

fieldAccess-examples.py

# Simple Field Access
material = createMaterial("UPhongMaterial")
material.setName("Python Material")
fields = material.fields()
fields.setVec3f("`diffuseColor`", 1, 0, 0)

# Complex Field Access
leatherMatFields = findMaterial("Leather red").fields()
colorComponentData = `vrFieldAccess`(leatherMatFields.`getFieldContainer`('colorComponentData'))
bumpComponent = `vrFieldAccess`(colorComponentData.`getFieldContainer`('bumpComponent'))
bumpImageComponent = `vrFieldAccess`(bumpComponent.`getFieldContainer`('image'))

width = bumpImageComponent.getInt32("width")
height = bumpImageComponent.getInt32("height")

print(width, height)

# Attaching arbitrary data to a node field
envNode = findNode("EnvironmentsTransform")
customAttachment = createAttachment("ValuePair")
`vrFieldAccess`(customAttachment).setMString('key', ['key1', 'key2', 'key3'])
`vrFieldAccess`(customAttachment).setMString('value', ['value1', 'value2', 'value3'])
envNode.addAttachment(customAttachment)

# Reading the values from the attachment
envNode = findNode("EnvironmentsTransform")
attachmentFieldAccess = `vrFieldAccess`(envNode.getAttachment("ValuePair"))
keys = attachmentFieldAccess.getMString('key')
values = attachmentFieldAccess.getMString('value')

keyValuePairs = list(zip(keys, values))
print(keyValuePairs)