In javafx if we have 2D HUD (made of Pane and then out of it we create SubScene object for 2D Hud) and 3D SubScene and inside 3D scene we have some object with coordinates (x,y,z) - how can we get 2D coordinates in our HUD of the object if it is in visual field of our perspective camera?
I tried to get first Scene coordinates of the object and then convert it (sceneToScreen) coordinates and the same for point (0,0) of Pane and then to subtract first point from second point but i don't get right result. Sorry because of my bad English.Can Someone help with this?
There is a way to convert the 3D coordinates of an object in a subScene to a 2D scene coordinates, but unfortunately it uses private API, so it is advised not to rely on it.
The idea is based on how the camera projection works, and it is based on the
com.sun.javafx.scene.input.InputEventUtils.recomputeCoordinates()
method that is used typically for input events from aPickResult
.Let's say you have a node in a sub scene. For a given point of that node, you can obtain its coordinates like:
and you can find out about the sub scene of the node:
Now you can use the
SceneUtils::subSceneToScene
method thatto get a new set of coordinates, referenced to the scene:
But these are still 3D coordinates.
The final step to convert those to 2D is with the use of
CameraHelper::project
:The following sample places 2D labels in the scene, at the exact same position of the 8 vertices of a 3D box in a subScene.
The FXyz3D library has another similar sample.
EDIT
A late edit of this answer, but it is worthwhile mentioning that there is no need for private API. There is public API in the
Node::localToScene
methods that allows traversing the subScene.So this just works (note the
true
argument):According to the JavaDoc for
Node::localToScene
:Without
true
the conversion is within the subScene, but with it, the conversion goes from the current subScene to the scene. In this case, this methods callsSceneUtils::subSceneToScene
, so we don't need to do it anymore.With this,
updateLabels
gets simplified to: