この記事はHoudini Advent Calendar 2016の一日目の記事です。
# copySOPのstamp
サンプルとして机を用意しました。まずは初心に帰り、基本中の基本copySOPのstampから。
*注意
(Houdiniを触り始めたての方は、
https://www.sidefx.com/tutorials/introduction-to-procedural-modeling-lesson-3-copy-me/
などでcopyを理解しましょう)
(分かりやすくするために机のオブジェクトを使用していますが、デフォルトではデータがないので、自分で行う場合はtestgeometryを使ってください)
## copySOPの基本
オブジェクトはpointごとの配置となります。
5x5のgridを作成し、copyと接続します。
こうした場合Transform Using Template Point Attributesのチェックを外したり、copyするobjectに対してtransformを行い回転させたりします。
しかし、この方法はあまり好ましくありません。なぜならば、今このときを限って言えば上手く動作しているのですが、ひとたびtemplateのデフォームが発生した場合、意図せぬ配置になる可能性があるからです。
▼Transform Using Template Point Attributesのチェックを外した場合、まったく動かない
では、どうすべきか。ここはpointのattributeにupベクトルを与えてあげましょう。(解説は後)
では、机ごとに少しランダムな回転をかけるためにstampを使いましょう。
StampInputsをオンにしてVariable1に変数名を与えます。値は適当に-22.5~22.5度にします。
そして、transoformのRotateに以下のstamp()を入れます
stamp("../copy","rot",0.0)
## ん?何か重くないか?
しかし、このstamp処理は重いです。数個なら問題はないでしょう。しかしコピーの数が数百となった日には…。
しかしcopyは悪くありません!諸悪の根源はstamp!であれば、stampを消してしまえ!
# PointAttribute
代わりにPointAttributeを利用しましょう。
(ヘルプ:http://www.sidefx.com/docs/houdini15.0/copy/instanceattrs)
Attribute name | Data type | Description |
---|---|---|
orient | float4(quaternion) | コピーした時の方向 |
pscale | float | xyzに均等なスケール |
scale | float3 | xyzに不均等なスケール |
N | vector | 法線 |
up | vector | Upベクトル |
v | vector | Velocity |
rot | float4(quaternion) | 回転 |
trans | vector | 移動 |
pivot | vector | ピボット |
shop_materialpath | string | マテリアルのpath |
material_override | string | マテリアルの上書きパラメータ |
この表で気を付けなければならないのは、「型(データタイプ)」です。
コピー時に型が違うと、名前が同じであっても完全に無視されます。
# 実践 PointAttributeを利用する
基本となる移動、スケール、回転について紹介していきます。以下のVEXはcopySOPのtemplateに入れる手前に作成したAttribute Wrangle(Run Over:point)で実行していきます。
例は移動量などで2を用いていますが、@Timeなどを上手く利用すると徐々に大きくなどの動作も可能です。
## 移動
Y方向に2移動します
v@trans=set(0,2,0);
## スケール
pscaleとscaleは型が異なります。
pscaleは直接floatを、scaleはvectorなのでset()などを利用します。
### 均等に2倍
@pscale=2;
### Y方向に2倍
(0倍だと消えてしまうので、XとZにも1倍を与えてやる必要があります)
@scale=set(1,2,1);
## 回転
軸をupベクトルにしています。
ident()はただの単位行列、upベクトルとgridからの法線を利用して回転行列を作成します。
matrix3 matx = ident() , maty = ident() , matz = ident();
vector4 @rot;
v@up = set(0,0,1);
float anglex = radians(90);
vector axisx = cross(normalize(v@up),normalize(v@N));
rotate(matx, anglex, axisx);
float angley = radians(20);
vector axisy = cross(normalize(v@up),normalize(axisx));
rotate(maty, angley, axisy);
float anglez = radians(10);
vector axisz = cross(normalize(axisx),normalize(axisy));
rotate(maty, anglez, axisz);
matrix3 mat=matx*maty*matz;
@rot= quaternion(mat);
いきなり直接クォータニオンを利用しない理由は、クォータニオンの戻り値はvector4のため、matrixのように複数の座標系を乗算することができないからです。
そこで今回は先にmatrixで計算を行って、そのあとからクォータニオンでvector4の形に変換させています。
#そのあとは
PointAttributeを利用すると、ノードもすっきりしてインスタンスの処理が行いやすくなります。
下準備ができたら、あとはそのままcopySOPやInstanceSOP、Delayed Loadなど好きな手法でコピーしてみましょう。
http://blog.livedoor.jp/fujitarium/archives/52412058.html
(外部リンク:fujitarium「Houdini検証 インスタンス&コピー」)
マテリアルをpointごとに変える場合は、shop_materialpathとmaterial_overrideを利用します。
考え方は同じで、pointに対してmaterial情報を書き込みます(Wrangleでなくmaterialノードを利用するほうが良いでしょう)。このattributeはpointでなく、オブジェクトに対して適用したいので少し工夫が必要です。copySOPのattributeタブにおいて、Use Template Point Attributesを有効にし、To Primitiveでshop_materialpath material_overrideを入れます。そうすることでマテリアルをpointごとにバラバラにすることも出来ます。
以上