チュートリアルやってみた1

Category : CGTips · by 2月 17th, 2020

Creating Procedural Modular Level for Unreal Engine
https://www.udemy.com/course/draft/2503572/

UdemyのHoudiniチュートリアルをコツコツ進めます。

Houdiniでパスを書いただけで自動的に迷路を生成してUnrealEngineに最適な状態のモッシュを作るらしいです。
通路部分の生成の途中まで。角の判定はでき、角が外向きか内向きかをこれから取得しようというところです。

以下、発見した工夫や知らなかったノードやコードをメモしていきます。

通路とは別に、同じ大きさのグリッドを作るのですが、グリッドが常に通路を覆うように設定します。これはよくやる処理ですね。

bboxでバウンディングボックスの大きさ
centroidでセンターの位置を取得

グリッド平面と通路の面の交差を判定して、共通部分だけを残す処理をVEXで書きます。

int inter = 0;
vector P, uvw;

inter = intersect(1, @P - set(0, 0.1, 0), set(0, 0.2, 0), P, uvw);
if (inter == -1)
    removeprim(0, @primnum, 1);

https://www.sidefx.com/ja/docs/houdini17.5/vex/functions/intersect.html
光線とジオメトリの最初の交差を計算
起点から最大距離分までを計算して、光線が何も交差しなかった場合は-1をかえします。

removeprim
https://www.sidefx.com/ja/docs/houdini17.5/vex/functions/removeprim.html
ジオメトリからプリミティブを削除
Primitoveのrun overなのでプリミティブごとに距離を測って、何もなければ削除します。

これも随所に見られる輪郭以外のエッジを消す処理

DividSOPのUnshared Edge
本来、分割するはずのディバイドにエッジ削除があるので忘れがち。

不要な頂点を消すのはFacetSOP
Remove Inline Points
ファセットはポリゴンのクリーンナップ系の機能を多く持つ

上記の2つを組み合わせて使うことが多い

角かどうかを判定する処理
右側の流れでは、天井と床の不要な頂点を消したもの(角以外にポイントがない)を作っているので、これともともとの壁を比較して、ポイントが近くにあるかどうかを見れば良い。

int handle = pcopen(1, "P", @P, 0.1, 1);
if(pcnumfound(handle) > 0)
    i@corner =1;

ポイントクラウドファイルのハンドル
ここでは半径0.1のポイントを1つだけ取得、あった場合はポイントナンバーが入るので、0ではなくなる

コーナーを含むプリミティブだけを取り出す
コーナーを含まないプリミティブだけにするのは簡単(コーナーのポイントを消せば良い)だが、コーナーを含むプリミティブにするのが案外めんどくさい。
もっといい方法がありそうな気がするんだけど。

int prim_pts[] = primpoints(0, @primnum);
int corner = 0;

for(int i=0; i<len(prim_pts); i++)
    if(corner == 0)
        corner = point(0, "corner", prim_pts[i]);

if(corner == 0)
    removeprim(0, @primnum, 1);

コーナーを含むプリミティブ以外を消す
run overがprimitiveなので、プリミティブごとにprim_pts[] という配列が作られて、プリミティブのポイントリストは入る

primpoints
https://www.sidefx.com/ja/docs/houdini17.5/vex/functions/primpoints.html
プリミティブ上のポイントのリスト

for(int i=0; i<len(prim_pts); i++)
    if(corner == 0
        corner = point(0, "corner", prim_pts[i]);

ちょっと詰まったのが、”corner”以外のcornerはプリミティブが持つ別のチャンネルということ。あんまりよろしくない名前の付け方だと思う。

この値には最初は0を代入しているが、もし0だったらポイントリストの”corner”が順番に代入される。つまりポイントリストに1以外の値があると、プリミティブのcornerも0ではなくなる。
その後、プリミティブのcornerが0のものは消す。


SHARE :