「チュートリアル 7: VRED 2021.3 で導入された新しい vrdTransformNode
を使用してシーン オブジェクトの変換スクリプトを作成する方法」ビデオでは、VR 内のカメラとビューポイント、およびシーンプレートを使用する例について説明します。
ビデオ キャプション: VRED Pro の Python チュートリアルへようこそ。Christopher といいます。今日は、新しい vrdTransformNode
を使ってオブジェクト変換スクリプトを作成する方法を紹介します。
VRED バージョン 13.3 の最新リリースが登場するまで、API バージョン 2 にこのビデオでお話しする vrdTransformNode
クラスは含まれていませんでした。vrdTransformNode
クラスには、ジオメトリ ノードを操作できるすべての変換操作が統合されています。以前のバージョンの VRED では、setTranslation
、setRotation
など、vrNodePtr
クラスで提供されている関数を使用して変換を行っていました。新しい vrdTransformNode
の機能自体は以前の vrNodePtr
と比較してそれほど変わっていません。ところが、これらの関数の使用方法は大幅に変更されました。
以前の変換操作を見てみると、すべてのパラメータを単一の値として渡す必要がありました。したがって、ベクトルの x、y、z 成分は関数に個別に渡されます。戻り値もベクトル成分のリストになります。
現在の例は、2 つのポイントを作成し、その中心点を計算する単純なスクリプトを示しています。ベクトルの各成分を個別に処理し、変換関数に渡す必要があります。この方法で問題はありませんが、2 つの位置の中心点を計算する場合のように、何らかのベクトル計算を行う場合は、問題が生じます。この処理を行うには、これらの値を適切なベクトル表現に変換するか、独自の数学関数を記述する必要があります。ここでは、値を手動で計算します。
この問題を解決するために、すべての変換操作が vrdTransformNode
に組み込まれ、新しい Qt データ タイプが使用されるようになりました。新しいデータ タイプは x、y、z の個々のコンポーネントを 1 つのベクトルに結合し、ベクトル計算で直接使用できるようにします。以前の例を見てみると、中心点を手動で計算する必要はないことがわかります。2 つのベクトルを直接加算し、2 で除算し、生成されたベクトルを変換関数の入力として使用することができます。したがって、外部ライブラリを読み込んだり、独自のベクトル演算を記述したりする必要はありません。これにより、コードがより読みやすく、また管理しやすくなります。
別の例を見てみましょう。線分に沿ってらせん運動を行う一連の直方体を生成します。この直方体を位置に応じて相互に回転させたり、スケールを変更したりする必要があります。この例は、変換操作の仕組み示すのに最適です。もちろん、古い API で変換操作を行うこともできますが、新しいトランスフォーム ノードは数学の面でユーザをサポートします。
では、直方体を配置するグループ ノードを作成してみましょう。直方体のらせん運動の動作をコントロールする変数をいくつか定義します。次に、ループ内に直方体を作成し、これらをグループノードに追加して、x 軸に沿って移動します。createBox
関数は古い API からノード ポインタを取得して返します。したがって、getNodeFromId
関数を使用してこのポインタを vrdTransformNode
に変換する必要があります。次に、変換を保持する単純なベクトルを作成して、直方体の setTranslation
関数に配置します。ループ内の「I」パラメータには、各直方体を x 軸に沿って少し移動する役割があります。
次に、x 軸に沿って直方体のスケーリングを変更します。そのためには、まず直方体の現在のスケーリングを取得し、ループの増大に伴って大きくなる小さな係数を乗算します。生成されたベクトルが setScale
の入力パラメータとして使用され、直方体が大きく表示されるようになりました。
最後に、直方体を中心線の周りにらせん状に動かします。これについては、私に任せてください。最初に、回転のオイラー角度を保持する回転ベクトルを作成し、直方体の回転を設定します。この方法では、直方体ごとに適した回転が設定されます。ここで、setWorldRotatePivot
関数をゼロ ベクトルで呼び出し、setRotatePivotTranslation
関数を回転ピボットの位置を指定するベクトルで呼び出します。基本的に、回転軸は直方体から遠ざかるように移動するため、回転変換はシフトし、このように適切ならせん効果が得られます。回転は直方体の中心ではなく、直方体の上の x 軸に適用されるようになりました。
既に説明したように、以前の API でも同じ結果が得られますが、新しいトランスフォーム ノードを使用した方がはるかに簡単です。Qt フレームワークのドキュメントで Python Qt ベクトルを検索すると、これらの新しいデータ タイプのドキュメントが見つかります。たとえば、Qt ベクトルのドキュメントには、基本演算である加算と減算、ベクトルの正規化のような関数など、このデータ タイプで実行できるすべての数学関数が記載されています。また、VRED の新しいデータ タイプについて詳しく紹介する、別のチュートリアルも用意されています。
今日の説明はこれで終わりです。お楽しみいただけましたか。ご参加いただき、ありがとうございました。次のチュートリアルでお目にかかりましょう。
「チュートリアル 7: VRED 2021.3 で導入された新しい vrdTransformNode
を使用してシーン オブジェクトの変換スクリプトを作成する方法」ビデオに付属しているサンプル Python スクリプトを次に示します。
以下のファイルが含まれた ZIP ファイルをダウンロードするには、ここをクリックしてください。
# Old API transformations
# Create a point p1
x1 = -500
y1 = 0
z1 = 1500
p1 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
p1.`setTranslation`(x1, y1, z1)
p1.setName("p1")
# Create a point p2
x2 = 500
y2 = 0
z2 = 500
p2 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
p2.`setTranslation`(x2, y2, z2)
p2.setName("p2")
# Create a point p_center at the geometrical center between p1 and p2
x_c = (x1 + x2) / 2
y_c = (y1 + y2) / 2
z_c = (z1 + z2) / 2
p_center = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
p_center.`setTranslation`(x_c, y_c, z_c)
p_center.setName("p_center")
# NEW API transformations
# Create a point p1
v1 = QVector3D(-500, 500, 1500)
p1 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
vrNodeService.getNodeFromId(p1.getID()).`setTranslation`(v1)
p1.setName("p1")
# Create a point p2
v2 = QVector3D(500, 500, 500)
p2 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
vrNodeService.getNodeFromId(p2.getID()).`setTranslation`(v2)
p2.setName("p2")
# Create a point p_center at the geometrical center between p1 and p2
v_center = (v1 + v2) / 2
p_center = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
vrNodeService.getNodeFromId(p_center.getID()).`setTranslation`(v_center)
p_center.setName("p_center")
vrdTransformNode.py
groupNode = vrNodeService.findNode("Group")
deleteNode(groupNode)
numberOfBoxes = 50
boxSize = 50
xStep = 125
xRotationStep = 20
z = 500
radius = 400
boxGroup = createNode("Group")
for i in range(0, numberOfBoxes):
box = vrNodeUtils.createBox(boxSize, boxSize, boxSize, 1, 1, 1, 0, 0, 0)
box.setName("box {}".format(i))
boxGroup.addChild(box)
# Get the vrdNode object of the box
boxNode = vrNodeService.getNodeFromId(box.getID())
boxTranslation = QVector3D(xStep * i, 0 ,z)
boxNode.`setTranslation`(boxTranslation)
boxScale = boxNode.getScale() * (1 + (i * 0.01))
boxNode.setScale(boxScale)
boxLocalRotation = QVector3D(xRotationStep, 0, 0) * i
boxNode.`setRotation`AsEuler(boxLocalRotation)
boxNode.`setWorldRotatePivot`(QVector3D(0, 0, 0))
boxNode.`setRotatePivotTranslation`(QVector3D(0, 0, z + radius))