3

私はC#のゲームにOpenTKを使用していますが、ワールド座標と画面座標の間で変換するプロジェクト関数とプロジェクト解除関数は付属していません。ええ、そうですが、それらは非推奨であり、私はそれらを動作させることができませんでした。私はopengl仕様に基づいてそれらを自分で実装することを試みました(左側のメニュー、gluProjectとgluUnProjectを参照し、ChromeではなくFFで表示してください)。それらの式を参照してください、私はそれらを一致させようとしています。私の関数はまったく機能していません。Projectが返すポイントはすべて画面の中央近くにあり、ワールドポイントをあちこちに移動しているにもかかわらず、非常に接近しています。

OpenTKのmathlibには、行列にベクトルを乗算する関数が含まれていないことに注意してください。そのため、結果のベクトルの各エントリに対して、行列の行とベクトルの内積を計算しました(正しいですね)。

    public static Vector3d Project(Vector4d point, Matrix4d projection, Matrix4d modelview, int[] view)
    {
        Matrix4d temp = Matrix4d.Mult(projection, modelview);
        // multiply matrix by vector
        Vector4d v_prime = new Vector4d(
            Vector4d.Dot(temp.Row0, point),
            Vector4d.Dot(temp.Row1, point),
            Vector4d.Dot(temp.Row2, point),
            Vector4d.Dot(temp.Row3, point)
            );

        v_prime = Vector4d.Divide(v_prime, v_prime.W);

        return new Vector3d(
            view[0] + view[2] * (v_prime.X + 1) / 2,
            view[1] + view[3] * (v_prime.Y + 1) / 2,
            (v_prime.Z + 1) / 2
            );
    }

    public static Vector3d UnProject(Vector3d window, Matrix4d modelview, Matrix4d projection, int[] view)
    {
        Matrix4d inv = Matrix4d.Mult(projection, modelview);
        inv.Invert();

        double vx = (2 * (window.X - view[0])) / view[2] - 1;
        double vy = (2 * (window.Y - view[1])) / view[3] - 1;
        double vz = (2 * window.Z) - 1;

        Vector4d vect = new Vector4d(vx, vy, vz, 1);

        // now multiply matrix times vector, which is really row (dot) vector for each value
        // correct, the bottom row of the inv matrix is unused
        return new Vector3d(
            Vector4d.Dot(inv.Row0, vect),
            Vector4d.Dot(inv.Row1, vect),
            Vector4d.Dot(inv.Row2, vect)
            );
    }
4

2 に答える 2

2

完全にはわかりませんが、少なくともProject関数内の行列の乗算の順序が間違っている可能性があります。Cコードのhttp://www.opengl.org/wiki/GluProject_and_gluUnProject_codeを見てください。ここでは、(コード内の)一時ベクトルv_primeは、最初にモデルビューマトリックスを乗算して計算され、次に結果に射影が乗算されます。マトリックス。

gluProject/gluUnProject実装を探すためのもう1つの良い情報源は、 http://www.mesa3d.org/です。

于 2010-08-20T09:20:05.450 に答える
2

私はそれを理解しました-私の行列は転置する必要がありました。理由はわかりませんが、OpenTK関数は、ネイティブ呼び出しとは異なる方法でモデル行列を返しました。

于 2010-08-22T02:23:02.720 に答える