1
\$\begingroup\$

It seems like converting a screen point to a world point is easy in libgdx but going from the world point to a screen point is quite tricky.

So How do I convert a world point into a screen point?

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

Camera has methods for both projecting (moving from world-coordinates to screen-coordinates) and un-projecting (moving from screen-coordinates to world-coordinates).

Vector3 screenPosition = camera.project(worldPosition);

Vector3 worldPosition = camera.unproject(screenPosition);

\$\endgroup\$
2
  • \$\begingroup\$ I couldn't get it to work with project, that's why I wrote this. hopefully it can help somebody else. I am using an orthographic camera. \$\endgroup\$
    – GabeTheApe
    May 21, 2022 at 18:40
  • \$\begingroup\$ OrthographicCamera inherits Camera so that should not make a difference, @GabeTheApe. Either way I think your initial question could benefit with some detail about the particular scenario you were facing where the Camera method didn't work. \$\endgroup\$
    – bornander
    May 22, 2022 at 18:32
0
\$\begingroup\$

This is a versatile approach and works in many implementations

    public static Vector3 MultiplyPoint(Matrix4 m, Vector3 point)
{
    Vector3 result = new Vector3(0, 0, 0);
    result.x = m.val[Matrix4.M00] * point.x + m.val[Matrix4.M01] * point.y +  m.val[Matrix4.M02]* point.z +  m.val[Matrix4.M03];
    result.y = m.val[Matrix4.M10] * point.x + m.val[Matrix4.M11] * point.y + m.val[Matrix4.M12] * point.z + m.val[Matrix4.M13];
    result.z = m.val[Matrix4.M20] * point.x + m.val[Matrix4.M21] * point.y + m.val[Matrix4.M22] * point.z + m.val[Matrix4.M23];
    float num = m.val[Matrix4.M30] * point.x + m.val[Matrix4.M31] * point.y + m.val[Matrix4.M32] * point.z + m.val[Matrix4.M33];
    num = 1f / num;
    result.x *= num;
    result.y *= num;
    result.z *= num;
    return result;
}

public static Vector2 WorldToScreenPoint(float x, float y)
{
    Matrix4 V = Constants.Camera.view;
    Matrix4 P = Constants.Camera.projection;
    
    Matrix4 MVP = P.mul(V); // Skipping M, point in world coordinates
    Vector3 screenPos = MultiplyPoint(MVP, new Vector3(x, y, 0));
    
    Vector3 screenPoint = new Vector3(screenPos.x + 1f, screenPos.y + 1f, screenPos.z + 1f).scl(0.5f); // returns x, y in [0, 1] internal. 
    
    return new Vector2(screenPoint.x * Constants.GlobalWidth, screenPoint.y * Constants.GlobalHeight); // multiply by viewport width and height to get the actual screen coordinates.
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .