一日の終わりに少し数学の時間。
ウィンドウサイズの4ポイントを投影する必要があります:
<0,0> <1024,768>
ワールドスペース座標にしたがって、後で地形カリングに使用される四角形の形状を形成します-GluUnprojectなし
テストのみのために、私はマウスの座標を使用します-そしてそれらを世界の座標に投影しようとします
[〜#〜]解決済み[〜#〜]
これを正確に行う方法を段階的に説明します。
で構成されるvector4を構築します
x = mouseposition.x
ウィンドウxの範囲内
y = mouseposition.y
ウィンドウyの範囲内
z = the depth value
(これはglReadPixelで取得できます)
w = 1.0
前に作成した逆行列をベクトルに乗算します
行列の乗算後、結果ベクトルをそのw成分で除算します(透視除算)
POINT mousePos;
GetCursorPos(&mousePos);
ScreenToClient( this->GetWindowHWND(), &mousePos );
CMatrix4x4 matProjection = m_pCamera->getViewMatrix() * m_pCamera->getProjectionMatrix() ;
CMatrix4x4 matInverse = matProjection.inverse();
float in[4];
float winZ = 1.0;
in[0]=(2.0f*((float)(mousePos.x-0)/(this->GetResolution().x-0)))-1.0f,
in[1]=1.0f-(2.0f*((float)(mousePos.y-0)/(this->GetResolution().y-0)));
in[2]=2.0* winZ -1.0;
in[3]=1.0;
CVector4 vIn = CVector4(in[0],in[1],in[2],in[3]);
pos = vIn * matInverse;
pos.w = 1.0 / pos.w;
pos.x *= pos.w;
pos.y *= pos.w;
pos.z *= pos.w;
sprintf(strTitle,"%f %f %f / %f,%f,%f ",m_pCamera->m_vPosition.x,m_pCamera->m_vPosition.y,m_pCamera->m_vPosition.z,pos.x,pos.y,pos.z);
SetWindowText(this->GetWindowHWND(),strTitle);
すべての行列を乗算します。次に、結果を反転します。投影後のポイントは常に-1,1になります。したがって、4つのコーナースクリーンポイントは-1、-1です。 -1,1; 1、-1; 1,1。ただし、z値を選択する必要があります。 OpenGLを使用している場合、zは-1から1の間です。directxの場合、範囲は0から1です。最後にポイントを取得し、マトリックスで変換します。
Gluライブラリにアクセスできる場合は、 gluUnProject (winX、winY、winZ、model、projection、viewport、&objX、&objY、&objZ);を使用します。
winX
とwinY
は、画面の隅にピクセル単位で表示されます。 winZ
は[0,1]の数値で、zNear
とzFar
(クリッピング平面)の間のどこに点を置くかを指定します。 objX-Z
結果を保持します。真ん中の変数は関連する行列です。必要に応じてクエリを実行できます。
ここで提供される回答にいくつかの調整を加える必要がありました。しかし、これが私が最終的に得たコードです(GLMを使用していることに注意してください。乗算順序に影響を与える可能性があります)。 nearResultは近平面上の投影点であり、farResultは遠平面上の投影点です。レイキャストを実行して、マウスが何にカーソルを合わせているかを確認したいので、それらを方向ベクトルに変換します。方向ベクトルは、カメラの位置から発生します。
vec3 getRayFromScreenSpace(const vec2 & pos)
{
mat4 invMat= inverse(m_glData.getPerspective()*m_glData.getView());
vec4 near = vec4((pos.x - Constants::m_halfScreenWidth) / Constants::m_halfScreenWidth, -1*(pos.y - Constants::m_halfScreenHeight) / Constants::m_halfScreenHeight, -1, 1.0);
vec4 far = vec4((pos.x - Constants::m_halfScreenWidth) / Constants::m_halfScreenWidth, -1*(pos.y - Constants::m_halfScreenHeight) / Constants::m_halfScreenHeight, 1, 1.0);
vec4 nearResult = invMat*near;
vec4 farResult = invMat*far;
nearResult /= nearResult.w;
farResult /= farResult.w;
vec3 dir = vec3(farResult - nearResult );
return normalize(dir);
}