I am trying to implement a 2D selection window that can select the 3D vertices inside the 2D window (indicated by dashed cyan rectangle). Each of my 3D models is currently a composite group of MeshView's, one MeshView per face. My plan was to iterate over each face (MeshView) and check if the 2D bounds intersect with the selection box bounds (I am planning to update this later using an Atlas texture to reduce the amount of meshes, but for now I just want the selection mechanism working).
Currently I have the following, but this isn't correct.
val selectionBounds = selectionRectangle.boundsInParent
val localBounds = meshView.localToScene(meshView.boundsInLocal, true)
if (selectionBounds.intersects(localBounds))
// do something with the mesh in meshView
My subscene contains a perspective camera, now I saw two useful posts:
- Convert coordinates from 3D scene to 2D overlay
- How to get 2D coordinates on window for 3D object in javafx
I think I have to first project the meshView's bounds properly using my perspective camera. But I am unsure how to proceed, do I have to project every 3D point in the local bounds to 2D as is done in referenced question 2 (above). Not very familiar with the math, or related concepts, any help would be appreciated.
(wink, wink MVP José)
EDIT 1:
After José's suggestion I added red bounding boxes for each meshview which gives the following result:
Apparently it adds some offset which appears to be the same regardless of the camera rotation. Here the red boxes are drawn around each meshview. Will investigate further..
EDIT 2:
I use a Pane which contains the SubScene and another Node. This is done to control the sizing of the SubScene and to reposition/resize the other Node accordingly by overriding the layoutChildren
method, as such (this is in Kotlin):
override fun layoutChildren() {
val subScene = subSceneProperty.get()
if (subScene != null){
subScene.width = width
subScene.height = height
}
overlayRectangleGroup.resize(width, height)
val nodeWidth = snapSize(overlayMiscGroup.prefWidth(-1.0))
val nodeHeight = snapSize(overlayMiscGroup.prefHeight(-1.0))
overlayMiscGroup.resizeRelocate(width - nodeWidth, 0.0, nodeWidth, nodeHeight)
}