1

レイピッキングで私を助けてください

float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(35.0f), aspect, 0.1f, 1000.0f);

GLKMatrix4 modelViewMatrix = _mainmodelViewMatrix;


    // some transformations

_mainmodelViewMatrix = modelViewMatrix;

_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);

_modelViewProjectionMatrixと_normalMatrixがシェーダーに配置されます

glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

とタッチエンドで

GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
                                             (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1)   ,  //1 - 2 * position.y / self.view.bounds.size.height,
                                               -1,
                                               1);
GLKMatrix4 inversedMatrix = GLKMatrix4Invert(_modelViewProjectionMatrix, nil);


GLKVector4 near_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

どうすれば遠いポイントを取得できますか?そして、私のnear_pointは正しいかどうか?

ありがとう!

4

2 に答える 2

2

あなたが持っているように見えます

GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
   (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1) ,
   -1, 1);

(phew)近点の正規化されたデバイス座標を計算します。

遠点を取得するには、-1z座標を1:に交換するだけです。

GLKVector4 normalisedFarVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
   (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1) ,
   1, 1);

そして、それに同じ逆変換を適用します。それでうまくいくはずです。

背景:通常の状況では、フラグメントをピクセルに変換するためにGLが受け取る最終的な座標は、正規化されたデバイス座標と呼ばれるものです。これらは、角が(-1、-1、-1_および(1,1,1)にある立方体の中にあります。したがって、画面の中心は(0,0、z)であり、左上の角は(-1)です。 、1、z)など。座標は、近い平面にある点のaz座標が1になり、遠い平面にある点のaz座標が-1になるように変換されます。これらは次の数値です。オンにしている場合は、深度テストに使用されます。

したがって、ご想像のとおり、画面の位置を3D空間内のポイントに戻す場合、実際にはいくつかのポイントから選択できます。実際には、近い平面から遠い平面に伸びる線です。正規化されたデバイス座標では、これはz=-1からz=1まで伸びる線です。したがって、プロセスは次のようになります。

  • x座標とy座標を正規化されたデバイス座標x'とy'に変換します
  • z'=1およびz'=-1のそれぞれについて。
    • 座標を正規化されたデバイス座標に変換します(式についてはここを参照してください)
    • 射影行列の逆行列を適用します
    • モデル/ビューマトリックスの逆行列を適用します(オブジェクトごとの変換前のように)

結果は、3D空間でのラインの2つの座標です。

于 2012-04-05T19:28:51.610 に答える
1

near_pointからfar_pointまで線を引くことができます。

  GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
                                                 (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1),  
                                                   -1,
                                                   1);

    GLKMatrix4 inversedMatrix = GLKMatrix4Invert(_modelViewProjectionMatrix, nil);

    GLKVector4 near_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

    near_point.v[3] = 1.0/near_point.v[3];
    near_point = GLKVector4Make(near_point.v[0]*near_point.v[3], near_point.v[1]*near_point.v[3], near_point.v[2]*near_point.v[3], 1);

    normalisedVector.z = 1.0;
    GLKVector4 far_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

    far_point.v[3] = 1.0/far_point.v[3];
    far_point = GLKVector4Make(far_point.v[0]*far_point.v[3], far_point.v[1]*far_point.v[3], far_point.v[2]*far_point.v[3], 1);
于 2012-04-10T14:52:08.087 に答える