2012年2月 8日 (水)ICEを使ってみる 第4回 プロジェクト格子点 境界抽出
おはようございます、本日の当番モーションデザイナーのY.Nです。
今回もICEの基礎的な使用方法を取り上げます。
と、その前に一つ手痛い事があったので書いときます。
前回、メモノードに日本語を書くことができることが判って
喜々として日本語でメモしてコンパウンド化して保存しました。
で、久しぶりにそのコンパウンドを呼び出してきてみたところ…
日本語だけきれいに消えてるじゃないですか。
何書いてたかわかんね~!!
自分の浅はかさをまたまた痛感した次第です。
というわけで、今回、図内のメモはまた拙い英語になってます。
単語や文法に誤りがあっても、そこは優しく読み飛ばしてください。
さて、今回はループ処理を取り上げます。
まずは結果から。
前回、オブジェクトの形を2次元平面上の点で投影しました。
今回はその影の輪郭を取ってみました。
今回説明しようとしている事柄
・ループ処理
・負荷調査
以下、結果を得るまでの流れです。
1.グリッド(点の集合)を作成
2.グリッドからレイキャストしてHit点を取得&その他諸々変数設定
3.行/列ごとに境界上の点を抽出
4.行ごとのチェック結果、列ごとのチェック結果を合わせて、重複を削除
5.作った後のチェック
開始前に、前回同様ループの基本的な使用方法をメモっておきます。
今回はRepeat with Counterノードを使ってループ処理を作っています。
図では、下記3つの設定をしています。
・Num Iterations ポートにループ回数を設定
・In Name ポートにループ回数用カウンター名を設定
・Excecute Ech Iteration ポートにループさせる処理を設定
In Nameに関しては、デフォルト値 Self.CounterValueをそのまま使っています。
ここではループ1回ごとに配列に現在のCounterValueを入れるという処理をしていて
図の通り、0~4まで5個の値をちゃんと入力できた事が判ります。
基本をおさえられたかなと思いますので、冒頭の結果を出していく事にします。
■1.グリッド(点の集合)を作成
形状参照用オブジェクトは前回と同様Body-Manを使います。
点も前回とほぼ同じ処理で用意します。
ただ、今回は後でラクしたいので、点の各Indexで列ID(col_Index)を持つ配列と行ID(row_Index)を持つ配列を予め用意することにします。
たとえば、行方向にIDを増やしていくようにした場合、2行1列のグリッドを構成する点の列IDが{012012},行IDが{001122}となるように行/列IDを出力できるようにしておきます。あと、まだ使いませんが言葉として、点全体のIDを点IDと呼ぶことにしておきます。
■2.グリッドからレイキャストしてHit点を取得&その他諸々変数設定
レイキャスト部分も前回と同様です。
今回は、後で呼び出して使いたいので、レイキャスト結果を変数に入力しておきます。
また、1で設定した行/列IDおよび、点列の数、点行の数も変数に入力しておきます。
■3.行/列ごとに境界上の点を抽出
たとえば下図の赤枠の中の各点のレイキャストのhit結果は
{00000111000111000000} (0:false,1:true)配列A
となっています。
しかし、最終的に欲しい結果は、連続で1が繋がっている場合、両隣が1のものだけ0になった、以下のような配列です。
{00000101000101000000}配列B
なので、この配列Bを配列Aから作ります。
配列Aの先頭および末端に0を入れて作り直した配列C、Dを配列Aと比較して結果が異なるもののうち配列A側の値が1のものだけ残せば配列Bができますね。
{00000111000111000000}配列A
{00000011100011100000}配列C
{00001110001110000000}配列D
{00000AxA000AxA000000}配列B
Aは配列AC、配列ADの比較で配列Aが1他が0だったもの、xは1同士だったものです。
Aを1、xを0にすれば境界がでてきますね。
他にももっと良い処理があると思いますが、ここではこの方法で境界を抽出する事にします。
この処理をコンパウンドにまとめたものがFind array boundaryになります。
これで配列の境界点をTrueにすることができました。
この配列内TrueのIndexがそのまま列番号を表すことになるので、行番号と列番号から
点IDを特定する事ができます。
行内で境界をチェックする場合は、このチェックを行数だけループして結果を配列に追加、
列内の場合は列数だけループさせます。
■4.行ごとのチェック結果、列ごとのチェック結果を合わせて、重複を削除
列方向、行方向の境界点の配列情報を合わせると境界を縦横両方から囲む事ができます。
ここで、両方を合わせただけだと、重複している点が重複して制作されてしまいます。
今回は重複を許さない事にして、重複を排除する処理が追加します。
列方向の配列を列配列、行方向の配列を行配列とすると
最終結果 = 列配列 - 列配列∩行配列 + 行配列
です。
列配列∩行配列をどう出すかですが、ループを使えば簡単にできそうです。
という事で作ったのが下記。
コンパウンド化したものを処理に組み込んだものがコチラ
行配列から1つずつ要素を取り出して列配列と比較、列配列∩行配列の要素を
新しい配列に追加することで列配列∩行配列を作成しています。
という事で、ひとまず冒頭の結果を出す事ができるようになりました。
これで、出来た出来たと喜びたいところですが…
■5.作った後のチェック
この処理のなんと重いこと!
試しに処理負荷チェックをしてみました。
このボタンを押してアニメートさせるだけで負荷チェックできます。
簡単ですね。
グリッドセル数 100×100,グリッドセル縦列の値に1つだけキーを打ち、60フレーム再生した結果こうなりました。
図からも判る通り、ループを使っているところのコストが目に付きます。
確かにICEではループ処理は負荷が高いと言われています。
では一体、どれぐらい高いのか。
とりあえず重複削除のところで安易にループ処理に飛びついたところを見直すことにしてみます。
3の処理と似たような事をしたらループを使わなくても簡単に重複を削除できますね。
ということでループを使わない重複削除の処理を作ったところ…
作り直した部分の処理負荷は1/300に!!!
ICEでは安易にループを使わない方が良さそうですね。
境界を抽出するところも、行列使ったらループ不要になりそうですがちょっと用意できてないので、今回はここまでということで。
次回は、もう少し実務で使えそうな事例をやっていければと思います。
それでは。
| 固定リンク | コメント (0) | トラックバック (0)
「モーションデザイナー」カテゴリの記事
- この頃 流行りの…(2019.02.28)
- たまには乗らんとね(2019.01.17)
- コミュニケーションを語る!(2018.11.22)
- 12個のアニメーション基本原則とは?(2018.10.11)
- 新人研修を終えて(2018.09.06)
この記事へのコメントは終了しました。
コメント