¿Qué hay de malo en mi proyecto y funciones unproject?
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)
);
}
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/.