2011/11/29

ICE : 配列とセットの違いを理解する

ICEを構築していると、いろいろな壁にぶち当たります。
そんな、そびえ立つ大きな壁のひとつとして、配列とセットという概念があります。

配列とセットの違いは、ICEを攻略する上で、非常に重要な概念となるので、覚えておく必要があります。

PointCloud Grid 3x3
Get -> Primitive -> Point Cloud -> Grid
から、3x3のPoint Cloud Gridを作成して、以下のICE Treeを繋ぎます。

上の黄緑の流れは、2012から搭載された、Build Array from Setノードを使用しています。
内部的には、セットから配列へ変換するノードです。
結果、配列で表示されています。


対して、下の黄色の流れは、普通にPointPositionを表示しています。
こちらは、セットです。


それぞれをカスタムICEアトリビュートのself.a、self.bと、二つにデータを格納しています。


Show Valuesのポイント
データを確認したいときは、ノードの線を右クリックして、Show Valuesでのプロパティの設定を開いてOKボタンで確認します。
ですが、今回のポイントは、このプロパティの一番下の文章です。

Labelに#を入れると、IDで置換します。

となっていますので


#:

とLabelに入力したものが、上の図です。
黄緑配列の値は、こんな感じで表示。
[ ] の中の数字が増えていっています。

0[0]:-4, 0, -4
0[1]:-4, 0, 0
0[2]:-4, 0, 4
    .
    .
    .

一方黄色セットの表示は、

0: -4, 0, -4

1:-4, 0, 0
2:-4, 0, 4
    .
    .
    .

と、[ ]が無い状態ですが、一番左の数字が増えていっています。

この違いは、一体なんなのか。

これを理解するには、IDという存在がキーポイントとなります。IDというのは、オブジェクトのポイントなどの頂点番号の事です。

3x3のPoint Cloud Gridは、9個のポイントから成り立っています。その頂点番号は

0, 1, 2, 3, 4, 5, 6, 7, 8
右上のポイントを選択
といったように、0から始まる番号がポイントひとつひとつに割り振られています。

試しに右上のポイントをタグ選択して、Selectを見てみます。

6番が選択されています。丁度、黄色セットの表示では

6:4, 0, -4

となっており、6つ目の要素であること確認出来ます。
ポジションの値からも確認することが出来ますね。

つまり、セットとは、IDというオブジェクトの頂点番号とセットのデータということになります。

一方、配列のほうは、IDが0の場所に、9個のデータが一気に格納されています。

ここが決定的に違うところなのです。

詳しく見ていきましょう。

PointPositionへ接続
配列は挿せず、セットは挿せる
上のツリーから、Set Dataに Self.PointPositionを追加し、そこへ、配列のaというデータと、セットのbというデータが挿せるかどうか、試してみます。

IDを持たない配列aの場合、PointPositionへ接続しようとしても、拒否されてしまいます。
PointPositionは、IDを必要とするICEアトリビュートのようです。

変わって、セットbの場合は、ID情報があるので、素直に接続することが出来ます。


配列にIDを割り振りPointPositionへ接続
配列aのようなデータをPointPositionへ接続するには、IDを割り振るという作業が必要です。

Get Point IDSelect in Array ノードをこのように繋げば、PointPositionへ挿すことが出来ます。

このコンボは、非常に良く使うので、覚えておいて損は無いでしょう。

さらに、詳しく見ていきましょう。

違う大きさのCubeA、B
良くある問題で、このオブジェクトと同じ形状にしたいのになんで接続出来ないんだろう・・・?
ということが、たびたびあるかと思います。

違うオブジェクトからデータを持ってきたときに、接続出来ないことが良くあります。


これも実は、IDの問題なのです。


別のPointPositionのデータが繋がらない
Bの形状を、Aと同じにしたい。と考えた場合、BにICE Treeを作り、誰でも最初はこういう風に挿そうと思うものです。

今まで説明してきたセットのあり方を考えると接続出来るのでは?と不思議に思うのですが、実は、IDというものは、オブジェクトごとに固有に持っているもののようです。

この状態ですと、AのIDを持ったPointPositionのデータを、BのIDのPointPositionへ無理やり持ってきているようなものです。

ですので、考え方として、AのPointPositionを、一度IDを持たない配列データにし、BのIDを割り振り直し、BのPointPositionへ挿すという風にします。

Aのセットを配列にし、BのIDを割り振る
Build Array from Set で、配列データへ変換した後、Get Point ID と Select in Array ノードで、BオブジェクトのIDを割り振るといったことをすれば、挿せるようになります。




このように、配列とセットを理解するだけで、かなり出来ないことが出来るようになるはずです。

実を言う僕も、触り始めて半年くらい良く分かりませんでした・・・。
他人が繋いでいるのをなんとなく見ていて、「ああ、なるほど!こういう風にやればさせるのか!」と思っていたのですが、なんで?というのが、拭いきれませんでした。

