ようやくわかった

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

ようやくわかった

投稿記事 by GRAM » 14年前

3D空間にある物体をマウスで捕まえる(ピッキングする)方法を示した

DirectX Pickサンプルにある一番肝心のコードPick.cpp 719~737行目

CODE:

        D3DXVECTOR3 v;
        v.x = ( ( ( 2.0f * ptCursor.x ) / pd3dsdBackBuffer->Width ) - 1 ) / pmatProj->_11;
        v.y = -( ( ( 2.0f * ptCursor.y ) / pd3dsdBackBuffer->Height ) - 1 ) / pmatProj->_22;
        v.z = 1.0f;

        // Get the inverse view matrix
        const D3DXMATRIX matView = *g_Camera.GetViewMatrix();
        const D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix();
        D3DXMATRIX mWorldView = matWorld * matView;
        D3DXMATRIX m;
        D3DXMatrixInverse( &m, NULL, &mWorldView );

        // Transform the screen space Pick ray into 3D space
        vPickRayDir.x = v.x * m._11 + v.y * m._21 + v.z * m._31;
        vPickRayDir.y = v.x * m._12 + v.y * m._22 + v.z * m._32;
        vPickRayDir.z = v.x * m._13 + v.y * m._23 + v.z * m._33;
        vPickRayOrig.x = m._41;
        vPickRayOrig.y = m._42;
        vPickRayOrig.z = m._43;
の意味がようやくわかりました…。まあ別に読み飛ばしてもいつかわかるだろうと思っていたのですが、
「スクリーンの座標をもとの3D空間に戻すのに逆行列を使うのはいいとして、何でカメラの中心(しかも距離0)からレイを出すんだ?
vPickRayDir.x = v.x * m._11 + v.y * m._21 + v.z * m._31;
vPickRayDir.y = v.x * m._12 + v.y * m._22 + v.z * m._32;
vPickRayDir.z = v.x * m._13 + v.y * m._23 + v.z * m._33;
vPickRayOrig.x = m._41;
vPickRayOrig.y = m._42;
vPickRayOrig.z = m._43;
の部分...カメラ空間のマウスポインタのあるx、yの座標からz方向に向かってz軸に平行にレイを出せばいいじゃないか…」と思い違いをしていましたw
今日寝て起きたら電撃的に閃いたw

なるほど!それだとレイが透視変換されてしまうんですね。
透視変換するときにはカメラ空間を四角錐へ変えることを考慮しないといけないという事か
これはアハ体験。
ふむ。逆に透視変換したいような場合はもともと自分で考えていたやり方でよいと。
頭使って考えるとこういう楽しみがあるからいいんですよね
最後に編集したユーザー GRAM on 2010年12月24日(金) 11:19 [ 編集 1 回目 ]

コメントはまだありません。