2019-10-20
■ [Houdini]OBBの一番長い軸を取得する方法

https://www.sidefx.com/forum/topic/31983/?page=1#post-149134
- boundノードで0BBが作れる
- バンディングボックスのxyz軸のなかで一番長いものを残す
長軸で分割するには、下記wrangleで長軸を取り出してresamleしてvoronoi
vector p0 = point(1,"P",0);
vector p1 = point(1,"P",1);
vector p2 = point(1,"P",2);
vector p3 = point(1,"P",3);
vector np0,np1;
if( length(p0-p1) > length(p1-p2)){
np0 = (p0+p3)*0.5;
np1 = (p1+p2)*0.5;
}else{
np0 = (p0+p1)*0.5;
np1 = (p2+p3)*0.5;
}
addpoint(0,np0);
addpoint(0,np1);
int prim = addprim(geoself(), "polyline");
addvertex(geoself(), prim, 0);
addvertex(geoself(), prim, 1);
■ [Houdini] 直線を分割している不要なエッジの削除

https://gamecgben.blogspot.com/2018/02/houdini.html
FacetのRemove Inline Points、distanceで調整
2019-07-31
2019-03-10
■ [Unity][Houdini]新居の間取りVR

新居の間取りを図面からモデリングしてVRで確認。壁や家具の配置も簡単に変えられて、トイレやロフトなど図面だけでは広さが実感しにくい所もわかりやすく体感できるので、とても役に立った
スイッチの位置や家事の動線も部屋の中を実際に歩きながら確認できるし、家具や壁紙の色を変えたらどんな雰囲気なるのかもすぐ見れる。部屋の実際の広さは図面の数字だけでは実感しづらいので、こういった用途にVRはほんと最適だと思った
新居の間取りをVRで確認しつつ決めて、今週末の引っ越しのために現地を見に行ったら、ちょうどVRで見たものと同じものがそのまま出来上がっててちょっと不思議な感覚。2Dの図面や平面のCGではわからない部屋のスケール感や光源の具合までちゃんと確認できるので、ほんとVR向きな案件だなぁ、と。
https://twitter.com/Nao_u_/status/1104573498066853888
家のモデリングにはHoudiniを使用。図面に変更があった時にも、大元の枠組みだけ変えれば簡単に修正できるので、プロシージャルモデリングの便利さを実感。
外構工事の検討もUnityでレイアウトしてVRで確認してた。Unityなら簡単に複数パターンの配置を切り替えながら試せて、HMDを通してみると2DのCGで見るのとけっこう印象が違ってたり、塀の高さを変えたら家の中がどう見えるかの違いなども検討できたりなど、ここでもVRは有用だった
2019-02-02
■ [Houdini]連続したnullをObject Mergeで参照する方法

Object Merge SOPのオブジェクト名にはワイルドカードが使える
TransformをInto This Objectにすると、そのオブジェクトのtransformを反映した座標を取ってこれる
これでnullにnormalを追加すれば、nullを編集することで回転情報のattributeが付いた連番の点が定義できるので、道路の傾きを自由に設定できるような仕組みが作れるはず。
点の増減はpythonでスクリプトを書く必要がある。
■ [Houdini]point列をカーブに変換する方法

https://www.sidefx.com/forum/topic/42371/
https://forums.odforce.net/topic/29278-make-curve-in-vex/
addのあとFit SOPでカーブにできる
FItはinterpolateでscopeをbreakpointにしないと必要以上に補間される
2018-05-03
■ [Houdini]プリミティブ端のエッジを除去して中のラインだけ残す

