DirectX Pickサンプルにある一番肝心のコードPick.cpp 719~737行目
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
なるほど!それだとレイが透視変換されてしまうんですね。
透視変換するときにはカメラ空間を四角錐へ変えることを考慮しないといけないという事か
これはアハ体験。
ふむ。逆に透視変換したいような場合はもともと自分で考えていたやり方でよいと。
頭使って考えるとこういう楽しみがあるからいいんですよね