stairtest
今回は階段を作ってみます。

実は昔houdiniで「rampで高さを制御したline上に階段を作成する」otlを
作ろうと試みたのですが、その時はうまいこといきませんでした。
なぜかというと、lineの角度が90度を越えた際に、踊り場を作る必要があったからです。
踊り場って言ってもそんなの簡単じゃないか?
と最初は思ったのですが、これが難しい。
なぜなら、

kaidan1

とあった場合、90度なのか270度か判定しなければならいためです。
270度ならば、あまり問題はありません。
しかし90度であれば踊り場を作るために、lineの角から踊り場の領域を遡って確保しなければなりません。

kaidan2

で見れば簡単そうだが、実際は・・・

kaidan8

この平行部分がなかなか作れない!

僕は当初内積を使えば角度がわかるので、それで判断できると考えていたのですが、
内積の返り値はスカラーの0~180度でしか判定できません。
「無理だ…」
ということで、そのときはlineを階段の中央とみなした作成方法を行いました。
しかしこれは…あまりうまくいきませんでした。

kaidan3

結局このやり方では正方形以外の踊り場が作成できないのです。
必ず四角形の踊り場が来るのであれば、対応はできます。しかし、斜めのコーナーが来た時点でこのやり方は破綻します。

そして1年後、たまたま「外積」を勉強し直す機会がありました。
外積は右回りは正、左回りは負の特性を持ちます。(yの方向に注意!!)
ということは、負のときの内積を360から引けば、0~360の判定が可能になる!!
やった!

Wrangleサンプル
実行させる前にdivideでRemove Shared Edgeと
sort(By Vertex Order)をしてください。
kaidan10

#include <voplib.h>
 
vector  N_A;
vector  N_B;
vector  crossprod;
int     nb1ptnum;
int     nb2ptnum;
float   product;
float   dotprod;
float   trig;
float   deg;
 
if(@ptnum==0){
    nb1ptnum = (npoints(0)-1);
    nb2ptnum = 1;
}else if(@ptnum==(npoints(0)-1)){
    nb1ptnum = @ptnum-1;
    nb2ptnum = 0;
}else{
    nb1ptnum = @ptnum-1;
    nb2ptnum = @ptnum+1;
}
 
N_A=point(@OpInput1,"P",@ptnum)-point(@OpInput1,"P",nb1ptnum);
N_B=point(@OpInput1,"P",@ptnum)-point(@OpInput1,"P",nb2ptnum);
 
crossprod = vop_cross(normalize(N_A), normalize(N_B));
dotprod = vop_dot(normalize(N_A), normalize(N_B));
trig = vop_acos(dotprod);
deg = vop_degrees(trig);
if(crossprod.y > 0){
    f@degree360=360-deg;
}else{
    f@degree360=deg;
}


0~360度が取れることはわかりました。では踊り場はどうやって作ればいいでしょうか?
方法は2種類あります。(あくまで僕のやり方なので導師の人は別の方法でやるかも・・・)

180度以上のコーナー:
1つの頂点からそれぞれの2本ベクトルに垂直な線を取り出す
その垂直な線をノーマライズして内角の1/2からだいたい√2ぐらいの長さでベクトルを出す。(90度の場合)
あとはその3点で三角形を2つ作成してマージすると踊り場が作成されます。

kaidan4

180度以下のコーナー:
(1)
上の方法だと頂点からでる2つのベクトルと隣り合う2つのベクトルとの間に角度によってメッシュの重なり(もしくは隙間)が生じてしまいます。これはよくないので
kaidan5.1

(2)
それぞれ頂点から垂直に出していたベクトルの方向を、頂点から内角の1/2に伸びたベクトルの先に変更します。これで三角形が2つ作られました。
kaidan6
(3)
そしてここにできた隙間を埋めてやります。
1:赤の頂点を紫の頂点に(1つめの三角形)
2:青の頂点を紫の頂点に(2つめの三角形)

kaidan7

(4)
計4つの3角形を作ります。これである程度の(90度以外の)角度に対応することができます。
ただし0~90度のときは、赤と青の根元が重なる可能性があるのでfuseで微調整をします(結局力技)。
kaidan9
問題点としてはUVがきれいにならない可能性があることと、
角度によってはいびつな突起が生じる可能性があることです。

どうだったでしょう。内積と外積。とても便利ですね!

(hipファイルは・・・ネットワークが汚いので整理したらアップします。)

>>一覧にもどる