convertLineを参考に。
int n[] = neighbours(1, @ptnum);
foreach(int pt; n){
int e0 = inpointgroup(1, "edge", @ptnum);
int e1 = inpointgroup(1, "edge", pt);
if( (e0==0 || e1==0) && pt<@ptnum){
int pr = addprim(geoself(), "polyline");
addvertex(geoself(), pr, @ptnum);
addvertex(geoself(), pr, pt);
}
}
追記:上記だとまずいパターンがあった。単純なvoronoiであれば問題ないが、複数の分割が重なって、エッジの中央に他のポリゴンの点があるなど、共有されない頂点で割られている時にうまく動かない
そういう形状の時は、いったん綺麗な形のポリゴンになるように前処理してやる必要がある
- scatter→voronoifractureだと裏面ポリゴンが生まれるケースが多いので、deleteで裏面を削除してから作業開始
- エッジが共有されていない時には、groupのunshared Edgesがうまく動かないので、fuseで連結した後にcleanで重複したラインやポリゴンを削除してから実行する必要がある
追記2:さらにまずいパターンを発見。エッジが共有されていない分割だと、Group SOPのエッジ検出がポリゴンの内側にエッジがあるとみなしてしまっておかしくなる
対策として、ConvertLineしたラインの向きベクトルを微小にしたものから計算した、左右斜め前両方のポジションでレイキャストしてどちらかが抜けてたら弾く、という処理にしてみた。
float delta = 0.01;
int pn0 = primpoint(0,@primnum,0);
int pn1 = primpoint(0,@primnum,1);
vector p0 = point(0,"P",pn0);
vector p1 = point(0,"P",pn1);
vector dirVec = normalize(p1-p0) * delta;
vector crossVec = dirVec;
crossVec.x = dirVec.z;
crossVec.z = dirVec.x;
vector chkPos = p0;
chkPos.y = delta;
vector chkDir = {0,-1,0};
vector cp0 = chkPos+(dirVec+crossVec);
vector cp1 = chkPos+(dirVec-crossVec);
vector retPos;
float retU, retV;
int ck_l = intersect(1, cp0, chkDir, retPos, retU, retV);
int ck_r = intersect(1, cp1, chkDir, retPos, retU, retV);
if( ck_l == -1 || ck_r == -1){
removeprim(geoself(), @primnum, 0);
}
余りに鋭角なポリゴンだと検出点に引っかからない可能性はあるが、それ以外はたぶんこれでほぼどんな形状になっても大丈夫?
■ [Houdini]polyExpand2Dで失敗するケースへの対策

上記で作ったLineをpolyExpand2Dでポリゴン化しようとすると、重複したラインがある為にそのままでは失敗する。
intersectionStichで交点で分割することで、長いポリゴンの辺になっていて、間に点のある重複したラインを分割できる
実用的な複雑な形状だと、intersectionStichしても失敗するケースがある。
その時は、intersectionStich → fuse → intersectionStich とつなぐことで、polyExpand2Dが成功するようになる
これで、ブロック内を任意のポリゴンで分割したときに、間にできる道をpolyExpand2Dで作ることができるようになる…
2019/07/15追記
fuse->intersectionStich->fuse で中点を消すパターン、cleanで綺麗になるケースもありそう。要検証
外周のエッジのみ消す方法は、traianglete2d(凸型限定)->clean->groupでエッジ抽出
したものを、groupTransfarでプリミティブに転送(このとき、include only Elements Entirely.... をONしないと余分に転送される)してblastすれば消える
2019/10/20追記
外周をGroup SOPのUnshard Edgeでエッジグループにしておいて、Primitive SOPのCloseUをOpenにしてラインに変換したあとに外周グループのみをBlastで消せる
2019/10/21追記
これでいける。
Voronoi結果をFuse→GroupのUnshared Edgeでエッジのグループ生成→ConvertLineでライン化したあとにGroupTransferでエッジグループを転送(このとき、グループが残ってるのでGroup Name Confrict時の処理をOverwriteにする必要がある)→GroupTransferでEdgeグループをPrimitiveに転送して、Balstで外周だけ消す
2018-05-02
■ [Houdini]プリミティブ内の最長ラインを検索

先端になるpoint配列を生成してインデクスをbasePtNumのattributeに詰めて、findshortestpathのStart PointsとEnd Pointsを、
`point("../pointwrangle3/",detail("../foreach_count1/","iteration",0),"basePtNum",0)`
みたいな形でインデクスを二重ループで取り出した。
findshortestpathのStart PointsとEnd Pointsは文字列なので `` で括る必要があったが、よく見たら Output Pathsに「Fron any start ton any end」って項目があったので、もしかして頂点番号リストを文字列で渡せば二重ループはいらない?要検証。
元ネタ:
https://twitter.com/veltman/status/973570650429206528
https://bl.ocks.org/veltman/403f95aee728d4a043b142c52c113f82
2017-10-22
■ [Houdini]OSM+Houdini

