Houdini Advent Calendar 2025:21日目の記事です。
外部ツールなどで作った木のデータなどをそれっぽく動かしたい場合とかとか。
Houdini上で作ったものでも後からちょっと回転させたりしたい場合に使えたり。

Scene File
pack_addRotate.hipnc - Google ドライブ
木のモデル
これは一旦 Labs Quick Basic Treeで作成

作り
必要なアトリビュートを作成する
まず原点に戻す必要がある。今回は葉っぱなので、UVを使用して戻している。

Extract Transformを使用して、原点と実際のメッシュでのorient, scale, pviotを取得する。

orientからN, up, outを抽出する。この作りでは意味がないが、Attribute Type Infoも念の為設定しておく。
v@up = qrotate(p@orient, {0,1,0});
v@N = qrotate(p@orient, {0,0,1});
v@out = qrotate(p@orient, {1,0,0});
setattribtypeinfo(0, "point", "out", "normal");
Pivotのオフセットをする
動かしたいメッシュをPackする。

前段階で計算したアトリビュートをPackしたメッシュへ転送する。

以下VEXでPivotをオフセットする。これはPrim Intrinsicのアトリビュートにpivotがあるのでこれを書き換える。Pivotをずらすことによって、回転するための中心点を好きな場所に定義できる。
この辺りの処理はオフセットしたい軸などによって書き換える必要がある。

vector _pivot = primintrinsic(0, "pivot", @primnum); //ここではupだがオフセットしたい方向次第でN ,up,outから選ぶ vector _dir = point(0, "up", @primnum); float length = length(_dir); vector dir = normalize(_dir); //オフセットに使うためのScale vector _scl = point(0, "scale", @primnum); //オフセットに使うため、UV展開時のYが一番低い部分の値を取得 vector _bbox = point(0, "_bbox", 0); //Pivotをオフセットさせる _pivot += (length *(abs(_bbox[1]) *_scl.y)) *dir; setprimintrinsic(0, "pivot", @primnum, _pivot); //そのままだと元のポジションからずれてしまうのでPもオフセットする vector pivotOffset = (length *(abs(_bbox[1]) *_scl.y)) *dir; setpointattrib(0, "P", @primnum, pivotOffset, "add");
回転の値をノイズで作る
Attribute Noise Floatを使用して、X ,Y,Zそれぞれの軸ようにノイズで-1から1のオフセットの値を設定する。
このアトリビュートで回転量を制御するので、一部だけ止めたい場合や途中から変えたい場合などが手でコントロールできる。

//rotate
matrix m = primintrinsic(0, "packedfulltransform", @primnum);
matrix3 rot = ident();
rotate(rot, ch("rotation_X") * f@rotNoiseX, v@out);
rotate(rot, ch("rotation_Y") * f@rotNoiseY, v@up);
rotate(rot, ch("rotation_Z") * f@rotNoiseZ, v@N);
setpackedtransform(0, @primnum, m * rot);
そうすると原点で指定した軸ごとに回転するジオメトリができる。

最後にもう一度Pを戻す
v@P = point(1,"P",@ptnum);