完全に理解できたのは、Show Valuesで、Labelに#を入れて見た瞬間でした。

なるほどなぁ。こう違うんだ。
とね。

読んでくれてありがとう。


2011/11/22

Python : シェーダがマテリアルに繋がっているか調べる

シェーダがマテリアルと繋がっているのかいないのかを調べる関数です。

7.5辺りから、Render Tree上でリフレッシュしても繋がっていないものが残るようになりました。
Material.GetAllShadersを使用すると、繋がっていない、ごみシェーダを取得してしまいます。

なので、本当に使われているのか?という判定に使えます。
GetShaderParameterTargetsを使います。
このメソッドは、シェーダのアウトプットに繋がっているパラメータコレクションを返してくれる便利なものです。


from siutils import sisel # Selection
from siutils import log  # LogMessage

# シェーダがマテリアルに繋がっているかを調べる
def IsConnect(oShd):
 # シェーダのアウトプットのパラメータコレクションを取得
 oShdTgt = oShd.GetShaderParameterTargets("")
 # パラメータコレクションの数が0(すなわち繋がっていない)の場合は、False
 if not oShdTgt.Count: return False
 for oTgt in oShdTgt:
  # パラメータの親、つまりシェーダかマテリアルかを調べる
  if oTgt.Parent.Type == "material":
   # マテリアルなら、繋がっている
   return True
  else:
   # マテリアルじゃないなら、再度そのシェーダのアウトプットを再帰的に調べる
   return False or IsConnect(oTgt.Parent)




2011/11/18

Chain Generator

Twitterにて、#ICEドリルが始まりました。
ICEの質問の投稿があって、それをみんなで答えていたので、これはハッシュタグつけて、みんなでやったら面白いんじゃないかと思い、始めてみたのがきっかけです。

このICEドリルの参加に制限はひとつだけです。

行き詰ったり、こういうのどう繋げばいいのかふと思ったり、自分はこういう風に繋いでいるけどほかの人はどう繋ぐんだろう?とか、いろいろな動機があると思いますが、その質問に、#ICEドリルとハッシュタグを付けるだけで、参加出来るものです。

ただ、誰か質問しているのにも関わらず、さらにその上から質問を投げるのは、禁止します。

と前置きはいいとしまして、そのICEドリルから、Chain Generatorが産まれました。

今回は、そのプラグインの紹介です。

ICEで、鎖を簡単に作れます。
動画はこちら。



コンパウンドは、こちらです。
bit.ly/vJA7Wu

コンパウンドをICE Treeにドラッグアンドドロップで使用可能になります。

Chain Generatorプロパティ
動画は、1.0のバージョンのものですが、現在は、1.1になっています。

では、機能の紹介です。

Curve Name
一番上は、curveオブジェクトを入力します。
そこに、Pointが発生します。
Get Dataノードで、カーブオブジェクトの名前を挿すことも出来ます。

Distance
この値は、PointとPointの距離です。
大きければ、離れるし、小さいと密着した鎖が作れます。
大体鎖オブジェクトの大きさを入れればOK。

Accuracy
これは、精度です。
ICEノードには、カーブ上の位置を等間隔にするものが無いので、仮想ポイントを内部で作成しています。
その仮想ポイントをみて、等間隔の距離を抽出するので、小さい値だとカーブ上から離れる場合があります。
大きければ良いですが、その分処理が重くなるので、丁度いい値を探さなくてはなりません。
おかしい挙動をしたら、大きくしてみましょう。

Shape - Shape
シェイプを指定します。
Instans Shapeを挿してお好みのオブジェクトを割り当てられます。

Shape - Align Axis
カーブに沿って整列させるシェイプの向きです。

Shape - Is Chain
オンにすると、交互に90度回転します。
鎖だとオンです。

Up Vector - Up Vector
アップベクター機能のオンオフです。

Up Vector - Up Vector Axis
アップベクターの向きを3軸から選びます。

Roll - Roll Angle
ロールの角度を入力します。
カーブに沿ってぐるぐる回ります。

Twist - Twist Angle
ねじれです。

Twist - Profile
ねじれ具合をFcurveでコントロールします。
横軸は、カーブの始点、終点です。
縦軸は、回転の度合いです。


こういうのは、本当にICEに向いてるなと思いますが、作るのは本当に大変でした。
今、中身を見るのが正直嫌ですw
ホントは、中身の解説をしようかなーと思ったんですけど、余りに膨大すぎるので、やめました・・・。

えへ。すいません( ´థ,_‥థ`)

さて、次は何を作ろうかなー。



Perforce: 複数のワークスペースを更新するバッチ

batを叩けば全部更新。 @echo off set P4PORT=x.x.x.x:xxxx set P4USER=user set P4PASSWD=password echo %P4PORT% echo %P4USER% echo %P4PASSWD% echo %P4PAS...