houdini game dev toolのopen street mapでニューヨークを取り込んでFBX出力したものを、UnityでGoogle Mapの衛星画像と合わせてみた。OSMの道路データも加工できると面白そうなんだけど、そっちは簡単にはいかなそう
Yoshiaki Higa @YoshiakiHiga 10月21日
道路はラインポリゴンで読み込まれるのできれいに作ろうとしたら難しそうですね。自分も色々やってますがなかなか上手くいってないです。地図画像のスクショとって画像からジオメトリ生成するのがきれいにできそうです。(多分)
いただいたアドバイスを元に、地図の画像から道路の色を抜き出してポリゴン化してみた。
画像解像度より細かくしたGridにUVを割り当てて画像を転写して、Wrangleで色の白いところだけを残して頂点を削り、fuseしてから、Groupで端のエッジをグループ化。Groupでエッジを残す方法は以下の通り。
この後は、dissplveで端のエッジグループ以外を削除。ここでfuseしてないといるエッジまで消える?この辺トラブってた。
最後にresampleで適当に削ってるけど、ここももっといいやり方ありそう
2017-08-20
■ [Houdini]剛体破壊をテクスチャに焼いてUnityに持っていく(5)

頂点位置だけでなく法線も出力してみたら、法線が共有できなくなるので頂点数が数倍に膨れ上がり、2048頂点を超えたあたりでUVの精度不足かポリゴンが壊れるようになったり、レンダリング時に変なピクセルが出たりと問題がいろいろ発生。まだ一筋縄ではいかなそうだけど今回はここで時間切れ…
頂点とテクスチャが一対一対応している前提ならSV_VertexIDで頂点番号からUVを計算したいところだけど、HoudiniからUnityに出す間のどこかで頂点順が変わっているのかうまくいかず。あと法線も2成分だけ出して残りは外積で求められるなら、Posのαに圧縮して入れられそう
2017-08-19
■ [Houdini]剛体破壊をテクスチャに焼いてUnityに持っていく(4)

Houdiniの頂点テクスチャアニメ、標準機能は使わず自前で位置情報をf16のテクスチャに出力してみた。ひとまずベタに座標のみ出してみると今回は位置のずれは発生せず。テクスチャが位置情報だけで1600頂点×190フレームで2.3MBもあるので、実用的に使うなら剛体化は必須かも…。
Houdiniからの頂点テクスチャ出力、標準のvertex_animation_textureから必要な部分を切りしてみたら、テクスチャの生成処理が「ドット絵のようなグリッドモデルを作ってカメラで撮影する」という予想外の実装になってた。テクスチャを出す方法ってこれしかないのかな?
UnlimitedEffectWorks @ijiVFX さん
pointにCdのアトリビュートが設定されたグリッド上のメッシュならこんな感じでPythonのPILを使って吐き出せます
2017-08-17
■ [Houdini]剛体破壊をテクスチャに焼いてUnityに持っていく(3)

