資料館/ヒート剣を出す

Last-modified: 2008-04-29 (火) 10:17:01

がいよう

さて、ネチネチ研究を続ける筆者が今回お送りするのは、ヒート剣を出す、というガンダムを知らない人にとっては良く判らんものだ。
何かいい画像は無いかとググっていたところ、こんな感じのブツを発見したのでリンクを貼っておく。
ブゥィーン



これならば大抵の人間は、少なくともこの資料館を読んでるような方なら理解していただけるだろう。

方法

さて、どうやって刀身に光を這わせるかだが、今回は例によってパーティクルを用いてみることにする。以下、光を這わせる刀身部分を「ブレード」と表記する。

  1. ブレードの根っこと先端をボーンで繋ぐ
  2. 根っこと先端のベクトルをボーン座標から求める
  3. ベクトルをパーティクルの直径x2で割ってやり、パーティクルを重ねていく

例によって絵で表すと以下のようになる。
buwin.jpg

先端に向かってパーティクルが重なりながら延びていく。
恐らくパーティクルIDを複数作成し、寿命が1のパーティクルを毎フレーム作成しまくれば良いはずだ。ちょっと帰ってきたらやっておくので待っててください。
例によって出来上がったので、見てみることにしよう

素材の準備

まず、次のようなモデルを作った。
model.jpg
柄と刃で大まかにオブジェクトを分け、柄の部分を"tuka"、刃の部分を"beam"とそれぞれ命名した。
後述するが、今回は刃の部分は描写時に消してしまうので、形などはどうでもいい。


次にコレにボーンを入れる。
sigfile.jpg丸で囲んだ部分にボーンが入っている。
親子関係などはとりあえず今回はどうでもいいのだが、適当につけておいた。またこのうち実際に使用するボーンは上の二つだけである。ブレードの根っこ付近のボーンに"root"、先端のボーンに"reaf"と名づけた。

パーティクルはとりあえずロボゲーから持ってきた。
part.png
何かこんな感じに適当に透明ならいい。後述する少し高度な処理を行う場合は、このあたりきちっと作る必要があるかもしれないが、とりあえず適当に半透明な○を用意した。

パーティクルの生成

パーティクルはフレーム単位で扱うようになってます。
以下の文章もパーティクルはフレーム単位で扱うもんだと仮定しています。
filehblade.zip
とりあえず最低限用意したセットを添付しておいたので、ソースを見ながら読んでもらえばわかりやすいはずだ。ソースを上から見ていこう。
まずはパーティクルの数と大きさを決める。今回は適当に100個とした。カメラの位置を適当にツかんだ所で剣のオブジェクトを読み込む。




次にパーティクルを生成する。今回の表現の肝は生成数1のパーティクルを串団子の如く並べるという事に集約される。
例えば100個パーティクルを出すなら、一回の描写命令で100個生成するのではなく、1個描写命令を合わせて100回呼ぶ必要があるのだ。一個しか生成しないパーティクルとはおっそろしく贅沢である。
ちなみに実行結果はこんな感じになる。
kekka1.jpg

さて、ソースを下へ進んでいくと描写命令を呼ぶメインループに行く。
ためしにコメントアウツすればわかるのだが、描写の際にブレード部分が邪魔になるので、描写前に一度無効にした後もう一度有効にするという処理を行っている。
恐らく次のE3Dchkinviewまでに元に戻せば当たり判定には関係ないはずだが、当たり判定用にもう一つ不可視なオブジェクトを用意しておくのも手ではある。

実際にパーティクルを描写する

サブルーチンジャンプでパーティクル処理へ飛ぶ。
まず、"root"、"reaf"の位置を取得する。そこからおわりひくはじめによってベクトルを求める。
この、終わり引く始め、という言葉はオイラの高校の先生が口癖のように言っていた言葉で、頭の悪いオイラでもベクトルを導き出すことが出来るノーベル賞モンの公式である。


適当に場を和ませた所で、ベクトルの長さを求めよう。ベクトルの長さを求めてくれる関数があるのでそれを使う。このベクトルの長さ*1が、実際にパーティクルで表示されるブレードの長さになる。
この長さを直径で割ることで、パーティクルが何個必要になるかがわかり、その回数だけ描写命令を呼べば良い。




試しに、MITSUDOを1にして実行してみればわかるのだが、パーティクルが重なっていなくて全然剣に見えない。
実際に剣っぽく見せるには、パーティクル同士の密度を上げて重ねてやる必要がある。今回はパーティクルがちょっとボケボケなので、密度に4を指定すると丁度良くなる。さて、密度とパーティクルの大きさから、ベクトル中に何個パーティクルを置けば良いのか判明したので、実際に描写命令を呼ぶ。
最初は根っこの部分に座標をセットし、描写するたびに少しずつ先端へ向けて描写位置をずらしていく。
毎フレーム消えるパーティクルを生成してやることで、剣を滑らかに振り回すことが出来る。


逆に、一個のパーティクルIDに複数個パーティクルを出せるようにしてやれば、残像を出すことも出来る。このようになる。
kekka2.jpg
fileheat02.hsp
ソース。パーティクルの宣言が少し変わっただけである。図を見ると一箇所パーティクルが途切れているように見える。これは寿命とパーティクルの数が同じになっているからである。寿命を迎えるフレームを考慮し、パーティクルの生成数には寿命+1を指定しないといけないので注意しよう。悪い見本をあえて実践した。直すのめんどくさいとかそういうのじゃないです。




更に気付いたのだが、パーティクルを滑らかに表示させるためには、描写命令の後にE3Dinitparticleを呼ぶのが良い。
ソースなどは修正しておくが、オイラが書いているのを見ながらダウンロードしちゃったせっかちさんは、適宜改善するか、ダウンロードしなおすように。

弱点

今の所主に考えられる弱点

  • 平べったいものは表現できない
  • 細さと密度に重さが比例する

応用例

あえてパーティクルに適当な初速を与えることでビームを拡散させる。この場合、パーティクルの寿命や生成数を増やすことでより拡散したような感じが得られる。生成数を2にして動画を作っておいた。
&flash(http://www.youtube.com/v/KyvUEsxeIig,425x350,bgcolor=#000000);
パーティクルは拡散しているのに何故か出力が強まったような感じだ。数字を上げれば上げるだけ粒子は増えるが、増やしすぎると分けわかんなくなるので&激重いので控えるように。こうなる。
imihumei.jpg

改良の余地

まず、パーティクルの太さを複数用意し、色々変えてやることで動きを出す。
これも動画でないとわからないと思うので、youtubeにアップロードしておいた。
&flash(http://www.youtube.com/v/B1xzyIXlRIo,425x350,bgcolor=#000000);
次に場所によって太さを変える等の方法があるが、コレはめんどくさいので各自研究してください。
また、剣のサイズなどが不変ならば、板のようなモデルを使ったり、別のモデルを重ねたりしてこんな感じの処理が出来るかもしれない。ていうかやり方教えてください。いいものが出来たら教えてください。他力本願です。


*1 正確には、この長さ+パーティクルの半径