-加筆中-
Houdini習得の壁の1つに位置、回転、スケールを追従させるコンストレイントがある。他のソフトでは当たり前な機能だがHoudiniは自分で実装しないといけない。方法も様々あって迷いやすいところなので整理しておく。
#位置コンストレイント
##➀ Expression
コンストレイントしたいメッシュのポイント番号をExpressionのpointに指定して移動させる。
シンプルで使いやすい。
サンプルは、ポイント番号が3、最後の0,1,2はvectorなのでx,y,zの意味。
point("../transform1",3,"P",0)
point("../transform1",3,"P",1)
point("../transform1",3,"P",2)
##➁ copytopoints
コンストレイントしたいポイントにcopytopointsでコピー。
##③ wrangle
コンストレイントしたいポイントをwrangleに入力してpoint関数で位置をコピー
point関数でwrangleの2番目の入力から位置をコピー
@P += point(1, 'P', 0);
##④ packed
primintrinsicの配列から位置をコピー。
packしたメッシュは、モデルの中心に基点がかわる。
この方法は使わないがpackオブジェクトのprimintrinsicの知識として入れてみた。
matrix mat = primintrinsic(1, "packedfulltransform", @ptnum);
@P += set(getcomp(mat,4,0), getcomp(mat,4,1), getcomp(mat,4,2));
##⑤ matrix
maketransformで移動量の3x3マトリックスを作ってポジションに乗算
int pnum = chi("point_number");
vector point = point(1, "P", pnum);
vector center = getbbox_center(0);
@P *= maketransform(0,0,point-center ,set( 0, 0, 0 ),{ 1, 1, 1 },center);
#回転コンストレイント
Houdiniには非常に沢山の回転に関する機能が用意されているが大別するとXYZ軸回転(オイラー)と姿勢回転(クオータニオン)の2種類に集約される。
XYZ軸回転は、位置、回転、スケールの情報の入った3x3のmatirxを@Pに乗算することで変換するシンプルな方法。ただし、数学的な知識が必須なのでデザイナーには扱いずらい。
一方、姿勢回転は、向きと角度からなるquaternionをアトリビュートで扱いcopy to pointsノード(以降copyノード)で変換する方法。こちらはアトリビュートだけで制御ができるのでデザイナー向き。ただし、細かい制御をするとなるとmatrixを使う事になる。
扱いやすく応用範囲が広く実践的なのは姿勢回転なので、copyノードを利用したケースを中心に説明を進めていく。
姿勢回転は、向きと角度の2軸で回転を表す考え方で飛行機に例えると進む方向が向き(N)、上を示す垂直尾翼が角度(up)となる。2軸で事足りるのは、3軸目となる2つのベクトルの垂直方向は、外積(cross)で求められるからであり、X,Y,Zに相当するのがcross, up, Nである。
copyノードは、transformに関わる以下のアトリビュートを使ってオブジェクトを変換する(他にも多くのアトリビュートがある)。
v@N 法線(Z軸)
v@up upベクトル(Y軸)
f@pscale 均一なスケール
v@scale 各軸を個別にスケール
p@orient 向きをquaterniondで定義
p@rot 回転をquaternionで定義
copyノードは、アトリビュートの@Nの向きと@upの角度の2軸があれば回転ができ、これらはNormalとPolyFrameノードで求めることができる。
ここで注意しないといけないのは、copyノードは@Nの1軸だけでも回転ができ問題ないように見えることだが、ある角度になると反転して制御不能になるのでキチンと2軸を指定しないといけない。
##➀ copytopoints (orientアトリビュート)
copyノードを使った向きと角度だけの一番単純な回転コンストレイント。面に対してそのまま回転コンストレイントするだけならこれで十分。
@orient = quaternion(maketransform(@N, @up));
##➁ copytopoints (rotアトリビュート)
copyノードを使った3軸の調整が可能な回転コンストレイント。各軸のradiansに角度を入れて自由な回転を追加できる。
matrix3 matx = ident() , maty = ident() , matz = ident();
vector4 @rot;
float anglex = radians(0);
vector x = cross(normalize(v@up),normalize(v@N));
rotate(matx, anglex, x);
float angley = radians(0);
vector y = cross(normalize(v@up),normalize(x));
rotate(maty, angley, y);
float anglez = radians(0);
vector z = cross(normalize(x),normalize(y));
rotate(maty, anglez, z);
matrix3 mat=matx*maty*matz;
@rot= quaternion(mat);
##➂ matrix
①のcopyノードの方法をmatrixに切り替えた方法。学習用に作ったものなので実際に使うことはないかも。
vector N = point(1, "N", 0);
vector up = point(1, "up", 0);
vector P = point(1, "P", 0);
vector x = cross(normalize(up),normalize(N));
vector y = cross(normalize(up),normalize(x));
vector z = cross(normalize(x),normalize(y));
vector center = P;
matrix m = set(x, y, z, center);
@P*=m;
##④ copytopoints (位置、回転、スケール ローカル軸対応)
copyノードを使った一番実践的な回転コンストレイント。コンストレイントした面のローカル軸で位置、回転、スケールの調整が可能。
このサンプルではやっていないがノイズを使って個別に回転を変えることも可能。
##⑤ matrix (位置、回転、スケール ローカル軸対応)
④のcopyノードを使った方法をmatrixに切り替えた方法。複雑になってしまうので1つの面のコンストレイントにしている。
学習用に作ったものなので実際に使うことはないかも。
HIPファイル
データの動作環境:
Houdini Apprentice 18.0.348
ダウンロード先リンク(Github):
https://github.com/DefultVFX/houdini/blob/master/constraint.v2.hipnc