Estoy escribiendo un juego 2D en el que mi mundo de juego tiene eje x de izquierda a derecha, eje y de arriba a abajo y eje z fuera de la pantalla:
Mientras mi mundo de juego es de arriba hacia abajo, el juego se presenta con una ligera inclinación:
Estoy trabajando en proyectar del espacio mundial al espacio de la pantalla, y viceversa. Tengo el primero trabajando de la siguiente manera:
var viewport = new Viewport(0, 0, this.ScreenWidth, this.ScreenHeight);
var screenPoint = viewport.Project(worldPoint.NegateY(), this.ProjectionMatrix, this.ViewMatrix, this.WorldMatrix);
El NegateY()
método de extensión hace exactamente lo que parece, ya que el eje y de XNA se ejecuta de abajo hacia arriba en lugar de arriba hacia abajo. La captura de pantalla anterior muestra que todo esto funciona. Básicamente, tengo un montón de puntos en el espacio 3D que luego renderizo en el espacio de la pantalla. Puedo modificar las propiedades de la cámara en tiempo real y verlo animado a la nueva posición. Obviamente mi juego real usará sprites en lugar de puntos y la posición de la cámara será fija, pero solo estoy tratando de poner todas las matemáticas en su lugar antes de llegar a eso.
Ahora, estoy tratando de volver a convertir a la inversa. Es decir, dado un punto x e y en el espacio de la pantalla anterior, determine el punto correspondiente en el espacio mundial. Entonces, si apunto el cursor a, digamos, la parte inferior izquierda del trapecio verde, quiero obtener una lectura del espacio mundial de (0, 480). La coordenada z es irrelevante. O, más bien, la coordenada z siempre será cero al mapear de nuevo al espacio mundial. Esencialmente, quiero implementar la firma de este método:
public Vector2 ScreenPointToWorld(Vector2 point)
He intentado varias cosas para que esto funcione, pero no tengo suerte. Mi último pensamiento es que necesito llamar Viewport.Unproject
dos veces con diferentes valores z cercanos / lejanos , calcular la resultante Ray
, normalizarla, luego calcular la intersección de la Ray
con una Plane
que básicamente representa el nivel del suelo de mi mundo. Sin embargo, me quedé atrapado en el último paso y no estaba seguro de si estaba complicando demasiado las cosas.
¿Alguien puede señalarme en la dirección correcta sobre cómo lograr esto?