Pregunta

Estoy usando OpenTK para un juego en C #, y que no viene con el proyecto y funciones unproject, que convierten entre las coordenadas mundiales y la pantalla. Bueno, sí, pero están en desuso y no podía llegar a trabajar. Tomé un tiro en su aplicación a mí mismo en base a la OpenGL spec (ver la mano izquierda menú, gluProject y gluUnProject, y vista en FF, no cromo). Ver las fórmulas, estoy tratando de coincidir con ellos. Mis funciones no funcionan en absoluto, los puntos que los retornos del proyecto son todos cerca del centro de la pantalla, y muy próximos entre sí, a pesar de que me estoy moviendo mi punto mundo por todo el lugar.

Tenga en cuenta que lib matemáticas de OpenTK no incluye funciones para multiplicar una matriz por un vector, por lo que acabo de hacer fila de la matriz de productos escalares del vector para cada entrada en el vector resultante (eso es correcto, no?)

    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)
            );
    }
¿Fue útil?

Solución 2

Me lo descubrió - mis matrices necesitan ser incorporadas. No sabemos por qué, pero las funciones OpenTK dieron mis matrices modelo de forma diferente que las llamadas nativas.

Otros consejos

No estoy del todo seguro, pero al menos el orden de las multiplicaciones de matrices en función de su Project podría estar equivocado. Echar un vistazo a http://www.opengl.org/wiki/GluProject_and_gluUnProject_code para el código C , donde el vector temporal (v_prime en su código) se calcula multiplicando con la matriz modelview primero y el resultado es entonces a su vez multiplicado con la matriz de proyección.

Otra buena fuente para buscar una aplicación gluProject / gluUnProject es http://www.mesa3d.org/.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top