パーティクルの進行方向は変えないまま、速度だけいじくりたいの。
唐突ICE。
基礎パーツな ICEツリー記録。
パーティクルの進行方向は変えないまま、速度だけいじくりたいの。
Point Velocity, Length, Resize Vector
↑同じ画像を、別ウインドウで開く
Emitコンパウンドで初期状態を決めています。PPG の中ではPの大きさや形なども決めていますが、それらはこの話では重要ではない。 ここで重要なのは、Speed と Direction です。 Randomize Direction でPの方向を決定しています。そして Speed は 10 です。これで、向かうべき方向とその速度が決まりました。 西へ、時速300km で進む、みたいな。 東京から大阪行きの新幹線に乗った瞬間みたいなもんです。
このPを放置プレイすると、そのベクトルでその速度のまま、永遠に進み続けます。大阪を越えて福岡まで行ってしまうかもしれないということです。 なので、毎フレームちょっかい出すことにします。 方向と速度にちょっかいを出してあげるのですが、今回は方向にはちょっかい出さず、速度にだけちょっかいを出します。
まず Get Point Velocity でベロシティを取得してます。 ベロシティってのはベクタなわけですが、 「 方向 」 と 「 長さ(速度) 」 の両方の概念を含んでいると考えればいいんじゃないんですかね。 例えば 0,10,0 というベクタは、X や Z にはちっとも向かっておらず、Yプラス方向にのみ向かってまっせ、という方向情報を持っていますが、方向だけではなく、その長さ(速度)は 10 でっせ、という速度情報も持っています。 0,10,0 と書くだけで方向も長さ(速度)も表せてしまう、と考えるといいような気がします。
で、その速度の部分だけ取り出してちょっかい出します。Length というノードです。ベクタのインプットを食って、そのベクタの長さ(この場合の速度)だけを吐き出してくれるノードです。
Length ノードによって長さ(速度)だけを分離できたので、それに 0.95 を掛けています。 x 0.95 なので、長さがちょっと短くなりました。つまりこの場合、速度がちょっとだけ落ちました。
いや、まだ速度落ちてません。机上の計算を行っただけです。Pにその速度をセットし直してやらねばなりません。 そこで Resize Vector コンパウンドです。 このコンパウンドは Vector と Length を別々にを食い、Length を掛け合わせて新しいベクタを生成します。 方向はいじってないのでそのまんまであり、Length だけ 0.95 かけて短くなった結果が、新しいベクタです。
最後にそれを Set Particle Velocity でセットし直してやります。これで終わり。
この1連の流れが、毎フレ起こります。 毎フレ起こるのは、ICETree が Simulation モード以下にあるからです。
毎フレ起こるということは、次のフレームで取得されるベロシティは、さっきの計算で速度だけが一度 0.95倍されたベロシティです。 次のフレームでも再び、 x 0.95 済みの値にさらに x 0.95 します。こうして1フレごとにどんどん速度が落ちます。 方向にはちょっかい出してないので、最初に与えられた進行方向は維持したまま、速度だけがどんどん落ちていくという状態です。
こうして大阪行きの新幹線は、だんだん速度を落とします。まだ名古屋あたりかもしれません。たこ焼きをあきらめて手羽先にしようかどうか迷います。落合さんお疲れ様でした。
以上。
ええとですね、Vector から Length を取り出してごにょごにょってのは何度かやったことあったのですが、今回、ごにょごにょした結果をどうやってパーティクルのベロシティに戻してあげるのか、ってのを知らないことに気づいたのです。
って言うよりは、方向と長さに分離された2つの情報をどうやって1つのベクタに戻してあげるのか、を知らないことに気づいて焦ったんですね。 調べてたら Resize Vector にたどり着いたので、こうして記録しておきます。
ちなみに。
上記のツリーは、Get Data ノードで PointVelocity アトリビュートを取得し、そこから Length で長さを分離したわけですが、これを1つのノードで代替することもできました。
Get Data と Length を取っ払い、代わりに Get Particle Velocity コンパウンドにしました。このコンパウンドは、アウトプットに Velocity と Speed があるので、自分で Length ノードを足してやらなくても方向と長さ(速度)に分離できます。
ってよりも、このコンパウンドの中身を見てみればわかりますが、
そのまんま、Get Data で PointVelocity を取得し、Length ノードを使って長さ(速度)を取り出しているだけです。さっきやったのと全く同じじゃねえか。 ってことで、どっち使ってもいいです。 けど、このコンパウンド使えばノード数は減らせますね。
さらに。今回の用途であれば、Get Particle Velocity まで廃して、もっとシンプルにできます。
今回は「方向」にはちょっかい出さず、「速度」しかいじらないと決めています。ならば、Get Particle Speed と Set Particle Speed というコンパウンドがあるので、こいつらを使えば、最初から速度だけをいじっている状態になりますから、楽です。 ベクタを方向と速度に分解し → 速度だけいじくり → またひとつのベクタに合体し直す なんてことはしなくて済みます。
でもまあ、この2つのコンパウンドの中身を見ればわかりますが、やはり同じく Get Data で PointVelocity を取得して、かつ Length ノードで長さ(速度)を取り出しているんですよ。ただしこちらは、Speed しか関知しないという名目なので、アウトプットに Vector はなく、Speed だけになっています。 この違いだけです。 つまり表面に見えているパラメータを限定し、わかりやすくしているというだけで、処理的には、Length ノードつないでやったのと全く同じことをコンパウンドの中でやっていることになります。
このシーンのダウンロード(XSI 2012)
JJJ_ResizeVector.zip (246.1K)
とかなんとか。
ではごきげんよう。
---------------------------------------------
以下追記。
コメント欄参照。
mskさんが指摘してくれてますが、素直に Velocity を Multiply by Scalar で小さくしてやるのが最もシンプルなやり方だと思われます。 イエス、その通り!
.
| 固定リンク
コメント
速度だけを変えたい場合は細かいことを考えずに
GetParticleVelocity - MultiplyByScalar - SetParticleVelocity - Execute
でMultiplyByScalarのFactorで調整してました・・・
投稿: msk | 2011年11月22日 (火) 19時18分
msk さん、たぶんそれでいいでよねえ。うん。
いや、実は俺も無理に難しく考えたつもりもなくてですね、まあアレです、今回の場合は、Length で取り出して何らかのごにょごにょをした場合、Resize Vector で戻すという方法があるぞ、というのを記録しておきたかったのです。 もともとは、必ずしもパーティクルの減速の方法を記録したかったわけではないという感じ。
なので、タイトルが不適切というか、もともとの動機を示していませんね。すいません、後付けです。 Resize Vector の方が俺の中で、より関心がありました。
でもまあ、もっともシンプルな方法として、追記しておくかあ。
投稿: junki | 2011年11月23日 (水) 02時25分
考えてみたらResize Vectorは一度も使ったことありませんでした。
と、中を見てみたらノーマライズした上で
新しいLengthをMultiplyByScalarでかけているだけなんですね。
Stateごとに速度を変える場合などに
すべてResize Vectorを使えば
絶対的な値としてわかりやすいかもしれないですね。
投稿: msk | 2011年11月24日 (木) 10時55分