# Get Screen Position

Hi

Is it possible to get the position on the screen that a spatial is being drawn? And also the size?

I want to draw a 2D box around a 3D object when it is selected.

Hi,

yes you can know screen position with camera.getScreenCoordinates(vertexPosition)

Cool that works good.

But is there anyway of getting the size.

I'm thinking I could always loop the vectors to find edges but is there a better way?

Petah said:

Cool that works good.

But is there anyway of getting the size.
I'm thinking I could always loop the vectors to find edges but is there a better way?

If you want to draw a 2D box (e.g. like targeting brackets?) you could also just use a quad positioned at the model, maybe as large as its bounding box (or some other way of determining its size), and screen aligned (e.g. using a billboard node). E.g. something like below...

And a quick thing I made while writing this up using the above mentioned steps ;)

Yes I thought of using the bounding box, but for one what if I'm using a bounding sphere, and two even for what ever type of bounding I use would I not still have to loop through each vertex and calculate the relative screen position to find the edge?

Petah said:

Yes I thought of using the bounding box, but for one what if I'm using a bounding sphere, and two even for what ever type of bounding I use would I not still have to loop through each vertex and calculate the relative screen position to find the edge?

Well with the bounding sphere, you'd use the radius for width and height. Though you'd run into problems where an object is much longer than it is wide. You can always just manually tweak those values of course. Or just implement a similar algorithm found in the bounding volume classes to create the quad (in which case, you'd loop over the vertices trying to find an appropriate width and height for your 2D box - look in the bounding classes).

For the second point, do note that the above solution I mentioned doesn't use anything with the screen positions of vertices, that quad is out there in 3D space. You'd calculate the quad's width/height however well you'd like, place it in a billboard node, have it aligned with the screen, and attach that to whatever you're selecting.

You could probably do what you're thinking of, of finding the dimensions needed in screen coordinates to define the 2D box. Most likely that 2D box then would be represented by a Quad being rendered in Ortho mode. Frankly, I'd find it a lot easier just having the quad out in 3D space attached to a billboard node oriented towards the screen.

OK well I’ve got it every thing working.

The only problem is that it doesn’t take rotation into account, any idea on how to correct that?

EG:

The code I’ve used is:

```     private void paintHud(Graphics2D g) {         GameGraphics.setAlpha(g, 0.3f);         for (GameObject gameObject : Selection.getSelectedObejcts()) {             Vector3f[] vertices = new Vector3f[gameObject.getVertexCount()];             vertices = gameObject.getMeshAsTrianglesVertices(vertices);             Vector2f topLeft = new Vector2f(getWidth(), getHeight());             Vector2f bottomRight = new Vector2f(0, 0);             for (Vector3f v : vertices) {                 if (v != null) {                     Vector3f pos = GameSystem.getCamera().getScreenCoordinates(v.add(gameObject.getLocalTranslation())); //                    g.setColor(Color.RED); //                    g.drawLine((int) pos.x, getHeight() - (int) pos.y, (int) pos.x, getHeight() - (int) pos.y);                     if (pos.x < topLeft.x) {                         topLeft.x = pos.x;                     }                     if (pos.y < topLeft.y) {                         topLeft.y = pos.y;                     }                     if (pos.x > bottomRight.x) {                         bottomRight.x = pos.x;                     }                     if (pos.y > bottomRight.y) {                         bottomRight.y = pos.y;                     }                 }             }             g.setColor(Color.GREEN);             //Relitive padding             int x = (int) topLeft.x;             int y = getHeight() - (int) topLeft.y - (int) (bottomRight.y - topLeft.y);             int width = (int) (bottomRight.x - topLeft.x);             int height = (int) (bottomRight.y - topLeft.y);             float padding = 0.2f; //            g.drawOval(x - (int) (width * padding), y - (int) (height * padding), //                    width + (int) (width * padding) * 2, height + (int) (height * padding) * 2);             g.drawRect(x - (int) (width * padding), y - (int) (height * padding),                     width + (int) (width * padding) * 2, height + (int) (height * padding) * 2);             //Absolute padding //            int padding = 50; //            int x = (int) topLeft.x - padding; //            int y = getHeight() - (int) topLeft.y - (int) (bottomRight.y - topLeft.y) - padding; //            int width = (int) (bottomRight.x - topLeft.x) + padding * 2; //            int height = (int) (bottomRight.y - topLeft.y) + padding * 2; //            g.drawOval(x, y, width, height); //            g.drawOval((int) topLeft.x - padding, getHeight() - (int) topLeft.y - (int) (bottomRight.y - topLeft.y) - padding, //                    (int) (bottomRight.x - topLeft.x) + padding * 2, (int) (bottomRight.y - topLeft.y) + padding * 2);         }     } ```