この記事は Qiita の Houdini Apprentice Advent Calendar 2020 に投稿するものです。
simon が 2020年9月に投稿した Falling Rocks tool を、Houdini・Python を勉強し始めて数か月の筆者が勉強してみた結果です。
勉強中の身なので、自分ならどう書き足すなどご意見ありましたらコメント頂けますと幸いです。
1. 仕様
https://vimeo.com/487976424
- Scene View をクリックすると球が生成される
- 発射角度・初速度がランダム(ある程度範囲は設ける)
- 生成されたタイミングから射出が始まる(クリックしたフレームから運動が始まる)
- 一定進むと止まる
2. 手順
2.1 自由落下
参考にしたチュートリアルが終了した状態から手を加えていきます。
参考動画と上の画像とでノード名は一部異なりますが、ノードネットワーク自体は変わりません。
また、この先途中でアトリビュート名が変わることがありますがご容赦ください。
2.2 X-Y 平面での斜方投射
運動の処理をするノード(上の fall_down)の中身を書き換えて、自由落下から斜方投射に変更します。
クリックした地点からポイントが急に飛び出すのも面白いですが、とりあえず今回はポイントの生成座標を(0, 0, 0)に統一しておきます。
自由落下から斜方投射に運動を変えたことで、投射角度θと初速度v0という概念が生まれました。仕様として、発射角度θと初速度v0はポイントごとにランダムな値をアトリビュートに用意します。
foreach 内で Start_frame をアトリビュートとして用意したときと同じようにして二つのアトリビュートを作ります。
attribcreate_theta_v0 では rand() を使ってポイントごとの発射角度と初速度を決めています。シード値は改善の余地がありますし、attribcreate_spawnframe と合わせて一つのノードにまとめてもいいでしょう。
setrange では発射角度と初速度の最低値を設定しています。
それぞれ数値があまりに小さいと運動の様子が分からないので追加しましたが、ここも attribcreate_theta_v0 と合わせて改善の余地があります。
公式に則り、Y軸とX軸の運動を記述します。
θとv0はアトリビュートを、重力加速度gと経過時間tは変数として定義します。
X-Y 平面での斜方投射の全体像です。
最低限x軸方向の運動を追加しただけですが、物理運動を再現している感は出たと思います。
2.3 XZ-Y 空間での斜方投射
上では sphere は X > 0 の方向にしか飛びません。
X < 0 にも飛ぶようにして、さらに Z軸も増やして、XZ平面に飛び出すようにします。
第一象限に飛ばす
X軸を θ=0 とする XZ平面の角度を XZtheta としてアトリビュートを作ります。
やっていることは投射角度 theta(X軸と Y軸間の角度)を作った時と同じですが、シード値を少し変えておきます。
wrangle を書き換えます。
@P.x と @P.y を書き直して、
X軸上だけではなく平面上に射出できるようになりました。
ただしさきほどの attribcreate で角度を0°-90°に制限しているので、ポイントの x, z 座標は X-Z平面の第一象限上(x, z 共に正)に収まります。
象限を増やす
0 <= θ <= 90 間で cosθ, sinθはどちらも正の値を取ります。なので、ポイントが持つランダムな値を基にポイントアトリビュートに正負を代入します。
各ポイント固有のSpawnFrameで条件分岐して、飛ぶ象限をばらけています。
ポイントが遠くに行き過ぎないようにして、
ポイントが空間内にばらけるようになりました。
3. まとめ
勉強したての筆者がチュートリアルを見て、できそうなことを追加してみました。
simon が言っていたように、Python viewer state を含めて Python, VEX は作り手の想像力次第で色んなことに使えるので、多くの作品を見て発想力を鍛えていければと思います。
ex. 追加できそうな仕様
せっかく物を投げ飛ばせるなら、地面や壁との衝突運動を加えても面白そうです。
ケーブルツールなどでも add point のコードジェネレーターを使っているので、どんどん派生して作品作りに役立てればと思います。
他にも Houdini 関連の記事を投稿していますので、ご参考ください。
https://support.borndigital.co.jp/hc/ja/categories/203099087-Houdini