4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Houdini ApprenticeAdvent Calendar 2018

Day 11

CopyのStampを使わずに花が咲広がるアニメーション

Last updated at Posted at 2018-12-24

#はじめに
こんにちは。フジヤマタカシです。調子にのってHoudini Apprentice Advent Calendar 2018、4つ目の投稿をさせていただきます。
今回のは花畑で花が咲広がるアニメーションをCopyのStamp機能を使わずに行います。
fujitaさんの記事の中でCopy Stampはなるべく使わず、アニメーションに関してはなるべくCopyよりも下流で行うとの話があったので、勉強のためそれに挑戦してみようと思います。

#単体の花びらアニメーション
ベースのシェイプはGridとランプで適当に用意します。
Screenshot from 2018-12-24 00-00-02.png

花びらのアニメーションに関しては前の記事で紹介したBendのテクニックを使うので、まずはBnedの関数を用意します。

////function fn_rot////
matrix3 fn_rot(float r_val; vector axis){
    matrix3 rotM = ident();
    rotate(rotM, r_val ,normalize(set(axis)));
    return rotM;
}
////function fn_trans////
matrix fn_trans(vector position){
    matrix transM = ident();
    translate(transM, position);
    return transM;
}

/////function fn_bend//////
matrix fn_bend(vector P, pivot, dir, axis; float dist, angle){
    matrix bendM  = ident();
    bendM *= invert( fn_trans( pivot ));
    float dot = dot(normalize(dir),P*bendM);
    matrix horizonDir = bendM * invert( fn_trans( normalize(dir) * dot));
    float bendArea = fit(dot,0,dist,0,1);
    if(bendArea < 1){
        bendM = horizonDir;
    }else{
        bendM *= invert( fn_trans(normalize(dir) * dist));
    }
    float angAmount = angle * min(dot,dist)/dist;
    float axisOffset = dist/angle;
    vector axisPos = normalize(cross(axis,dir)) * axisOffset;
    matrix3 rot = fn_rot(angAmount,normalize(axis) );
    if(bendArea > 0 && angle != 0){
        bendM = bendM * invert(fn_trans(axisPos)) * matrix(rot) * fn_trans(axisPos) * fn_trans(pivot);
    }else{
        bendM = ident();
    }
    return bendM;
}

bendの式はmatrix fn_bend(vector P, pivot, dir, axis; float dist, angle)と設定してあるので、アングルをアニメーションさせます。

`chs("../fn_bend/snippet")`

float bloomStart = length(v@flowerCenter)* 20;
float bloomAnim = fit(@Frame - bloomStart,0,25,0,1);

float bloom = fit01(bloomAnim,-0.32,2);

matrix bendB = fn_bend(@P, set(0,0,0), set(0,1,0), set(1,0,0), 0.4, bloom);

@P *= bendB;

float bloomAnim = fit(@Frame - bloomStart,0,25,0,1);の部分で24フレームアニメーションさせています。
gaxgm-erino.gif

#花のひらくアニメーション
circleを作りそのポイントにベースシェイプをコピーします。その時にポイントにアトリビュートを用意しておきます。

@N = -normalize(@P);
@up = set(0,1,0);

v@petalCenter = @P;

Screenshot from 2018-12-24 00-29-58.png
N up は花びらの向きに必要で、それにpetalCenterを加えたそれぞれのアトリビュートはBendの為に必要なパラメータなのでコピーの際に移しておきます。
Screenshot from 2018-12-24 00-35-34.png

それぞれのアトリビュートをBendの関数の中に埋め込みます。

`chs("../fn_bend/snippet")`

float bloomStart = 1;
float bloomAnim = fit(@Frame - bloomStart,0,24,0,1);

float bloom = fit01(bloomAnim,-0.32,2);
matrix bend = fn_bend(@P, v@petalCenter, @up, cross(@N,@up), 0.4, bloom);
@P *= bend;

jbi4n-k16jv.gif

#花畑のアニメーション

先ずは適当にScatterで花のポイントを作ります。
Screenshot from 2018-12-24 00-50-38.png
そして用意したアトリビュート

i@flowerid = @ptnum;
v@flowerCenter = @P;

@up = @N;
@N = cross(@up,set(1,0,0));
v@floweraim = @N;

花の向きの為up Nを用意します。floweraimは得に無くてもいいですが最終的に花の角度を調整したい場合に必要です。
そしてCircleで作ったポイントをScatterのポイント上にコピーします。
Screenshot from 2018-12-24 00-58-40.png
ScatterのNとupはコピー先に読み込みさせませんが、Circle上で作ったNとupが、ScatterのNとupを元に調整されているのが分かります。(赤はfloweraim。これは移行させる。)

それからコピー後にv@petalCenter = @P;で花びらの中心アトリビュートを用意します。

これに花びらシェイプをコピーしたら準備は整いました。
Screenshot from 2018-12-24 01-08-16.png

これに対してアニメーションコードを書きます。

`chs("../fn_bend/snippet")`

float bloomStart = length(v@flowerCenter)* 20;
float bloomAnim = fit(@Frame - bloomStart,0,24,0,1);

float bloom = fit01(bloomAnim,-0.32,2);
matrix bend = fn_bend(@P, v@petalCenter, @up, cross(@N,@up), 0.4, bloom);
@P *= bend;

花単体との違いはfloat bloomStart = length(v@flowerCenter)* 20;で中心から離れた花ほど咲くタイミングを送らせてるだけです。

i1eq1-oezlz.gif

これだけではAnimation Packを使った方が早いので、せっかく用意したアトリビュートを元にもう少し複雑にしてみましょう。

`chs("../fn_bend/snippet")`
int uniqueid = i@flowerid * 100 + i@petalId;
@Cd = lerp( set(fit01( rand(i@flowerid + 11),0.5,1),fit01( rand(i@flowerid + 22),0,0.2),fit01( rand(i@flowerid + 22),0,0.2)), vector(rand( uniqueid) ), 0.3);

float bloomStart = length(v@flowerCenter)* 18;
float bloomAnim = fit(@Frame - bloomStart,0,20 + rand( i@flowerid + 33)*10 ,0,1);

float bloom = fit01(bloomAnim,-0.32,1.8 + rand( uniqueid + 33));
matrix bend = fn_bend(@P, v@petalCenter, @up, cross(@N,@up), 0.4, bloom);
@P *= bend;

float scale = fit01(bloomAnim,0.75,1 + rand( i@flowerid + 33)*0.5);
@P = (@P - v@flowerCenter) * scale + v@flowerCenter;

float rot = rand(i@flowerid + 555) * 3.1415;
matrix3 randomrot = fn_rot(rot, @up);
v@floweraim *= randomrot;

float shakeVel = sin(bloomAnim * 3.141592 * 4) * 0.15;
matrix3 shake = fn_rot(shakeVel, v@floweraim);
@P = (@P - v@flowerCenter) * shake + v@flowerCenter;

@P += @up * fit01(pow(bloomAnim,0.5),-0.5,0);

花別のIDであるfloweridと花びらのIDであるpetalIdを使って、色々ランダム値を仕込んで見ました。(ちょっと分かりずらいのでもう少し大げさにすれば良かったかな・・・。)
p8xkb-z1j8g.gif
ネットワークを見てもらえればCopyノード以前はアニメーションされてないのが分かると思います。
Screenshot from 2018-12-24 01-52-18.png

作成したファイルはこちらになります。
https://drive.google.com/file/d/1Zx2MM6g2AYVh9ikeCbnsZxEAwuwq2VEo/view?usp=sharing

では今回は以上になります。ここまで読んでいただきありがとうございます!

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?