🟠

第24回 Houdiniゆるゆる会備忘録

に公開

wire connect

毎月開催している勉強会「Houdiniゆるゆる会」の振り返り記事と発表資料の紹介を今回から始めます。

https://houdini-teaparty.connpass.com/

この勉強会は一つのお題に対して各参加者がシーンを作成して発表するスタイルで、視聴のみの枠はありません。主体的な勉強会です。シーンの配布は参加者のみに限定しているため、本ブログでは僕の発表内容を断片的に紹介します。

今回のお題

「10ノード縛り」

今回のテーマはイメージや具体的なオブジェクトではなく、何かしらの機能や表現を10ノード以内で作成するというものです。

10ノードというのは絶妙な縛りで、多くの参加者が「それなりの規模感のネットワークを作成し、それをスリムアップする」という手法をとりました。

似た機能があれば一本化し、複数のノードを代替できるものがないか探します。その中で無理やりすぎる結合はデバッグに支障をきたすことや責務の分散が犠牲になることを学ぶことも大きな収穫でした。

僕の発表

いくつかの発表内容がありましたが、その中の「ワイヤーコネクトグラフィック」だけシーンを見ながら簡単に説明します。その他の発表に関してはテキストで触れるだけに留めます。

PythonSOPの利用法とVerbについて

PythonSOPの使い所がイマイチわからないという声をいただいたのでその説明を行いました。(以下ツイートみたいなやつとかについてです)

https://x.com/kickbase/status/1936755624966316498

レガシーな使用法とVerb(動詞的使用)を用いて同じテーマを実装することにより理解を深めていただく構成にしました。

Houdini Engine for Unrealにおけるデータの取り回しについて

複数HDA間でパラメータを一括して取り回しできるデータ構造と、さらに各々のHDAにおいてパラメータをオーバーライドすることのできる仕組みを紹介しました。

事故の起こりにくいデータ構造でスマートに運用したいものです。

ワイヤーコネクトグラフィック

main

ロジック

01

まずは簡単のため一つのワイヤーで考えてみましょう。

  1. 任意のポイントを2つ用意し、それらを始点終点とする
  2. 始点と終点を中心部に対して寄せたポイントを中点として作成する
  3. ResampleSOPでポイントを細かくリサンプルする
  4. SmoothSOPでスムージングをかける

これでなめらかにワイヤーが接続された表現ができそうです。

※ もちろんConvertSOPを利用してベジェ曲線に変換してもいいでしょう。

まずは単純化

ノード数の削減や複数のポイント対応、クリックした点へのワイヤー作成など、やりたいことはひとまず置いておいて、まずはノード数を考慮せず実装してみましょう。ここで重要なのは中点の作成になりそうです。

最終的にはこのようなネットワークになりました。

02

順に重要な処理を見ていきましょう。

始点と終点の作成

03

AddSOPを使用して始点と終点を作成します。ここは問題ありませんね。

中点の作成準備

04

Match SizeSOPを使って始点と終点をまとめて原点中心に移動させます。その際Stash Transformをオンにすることもポイントとなります。

中点の作成

05

Match SizeSOPから分岐させたあとTransformSOPを用いてX軸に対してスケールをかけます

調整するパラメータが移動ではなくスケールであることが重要なポイントです。

先程のMatch SizeSOPでセンタリングしたおかげで、始点と終点の間を同距離移動した中点を作成することが可能になります。またスケールを用いることで0~1で正規化できるのもユーザーインターフェイスとして嬉しいポイントです。

ラインの作成

06

MergeSOPSortSOPAddSOPを経てラインを作成し、ResampleSOPを用いてポイント数を増加させます。

元の位置に戻す

07

原点にセンタリングしたことで中点をシンプルに作成できましたが、元の位置に戻す必要がありますね。

それも先程Match SizeSOPで仕込んでおいたxformアトリビュートを用いることで簡単に実行できます。

最終形

08

登壇ではステップバイステップでネットワークをリファクタリングしていった工程を説明しましたが、ここでは最終形の紹介に留めます。

attribwrangle_create_line
vector pos_list[] = {};
int max = npoints(1);

for(int i=0; i < max; i++){
    vector p = point(1, 'P', i);
    p.y = 0;
    append(pos_list, p);
};
vector start = pop(pos_list, 0);

for(int i=0; i < len(pos_list); i++){
    int prim = addprim(i, "polyline");
    vector p = pos_list[i];
    vector center = (start + p)/2.0;
    vector p0 = start - center;
    vector p1 = set(p0.x*ch('ratio'), p0.y, p0.z);
    vector p3 = p - center;
    vector p2 = set(p3.x*ch('ratio'), p3.y, p3.z);
    int p0_v = addpoint(0, p0 + center);
    int p1_v = addpoint(0, p1 + center);
    int p2_v = addpoint(0, p2 + center);
    int p3_v = addpoint(0, p3 + center);
    addvertex(0, prim, p0_v);
    addvertex(0, prim, p1_v);
    addvertex(0, prim, p2_v);
    addvertex(0, prim, p3_v);
}

VEXの詳細な解説は控えますが、TransformSOPMergeSOPAddSOPを使用してポリラインを生成した箇所やMatch SizeSOPをふたつ利用して位置をセンタリング・復元していた処理をattribwrangle_create_lineノードひとつで処理しています。だいぶエコになりましたね。

本記事では本筋から外れるためPython Viewer Stateを用いたポイントの作成も割愛します。

まとめ

他の発表も素晴らしく、各々の学習結果や得意分野について熱く語っていただけました。

Houdiniは非常に幅広い分野をカバーするパワフルなツールなので、専門以外の分野から受ける刺激も良い化学反応を生み出してくれます。

またノードベースアプリケーションの宿命として存在する「知らないノードは作りようがない」という問題も、勉強会に参加することでカバーすることが可能です。

この勉強会はクローズドな勉強会なので、参加希望の方は僕のアカウントめんたいこ(@kickbase) / Xまでお声がけください。

Discussion