Debris Sourceみたいな処理
やり方の一つとしてメモ。insideの外周からPOPをエミットさせる感じ。
ライン化してから処理しているが、精度を上げたり面からエミットしたい場合はvol.6の方法を応用して混ぜたり、ライン化せずinsideに大量にScatterして判定するのが良いと思う。
全体
ラインの作成
動いていないハイポリのエミットさせたい部分のinsideを取り出す。
for-each named primitive内でライン化処理をする
「Convert Line」でメッシュをライン上に変換。
元形状からGroup - Unshared Edgeで外周のエッジをグループにする。
外周グループと元アトリビュートをラインになっているものに転送し、
グループのみを残す。
アトリビュートの整理
不要なアトリビュート等を整理したり、nameをPointにPromoteしたりする。
キャッシュを取って、「Add」でポイント化する。Resampleを挟んでポイント数を増やしてもいいと思う。
エミッター処理
動かす
「Transform Pieces」で動かす。何度も出てきているが、
name
さえ一致すれば動くのでnameを維持し、
動かされる方は必ず時間依存しないキャッシュを作ると処理が遅くなりづらい。
Trailでvを再計算しておく。
速度で間引く
後でエミッター用に間引くために速度の遅い(動いていない)ものをグループに入れる。
vector vel = point(0, "v", @ptnum); if(length(vel) < ch("threshold")) { i@group_move=1; }
近接の名前で間引く
一定の距離内のポイントが自分と同じname
かどうかとrest
から離れた距離で判定し、グループに入れる。
int npts[] = nearpoints(geoself(), @P, ch("maxDist"), ch("maxPt")); int npt = 0; string currentName = point(geoself(), "name", @ptnum); vector currentPos = point(geoself(), "rest", @ptnum); foreach(npt; npts) { string findName = point(geoself(), "name", npt); vector findPos = point(geoself(), "P", npt); float dist = distance(currentPos, findPos); if(currentName != findName && dist < ch("dist")) { i@checkCnt += 1; } } if(@checkCnt >= 1) { i@group_checkGp = 1; }
グループ作成
↑2つで作ったグループから、速度が早く、近接に違うname
のものがいて、rest
位置から一定の距離離れていないものでグループを作る。
Wrangleでできるグループが逆なので文字にするとややこしい。ざっくりいうと速く動いていて離れたピースのグループがほしい。
ageの作成
「SOP Solver」で、↑のグループに入ったもののみ毎フレームageにTimeIncを足す。
分離した瞬間だけエミットさせたいので、「Attribute Remap」でageを極端にRemapして、ageの低いときだけCdを1,1,1にする。
その後、Cdにランダムを足し、vにもランダム化をする。
多すぎるのでランダムにポイントを間引き、さらにCdの閾値でポイントを削除してエミッターとする。
POP
特殊なことはしていない。ハイポリを動かしたものをコリジョンに使用している。
最後にマテリアルや場合によってはCopy to Pointsで軽い形状をコピーして終了。
レンダリング精度が低いので見えづらいが結構な量を出している。