MathHelp: ScreenCoordinates to WorldCoordinates

Assuming that my camera is located at (0,0,25) and the looking direction is (0,0,-1)

For spawning my gameobjects i would require the world position of an screencoordinate at WorldDepth 0.

Like:

[java]
toWorldPos(cam.getWidth(),cam.getHeight()) = Vector3f(?,?,0)
[/java]

Anyone with an idea to head me in the right direction?

Camera getWorldCoordinates(Vector2f screenPosition,float projectionZPos) looks close to what you need.

Thanks, already found that method, but i really could not get it working:

Following the doc, this should work:
[java]
System.out.println("Reversal: 0,0: " + camera.getScreenCoordinates(camera.getWorldCoordinates(new Vector2f(0, 0), camera.getViewToProjectionZ(25))));
System.out.println("Reversal: 0,1: " + camera.getScreenCoordinates(camera.getWorldCoordinates(new Vector2f(0, 1), camera.getViewToProjectionZ(25))));
System.out.println("Reversal: 1,1: " + camera.getScreenCoordinates(camera.getWorldCoordinates(new Vector2f(1, 1), camera.getViewToProjectionZ(25))));
System.out.println("Reversal: 1,0: " + camera.getScreenCoordinates(camera.getWorldCoordinates(new Vector2f(1, 0), camera.getViewToProjectionZ(25))));
[/java]

the output should show me a quad, 25units in front of the camera

But the actual output is:

Location: (0.0, 0.0, 25.0)
Direction: (0.0, 0.37139067, -0.9284766)
0,0: (-5.82488, -0.3299282, -2.057839)
0,1: (-5.82488, -0.31490555, -2.0518308)
1,1: (-5.8087, -0.31490555, -2.0518308)
1,0: (-5.8087, -0.3299282, -2.057839)

small rounding errors are not a problem really, but that numbers are way off

I think that you are supposed to pass screen coordinates in pixels, rather than in 0-1 range.

1 Like

Yeah, it does take pixel coordinates, and the getViewToProjectZ does also work different, for now i have hardcoded the value i need, but that cant be the production solution.

Wonder if i am the first person that needs stuff like this?

When you say worlddepth 0 what do you mean? Do you mean at the near plane of the camera or 0 wu in front of the camera because if the latter it would be the same as the camera location :slight_smile:

No i mean that the position should be in my case 25 wu in front of the camera, at worldPosition.z==0

@zzuegg said: Yeah, it does take pixel coordinates, and the getViewToProjectZ does also work different, for now i have hardcoded the value i need, but that cant be the production solution.

Wonder if i am the first person that needs stuff like this?

Show us the latest code and output with 25.

Yeah, now I see, you wrote in your example what you meant but I didn’t read to good.
But if you want to spawn on the plane at 25 wu I guess you could calculate it backwards from knowing where the near plane (which is also the screen projection plane) is and what pixels project where on that using the FOV.

I’m thinking like this, using the vertical axis, the near plane distance is 1 and the FOV angle is 45 deg for the top pixel Then it should be possible to figure out the angle for any pixel if it was drawn on the near plane. So then you have the angle and you know that you want to project it on the plane at 25 wu instead of on the near plane so atan and tan ought to cover it. The horizontal should be the same but adjusted for the aspect ratio.

I think :-?

@jmaasing said: Yeah, now I see, you wrote in your example what you meant but I didn't read to good. But if you want to spawn on the plane at 25 wu I guess you could calculate it backwards from knowing where the near plane (which is also the screen projection plane) is and what pixels project where on that using the FOV.

I’m thinking like this, using the vertical axis, the near plane distance is 1 and the FOV angle is 45 deg for the top pixel Then it should be possible to figure out the angle for any pixel if it was drawn on the near plane. So then you have the angle and you know that you want to project it on the plane at 25 wu instead of on the near plane so atan and tan ought to cover it. The horizontal should be the same but adjusted for the aspect ratio.

I think :-?

But you need to know all of the projection parameters… and why do manually what getScreenCoordinates() and its reciprocal are exactly doing for you?

@pspeed said: But you need to know all of the projection parameters... and why do manually what getScreenCoordinates() and its reciprocal are exactly doing for you?

zzuegg didn’t seem happy with it. But as you say, the camera already does this.

1 Like
@jmaasing said: zzuegg didn't seem happy with it. But as you say, the camera already does this.

Yeah, math is math… another method will have the same issues as the current method should work fine.

I’ve used this stuff before without issue but it can be tricky to get it wired properly.

1 Like

Allright got it working somehow:

[java]
System.out.println("Location: " + cam.getLocation());
System.out.println("Direction: " + cam.getDirection());
System.out.println("Projection Z: " + cam.getViewToProjectionZ(25));
System.out.println("0,0: " + cam.getWorldCoordinates(new Vector2f(0, 0), cam.getViewToProjectionZ(cam.getLocation().getZ())));
System.out.println("0,1: " + cam.getWorldCoordinates(new Vector2f(0, cam.getHeight()), cam.getViewToProjectionZ(cam.getLocation().getZ())));
System.out.println("1,1: " + cam.getWorldCoordinates(new Vector2f(cam.getWidth(), cam.getHeight()), cam.getViewToProjectionZ(cam.getLocation().getZ())));
System.out.println("1,0: " + cam.getWorldCoordinates(new Vector2f(cam.getWidth(), 0), cam.getViewToProjectionZ(cam.getLocation().getZ())));
[/java]

does the job.

Also it seems i kind of misunderstood/misread the javadoc, which was causing my issues at the first place.

This:
cam.getViewToProjectionZ(cam.getLocation().getZ())));

…implies that your camera is at z = 25. If you want things 25 units in front of the camera then replacing cam.getLocation().getZ() with 25 should work.

Yeah, sure. In my case cam position is fixed so it works

I haven’t actually tested but I would guess that the camera position in the world does not matter for getViewToProjectionZ, it goes from view space (eye space, the cameras POV) so ‘25’ means 25 units in front of the camera, regardless of where the camera is located or rotated. It maps Z to the projection space (which is non-linear but shouldn’t matter much) and then you go back from that to world space using the getWorldCoordinates.
At least that’s how I read the docs, I really need to install jME on this machine so I can test before I speak :slight_smile:

@jmaasing said: I haven't actually tested but I would guess that the camera position in the world does not matter for getViewToProjectionZ, it goes from view space (eye space, the cameras POV) so '25' means 25 units in front of the camera, regardless of where the camera is located or rotated. It maps Z to the projection space (which is non-linear but shouldn't matter much) and then you go back from that to world space using the getWorldCoordinates. At least that's how I read the docs, I really need to install jME on this machine so I can test before I speak :-)

Yes, that’s how it should be. View space = camera space.

@zzuegg said: Yeah, sure. In my case cam position is fixed so it works

Yeah, but it’s only coincidence. If you read that code 6 months from now you will be scratching your head. :slight_smile:

In my case it is neccesary to spawn objects at WorldPos.z==0, in that case cam.getLocation.getZ() should be the “always working” solution