Understanding camera’s getScreenCoordinates(Vector3f worldPos)

Hello!



Didn’t quite get it. According to sources this function does:

[java]float w = viewProjectionMatrix.multProj(worldPosition, store);

store.divideLocal(w);



store.x = ((store.x + 1f) * (viewPortRight - viewPortLeft) / 2f + viewPortLeft) * getWidth();

store.y = ((store.y + 1f) * (viewPortTop - viewPortBottom) / 2f + viewPortBottom) * getHeight();

store.z = (store.z + 1f) / 2f;



return store;[/java]



By definition of the word “screen” the output should be Vector2f or even to be completely right it should be vector of 2 ints… what is the meaning of the third parameter then which is calculated by:

[java]store.z = (store.z + 1f) / 2f;[/java]

?

Coordinates from multproj are in clip space.

clipspace is a space that goes from -1 to 1 the origin being the center of the screen.

Screen coordinates are usually expressed in this space because it avoid to take resolution into account.

But… for convenience, getScreenCoordinate does return the real screen coordinates, because that’s how all other gui coordinates are expressed in JME.



you’re right about the vector2Int remark, but creating a new type just for that was overkill, and vercor 3f can handle it very well.



the z value is kept in clip space and can be used as a z-index for the GUI. Hence the vector3f

Depth.



And just because the pixels are “integers” doesn’t mean that the coordinates for a 3D point should be.

@nehon said:
you're right about the vector2Int remark, but creating a new type just for that was overkill, and vercor 3f can handle it very well.


No. Frankly, if my object is between two "pixels", I want to know that.
@pspeed said:
Depth.

What depth means if we are speaking of screen coordinates? Distance to the object? It can't be since .z is always a small number..
screen is a 2d object, right? At least I am looking at such right now :)
By calling this function I get 2 variables (.x and .y) which corresponds to the screen coordinates, and .z contains some magical numbers which I am trying to understand why they are needed in the context of 2 dimensional screen (or screen space).
According to my tests this .z number is something like a "facing variable", because if this number is <1 then the object is visible at the screen, and if it is >1, then the object would be visible if I had one extra pair of eyes on my back :)
@KayTrance said:
What depth means if we are speaking of screen coordinates? Distance to the object? It can't be since .z is always a small number..


It's the distance to the passed coordinate in clip space. My understanding is that 0 is the near plane and 1 is the far plane.

But if you only want x,y then why worry about it?
But if you only want x,y then why worry about it?

Well.. in my project I do the following:
  • 1. Click at the screen at the desired location.

  • 2. Check for collision with game objects.

  • 3. If collision successful I place the rectangle (as a NiftyGUI panel) attached to the guiNode. Something like a selection box.


Now I need to re-position this selection box if the camera is moved or rotated. To do this I:
  • 1. call cam.getScreenCoordinates(targetLocatTranslation)

  • 2. get the selection box element and set a new ConstraintX and ConstraintY for it using .x and .y from the vector above.


The funny thing happens if I turn in opposite direction so that the object isn't visible anymore. In theory the selection box would be outside of the screen, right? Wrong :) Since it seems that by returning .x and .y getScreenCoordinates doesn't take in account whether I face the object or.. or am I facing directly in opposite direction. The .x and .y will be the same and the only difference would be in .z - in case the object will be in front of me, .z will be less than 1, and in case the object will be behind me, .z will be greater than 1.

It’s a bit cryptic I’ll admit, but there’s the reason why (if understand your problem correctly).



http://hub.jmonkeyengine.org/groups/general-2/forum/topic/behavior-of-getscreencoordinatesvec3-under-certain-circumstances/?topic_page=1&num=15#post-169147

And if you just want to know if the object is in front of you or behind you, you can do one dot product (a super simple 3 multiplications) before you even bother doing the getScreenCoordinates()… (which is going to do a bunch more math).



If you have a world position, get the position relative to the camera:

Vector3f pos = worldPosition.subtract( camera.getLocation() );



Then the dot product with the camera’s look vector:

float dot = camera.getDirection().dot( pos );



“dot” is now that actual distance of the worldPosition from the camera along the look vector… so positive is in front of you and negative is behind you. And it’s the real distance from the camera in world units… which can be useful for all kinds of things.



(The dot product is one of my favorite things.)

@pspeed

Ah right! Now I get what you meant in my thread. :smiley: I was under the impression you wanted me to do the dot product after I got the screen coordinates which in that case didn’t make sense. Still, since it doesn’t matter if it’s behind the camera I still had to get screen coordinates. At least now your answer makes more sense. :slight_smile: