スポンサーサイト

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

これで "2次元と3次元の世界を行き来" できるぞ!

【リンク】 ◆解説系TOP◆

今日は、2次元と3次元の座標の相互変換についてのお話です。

別の次元(2←―→3)へ座標を変換する方法を紹介します。
別に、自分がアニメの世界に入り込んだり、アニメのキャラクターが現実の世界に出てくる、
という様な意味ではありませぬ。


では、まずコレをご覧下さい。

【参考画像】
メタセコイア

メタセコイアです。

メタセコイアでは、普通にカーソルでモデルの表面を選択する事が出来るんですが、
(写ってないですが、黄色くなっている部分がカーソルで指されています

よく考えたら、謎ですね。
x軸とy軸しかないウィンドウ(2次元の世界)から、
x、y、z軸の3次元の世界を選択できています。

一体どうやっているのか?
今日は、この謎の部分を解説します。
(まぁ、先に結論を言ってしまうと、行列で2次元と3次元の座標を変換してます。

では、下記の様な順で書いていこうかな、と。
-----------------------------------------
【1】3次元→2次元への変換
【2】2次元→3次元への変換

-----------------------------------------



まず【1】について。
普段 意識しないかもしれませんが、3Dモデルをウィンドウに表示している時点で、
3次元→2次元の、次元を超える変換が行われてます。

・・・で、
そもそも、DirectXでは どのような過程を経て3Dモデルが描画されるのか。
実は、下記の様なややこしそうな計算を経て描画されてます。

ウィンドウ上の座標 = モデルの座標×ワールド変換行列×ビュー行列×射影行列×ビューポート行列


ワールド変換行列 ・・・ 拡大、回転、オフセットなどで、3次元世界の座標系に変換する行列です。
ビュー行列 ・・・ DirectXではカメラを設定します。そのカメラを基準とした座標系に変換する行列です。
射影行列 ・・・ 視錐台を立方体に変換する行列。(カメラ近くの物体は大きく、遠くの物体は小さく見えるように変換。遠近感が生まれる。)
ビューポート行列 ・・・ 射影座標系から、スクリーン座標系に変換する行列。(これでウィンドウ上の座標になる!)


図で説明すると、こんな感じ。
【参考画像】
3次元→2次元


で、ワールド変換行列は何をしたいかによって色々と変わる(回転、スケール変換など)
のですが、
------------------------------------------
・ビュー行列
・射影行列
・ビューポート行列

------------------------------------------
これは求め方が決まっています。

とりあえず、 ビュー行列射影行列は、DirectXに自動的に生成してくれる関数があるので、
それを使えば問題ないでしょう。


ビュー行列の生成
D3DXVECTOR3 vEyePt( -0.0f, 0.0f,-3.0f);    //カメラの位置
D3DXVECTOR3 vLookatPt( -0.0f, 0.0f, 0.0f ); //カメラの注視点の位置
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); //カメラの上方向の位置
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
Device->SetTransform( D3DTS_VIEW, &matView );


射影行列の生成
D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian(90.0f), (float)640/480, 1.0f, 100.0f );
Device->SetTransform( D3DTS_PROJECTION, &matProj );

※関数の詳細や、行列の要素の詳細はこちらに書いてあります↓
【参考URL】D3DXMatrixLookAtLH 関数
【参考URL】D3DXMatrixPerspectiveFovLH 関数

そして、最後のビューポート行列の要素はこのようになってます。

【参考画像】
ViewPort_mat.jpg

また、自分のウィンドウは640×480にしているので、
その場合の ビューポート行列はこうなります。
320     0    0    0
 0 -240 0 0
 0 0 1 0
320 240 0 1


では、全ての行列の説明をし終わったので、
実際に 3次元→2次元の変換が出来ているか調べてみましょう。

※ワールド変換行列は、単位行列、
ビュー行列と射影行列は、ヘルパー関数が生成したものを利用します。


ひとまず、左上の頂点が(-2 2 0)のポリゴンを表示してみたところ、
ウィンドウの座標上では(160 80)になりました。

【参考画像】
実験

計算があっていれば、

(-2 2 0)××ビュー×射影×ポート = (160 80)
となる筈です。
※長すぎるので、各 行列名は省略してます。

では、実際に計算して見ます。

【参考画像】
3次元→2次元2


見事、 結果が一致しました。
3次元から2次元へ変換する際は、こんなややこしい事をやっていた訳ですね。


では次に【2】について。
(2次元→3次元の変換)

これは、ちょっと行列に関する知識が必要となります。

