スポンサーサイト

--年--月--日 --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ペルトマッピングあれこれ その1

2006年09月08日 23:24

プライベートのことで色々あったせいか、ちょっとブログ書く元気がありません。。

google とかから検索で飛んできてくれた人やこんなページでもブックマークしてくれている奇特な人に大変申し訳ないです( ;Д⊂ヽ


ってことで、ブログを閉鎖します!


・・・・っていうのはウソですw


書く元気がないからって何もやってないわけじゃないですよ(・∀・)
あ、けど Closure のことはもうちょっと元気が出た時にでも書きますね。
あれは説明するのも労力が必要なので( ;Д⊂ヽ


今日は今やってることなんかをちょっとまとめるために書きます。


今は PeltMapping っていう処理をやっています。
これは、モデルデータのUVを「アジのヒラキ」みたいに展開(Unfold)する処理です。
3D Studio Max 8 の UV Pelt Mapping 機能ですね。


2000年ぐらいの Siggraph に出てた論文を元に作っています。
・・・っていうけど、原理は恐ろしいほど強引で簡単なんですけどねw

とりあえず、参考になるURLを上げておきます。
http://www.cgl.uwaterloo.ca/~krmoule/talks/pelt/intro.html

ちなみに、Model Pelting のプラグインは Maya のはフリーでありますし、 XSI のも多分あるでしょう。確かめてないけどw

なので、デザイナーさんが使う分にはメインストリームのソフトウェアでサポートされているので1から作る必要はそんなにないわけです。


ならなぜ作るのか?
もちろん自分が作ったツールでUVを気にしないでモデルに対して陰影のテクスチャを張ったりペイントしたりをやりたいからです!
テキストエディターを作ったのと同じ理由ですね(´ω`)



さて、原理はというと、上でも「簡単」で「強引」と書きましたが、物凄い簡単で物凄い強引です。
まず、「アジのヒラキ」を作る場合やらないといけないことはなんでしょうか?

切れ目を入れることですね。

PeltMapping も同じです。
UVを展開する時に展開元となる切れ目のエッジを選択します。

その後何をするかというと、、、
物理演算を行いながら実際に皮を剥ぐようにメッシュを展開していくんですねw
強引過ぎますw 考えた人単純すぎw
けど、理にかなってます。


やり方は、、、
 1:UVの展開を行うために切れ目を作成します。
 2:メッシュの頂点間を結ぶ線(エッジ)を全てばねモデルにします。。
 3:1の切れ目を引っ張ります
 4:後は布シミュレーションを行うようにばねモデルを解決しちゃえばOKです。

こう書くと簡単そうですね~。


実際は結構面倒な処理があります( ;Д⊂ヽ



まずはエッジの生成処理。

maya とかじゃ線を選択して切断コマンドしちゃえば出来ちゃいますが、自力でやる場合案外面倒です。


何が面倒なのか?
エッジでメッシュを切断した場合、当たり前ですけど切断部分の点が出来ます。
これはエッジに沿って切った場合も同様です。


切断後に出来た点をメッシュが崩れないように切断部分のポリゴンを再連結する処理がまず面倒でした。

あるけ は最近頭がなまってるせいか、あまりいい考えが思い浮かばず強引にやることにしました。
まず、切断点の頂点(これはメッシュが保持している既存の頂点になっています)のインデックスを使って、カットするエッジを用意します。
(用意の仕方はとりあえず置いておきます。まだ実装してないので( ;Д⊂ヽ
多分GUIを用意することになるでしょう。2点間の最短エッジを結ぶとかメッシュを調査して自動的にカットする部分を見つけるとか)


次に一筆書きの順番になるように切断する点を整列します。

このとき、往復で考えるところがミソです。
たとえば、
 1->2, 2->3, 3->4
と切断点が指定された場合
 1->2, 2->1, 2->3, 3->2, 3->4, 4->3
と往復でカットするエッジを配列に入れておくわけです。

この例を一筆書きの順番に並べてみると
 1->2, 2->3, 3->4, 4->3, 3->2, 2->1
になります。


こんなの簡単じゃんとか思う人いると思います。
それじゃカットするエッジが十字にクロスしてた場合を考えて見ましょう。

   4
   |
 3-2-5
   |
   1

こんな感じにですね。

この場合、一筆書きで書こうとすると、(CCW でいきます)
 1->2, 2->5, 5->2, 2->4, 4->2, 2->3, 3->2, 2->1
となります。


これを生成するところまでが第一関門。


まぁ、単純に考えて直線の為す角度を利用すればいいわけです。
為す角度っていうと内積。
けど、ただ内積を取るだけじゃ CW 方向なのか CCW 方向なのかわかりません。
そこで、あるけ はエッジに座標系を持たせました。

この座標系、一意に求まらないとダメです。
ここでもちょっと躓きました。
なんでかっていうと、1->2 のベクトルをたとえばZ軸として座標系を作成しようとしても
それは 1->2 のベクトルの周りに無限に存在することになっちゃいます。
これじゃ、使い物になりません。
Z軸だけが固定だけじゃX軸だと思って使ってても、Y軸が反転すればX軸も反転しちゃうので・・・。


それじゃどうするのか?
1->2 ベクトルを使うポリゴンを全て列挙して、そのポリゴンの面法線を加算して単位化して使いました。

こうすれば2つ(1->2 ベクトルと面法線の平均のベクトル)のベクトル(しかも必ず交差する)により座標系を固定できるんです。


後は為す角度を求めるだけです。
求め方を上記の例(クロスさせたやつ)をもとに説明しましょう。
1->2 ベクトル(以降Aベクトル)と 2->5 ベクトル(以降Bベクトル)を例にとって見ますと、
まず内積で余弦が出るので、acos( A・B ) で角度が求まります。
次に A ベクトルの座標系 M のX軸ベクトル(これをxベクトルとします)と B ベクトルで内積を取ります。
内積の方向でどっち周りなのかがわかるわけですね。
これで acos( A・B ) が CW なのか CCW なのかがわかるわけです。


さて、後は単純に角度を調べて、CCW に一番近いエッジを選んでいけばOKです。
・・・ってワケにも実は行きませんw
A ベクトルと B ベクトルの内積の結果と x ベクトルとの内積の符号、場合により x ベクトルの内積の大きさと座標系 M のY軸ベクトル y との内積の符号も使わないと実際の方向は出ないわけです。

たとえば、A・B == A・C となる C ベクトルがあったとします。
そうすると、C != B となるベクトルであった時、必ずどちらかが先に処理されるように求めなければいけません。
X ベクトルとの内積の符号だけみれば回転方向はわかりますが、回転方向が同じで A・B == A・C だった場合、先に処理された方が隣接辺と判定されてしまうでしょう。

そこで、X ベクトルとの内積の大きさと Y ベクトルとの内積の符号も使用します。
実際、A・B == A・C の時だけ判定すればいいのであまり無いかもしれません。
A・B == A・C の場合に X ベクトルとの内積と、Y・B と Y・C の符号を使って為す角度を求めます。
ちなみに、 A・B == A・C かつ X・B == X・C の場合 B == C となるので、この場合はエッジの指定方法またはポリゴン事態がおかしなデータになります。

これで一筆書きのカットするエッジリストが手に入ります。



とりあえず今日はここまで。
また気が向いたら続きを書きますw




blog_rank

スポンサーサイト


コメント

    コメントの投稿

    (コメント編集・削除に必要)
    (管理者にだけ表示を許可する)

    トラックバック

    この記事のトラックバックURL
    http://angra.blog31.fc2.com/tb.php/72-85868e36
    この記事へのトラックバック


    最近の記事


    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。