libgdxperspectivecameradecal

libgdx get size of sprite in pixels on the screen


I'm working on Libgdx project. It's basically 2.5D aproach, so I use Decals, and DecalBatch. There is also PerspectiveCamera, which I can manipulate (zoom in/out), and the decals are static.

I'm having problem finding out what is the real size of decal projection on the screen, eg. when camera is zoomed in, it is bigger, when is zoom out, decal apears smaller on the screen.

I need to get that size.

I have tried camera.project, and camera.unprojects, but it returns the same values for both, and it works only for decal's position, and also I'm not sure what coordinate system is used for Decals in Libgdx.

Any suggestion how to work this out? What can I do?


Solution

  • Camera.project is the way to go. It does exactly what you want... "finding out what is the real size of decal projection on the screen".

    I'm not sure what coordinate system is used for Decals in Libgdx

    A standard (right-handed) 3D coordinate system. You supply the size of your decal when you create them via Decal.newDecal(width, height, ...). That's the size on the X and Y axes.

    What you need to do is the following:

    Calculate the 3D vertices of the decal, that means the "corner" points of the quad, by using the position, the dimension, the rotation and the scale of the decal. There is Decal.getVertices() which might already return those values for you, but it's a float[] and it's not documented how those values have to be interpreted.

    Once you have those 4 vertices you can use Camera.project(...) to get the position on the screen of this point. In case your decals are not always facing the camera directly, those coordinates won't necessarily define a rectangle, but this will depend on your usecase and what you actually want to achieve with this information.

    In case you want to detect input events on those decals (like clicks), you should probably create a BoundingBox for your decal (you might use the vertices which you've already calculated) and create a Ray with your Camera and the input coordinates. Then use Intersector.intersectRayBoundsFast(Ray, BoundingBox) to check if your click has hit this decal.

    Edit: You can get the vertices like this:

    float[] vertices = decal.getVertices();
    Vector3 topLeft = new Vector3(vertices[Decal.X1], vertices[Decal.Y1], vertices[Decal.Z1]);
    Vector3 topRight = new Vector3(vertices[Decal.X2], vertices[Decal.Y2], vertices[Decal.Z3]);
    Vector3 bottomLeft = new Vector3(vertices[Decal.X3], vertices[Decal.Y3], vertices[Decal.Z3]);
    Vector3 bottomRight = new Vector3(vertices[Decal.X4], vertices[Decal.Y4], vertices[Decal.Z4]);