-----------------------------------------------------------------------
・行列A × 逆行列A = 単位行列
・行列A × 単位行列 × 単位行列 ・・・ = 行列A

-----------------------------------------------------------------------
行列に逆行列をかけると単位行列になる、という性質と、
行列と掛け算すると単位行列になるような行列が逆行列、とも言える)

何回 行列に単位行列をかけても、行列の要素は変化しないという性質です。

この性質を用いれば、先ほどの式を下記の様に変形できます。
3次元座標×ワ×ビュー×射影×ポート = 2次元座標
3次元座標×ワ×ビュー×射影×ポート×逆ポート = 2次元座標×逆ポート
3次元座標×ワ×ビュー×射影×単位行列 = 2次元座標×逆ポート
3次元座標×ワ×ビュー×射影 = 2次元座標×逆ポート
3次元座標×ワ×ビュー×射影×逆射影行列 = 2次元座標×逆ポート×逆射影行列
3次元座標×ワ×ビュー×単位行列 = 2次元座標×逆ポート×逆射影行列
3次元座標×ワ×ビュー = 2次元座標×逆ポート×逆射影行列
3次元座標×ワ×ビュー×逆ビュー行列 = 2次元座標×逆ポート×逆射影行列×逆ビュー行列
3次元座標×ワ×単位行列 = 2次元座標×逆ポート×逆射影行列×逆ビュー行列

3次元座標×ワ = 2次元座標×逆ポート×逆射影行列×逆ビュー行列

※ややこしく見えますが、逆行列をどんどん右側からかけてるだけです。


で、最後の式を見てください。
この式を使えば、下記の様にして
(160 80)×逆ポート×逆射影行列×逆ビュー行列 = (-2 2)

2次元から3次元上の座標へ戻せます。
※但し、z座標は分かりません。 2次元へ変換した際にz座標の存在が消えてしまうからです。
(不定積分みたいな感じですね)

つまり、xとyは分かるが、奥行きが不明という状態。


しかし、メタセコイアでは、zが不明でも 3次元上の物体を指すことが出来ます。
これは、何故か?

実は、レーザーのような感じで当たり判定を行ってます。
z座標が分からなくても、
(-2 2 0)
(-2 2 1)
(-2 2 2)
(-2 2 3)
(-2 2 4)

みたいに、 z方面へずっと伸びて行くレーザーだと考えれば、
3次元上にある物体に当たる可能性があるわけです。

この当たり判定に関してはまた次回!
ではでは(`・ω・´)ノシ
スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント

No title

わかりやすうございます。
悲しいことにこんな基礎的なことも知らずに半年間ワケもわからずOpenGLプログラムをいじってました。でもおかげであと二年はその基礎を知った上で研究できます。ポジティブポジティブ

話が変わりますが私と同じ研究室だった人でなりふりかまわずプランナーとしてゲーム業界に就職した人に、ゲーム業界を目指すなら知っておくべきだと言う就職情報サイトを教えていただきました。既にご存知かもしれませんが参考までに。http://www.gamejob.jp/recruit/talent/list.htm?ty=fo

というかconioさんを彼に直接売り込んであげればよかったかなー。連絡先は聞いて無いので会うチャンスはもう卒業式しかありませんがもし会えたら一応聞いてみます。いくらコネがあってもプログラマーとして就職したいなら提出作品は必須だそうなので期待はしないでください。

No title

自分自身も、以前まで
「とりあえずライブラリが用意したヘルパー関数を呼び出せば、なんか描画される」と言う風に、
基礎を理解していない状態でプログラムを組んでましたe-260

何事も、理屈を根底から知ることが重要ですよねv-290
あと、 「これはどういう計算が行われてるんだろう?」みたいな、
仕組み・原理を知ろうとする習慣もつけないといけないかなーとか思ってます。


サイトの紹介有り難うございます!
全然 知りませんでした。e-447
(”ゲーム業界就職マニュアル”などの他サイトなら見たことはあったのですけども。)
 【参考URL】http://www.gamejob-hunting.com/


おぉプランナーとして就職した方がいらっしゃるのですか!
(プランナーは総合的な能力が必要で就職は難しいと聞いた事があるので、驚きました。)
そして、わざわざ有り難うございます(_ _)
しかし、紹介があろうとも最終的に見られるのは個人の能力だと思うので、
少しでも能力を磨いておこうと思います。
(あと、"能力が認められるような 提出できる何か"も制作しないといけないですね。)

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます
コメントの投稿
管理者にだけ表示を許可する



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