Convert 3D coordinates to 2D


I am facing an issue while converting 3D coordinates to 2D. My idea is to show a popup when I right click on a box. When I right click the popup appears but far away from the box.

Below is the code:

Vector2f ip = inputManager.getCursorPosition().clone();, ((int)ip.x), ((int)ip.y));

PS: I am using TWL for the popup menu

This post was wrongly tagged to SDK forum, it has been reposted in GUI forum.


@wezrule said: cam.getScreenCoordinates(worldPos)

by worldPos do you mean the WorldTranslation of the box?
I have already tried that and I still see the issue.

If you’re using Nifty popups, you need to know that Nifty and jME3 use opposite conventions for screen y-coordinates. One measures down from the top of the viewport, the other measures up from the bottom. Perhaps TWL has the same issue?

getScreenCoordinates should take care of an inverted Y position.

@shrikantkhapare you are probably feeding some other coordinate than world coordinates (most likely local). It’s easy to use the wrong coordinates since there are so many around. I didn’t find them explained in the tutorials (anybody know them?), so here’s a short rundown:

  • Local coordinates - this is relative to the paren’t local coordinates. This is so that you can attach stuff to a Spatial without worrying how it might have been translated, rotated, scaled, sheared, or otherwise transformed. This is where GUI libraries apply coordinate transforms.
  • World coordinate system - that’s the coordinate system of the scene graph. This is fixed.
  • View (or eye, or camera) coordinates - these are used in shaders, it’s the “behind-the-screen” position of a point.
  • Clip coordinates - x and y are already aligned to screen XY coordinates, z reflects distance from the viewer (plus there’s w, a nonlinear scaling value for z).
  • Device (or screen) coordinates - 2D pixel coordinates. (With exceptions, such as 640x480 full-screen mode on a 1024x768 screen, where the device itself will scale pixels up or down. I guess that’s why OpenGL says “fragment” instead of “pixel”.)

getScreenCoordinates applies all of the transformations from world to device for you.
You still need to take care whether you’re using local or world coordinates.

@toolforger I tried getScreenCoordinates.

Vector3f point = results.getClosestCollision().getGeometry().getWorldTranslation();
Vector3f camCod = cam.getScreenCoordinates(point);, (int)camCod.x, (int)camCod.y);

With this I get the below result:

You’d feeding screen coordinates to the popup.
Does use screen coordinates?
World coordinates?
Coordinates relative to frame?

(Oh, and how did you get TWL to work within JME? I never found out how to properly map the TWL concepts to the JME concepts.)

@toolforger I am not too sure but I guess uses screen coordinates. And yes, it uses the coordinates relative to frame(JInternalFrame).
I tweaked one of the TWL examples’ code for my purpose =D

If you’re not sure, look it up. Ask on the TWL forum if you can’t find out. JInternalFrame comes with yet another set of coordinate systems, any of which could be used by TWL - it could be screen coordinates, or relative to the outer frame, or relative to the inside area, with a positive or a negative Y axis, that’s already six possible coordinate systems, plus four possible coordinate systems on the LWJGL side, so you’re basically doing a gamble with a 1:9 (10%) chance. If anything works, it’s by accident, and will most likely break again as soon as coordinates get more involved - say, window resizing / resolution change, JME modifying the OpenGL transform stack, and whatever.

What example did you start work from?

Hi @toolforger download the from the below link there are a few examples.

Heck I know the TWL website. Been there, done that, downloaded stuff etc.
I found that integrating it into JME properly would be too much work. So I was wondering how you did that. A generic reference to “all the examples” isn’t going to tell that, I had hoped I could infer something from knowing what example you started off from, but maybe that was the wrong approach.

So… how did you integrate TWL into JME?