頂点カラーに焼かれていた回転中心をuv3に持っていけないかとデフォルトのvexを書き換えたりして試したけど、モデルが壊れるだけでうまくいかず。
出力部分と同等のものをゼロから作ろうとしてみてるけど、テクスチャの出力がグリッドの板ポリに頂点カラーを割り当てたものをカメラで撮影して作ってるっぽい。
ライトの設定とか、exrを出力してもUnityで読めないとかわからない点が多くて困ってるが、一通りこの辺が動くようにできれば理解は深まりそう。
調査メモ:
テクスチャを出すために、今のフレームの頂点位置を頂点カラーに焼いた横長のグリッドを作って、それをBlockBegin-endでマージしながら合成した板を作り、その板をレンダリングしている
レンダリング時にはcameraと同階層にMaterial Networkが置かれていて、その中にMaterialBuilderでConstantのシェーダーが置かれている。コメントには"Created from Gallery Entry: Constant. Mantra Constant Shader"と書かれているので、なにかコンスタントなシェーダーを作る方法があるのかもしれない。
描画するTEXTURE_MESH のGeometryに../matnet1/constant のシェーダーが割り当てられていた。
Houdiniでの任意のテクスチャの出力方法
シェーダーをGetmetryに割り当てる方法
- Material Networkを任意の場所に作れる。今回は、out/objnet1の下に作る。
- Material Palletを開いて、out/objnet1/matnet1 に Constantのシェーダーをコピーすれば、matnet1にConstantのシェーダーが増やせる。
- GeometryのRenderタブのMaterialから作成したシェーダーを割り当てることで、該当Geometryに任意のシェーダーを設定することができる。
Render Viewから任意のカメラを設定することで、レンダリング結果を確認できる。
カメラの設定と出力解像度
- ViewタブのResolution のXYで、出力テクスチャの解像度が決まる。レンダーターゲットの縦横比もこの時点で決まる。
- ProjectionをOrthographicにして、Ortho Widthを設定することで、横幅が決まる。縦の長さは出力テクスチャの解像度に依存
- なので、Ortho WidthはResolutionの横幅と一致させるようにする
テクスチャの出力
- outにMantraノードを作って、Cameraに適切なカメラを設定する
- "Render to Disk"のボタンでOutput Pictureにファイルを描きだす。
- Output Deviceでテクスチャフォーマットを決める
- OutputタブのPixel Filter は"minmax max"になっていた。内容は要確認…
- Quantization は 32bit float になってた
たまにUnityで読めない.exrができちゃうんだけど、何をミスってるんだろう…
とりあえずexrのテクスチャが吐けたのでノード構成をメモ
- 基本はvertex_animation_texture_bataのrigid_objを改変したもの。
- pointwrangleで頂点数分の横長のポイント列を生成して、copyPointsでgridを並べて横長のグリッドに変換し、block_begin-endでtimeshiftしながら時系列にループさせて縦に並べる
- block_metaでblock_beginのループ回数を取得できるらしい。
- wrangleで1番目につないだノード(左端は0番目)の頂点数は、[npoints(1)]で取得できる
- 今回は、wrangleに ch("vert_count") と書いて、右側のボタンを押すとwrangleのパラメータを追加できる。そのパラメータにnpoints(1)を設定して、頂点数を取得していた。
- テクスチャの幅は、cameraのviewのResolutuion.xとOrthoWidthには npoints("../geo1/object_merge1") を設定して、Resolution.yには bbox("../geo1", D_YSIZE) を設定
モデルの出力側
- unpackして頂点を展開してから、pointWrangleでuv2を生成して、vertexにpromoteする
2017-08-16
2017-08-15
■ [Houdini]剛体破壊をテクスチャに焼いてUnityに持っていく

基本的には下記リンクの通りで動くようになるが、手順が多くてHoudiniから出しなおすたびにうまく動かなくなって原因を調べる、みたいな状態で無駄に時間がかかった。
またハマりそうな点をいくつかメモ。
- BBOX MAX と MINは、テクスチャの再出力後になぜか更新されない時がある。そのときは、/outを抜けてもう一度入りなおすと最新の値になる?
- BBOX MAXが間違った値になっていると、回転の中心がずれておかしな位置に出てしまうので、そのような挙動になったらBBOXを疑うように。
- レンダリングモードをLinearに切り替えないと、posはセンターがずれるし、rotは微妙に向きが変になる。新しくプロジェクトを作り直した時には、こちらも忘れないように。
2017-02-19
■ [Houdini]オプティカルフローテスト スロー煙

Houdiniで8フレームおきにレンダリングした煙をオプティカルフローで補間して、スロー再生。
前回から少しシェーダーを修正。前回は現フレームと次フレームそれぞれで別々にオプティカルフローで流したものを補完していたが、今回は現フレームと次フレームのオプティカルフローを補完して、同じ方向にそれぞれのフレームをゆがめた後でフレーム補完している。
オプティカルフロー生成時のパラメータは前回と同じなので、差分が大きすぎてクランプされて変になってる箇所がある。速度ベクトルの補正係数は絵によって調整が必要か。
こういう流体的な絵であれば、ちゃんと調整すれば長いフレーム補間も十分機能しそう。