Is it possible in a JavaFX 8 3D scene to find points along a ray (e.g. PickRay), starting at an arbitrary point in 3D space with some 3D direction vector, where the ray intersects the triangles in a mesh (TriangleMesh inside a MeshView)?
I know this is done in the Camera/MouseHandler for mouse picking but I can't see any way for doing it for arbitrary rays.
As @jdub1581 suggests, a ray is just a geometric vector, so in order to find a list of triangles intersected by this vector we need to solve problems of the kind 'line intersects plane' and 'line intersects plane within the triangle borders'.
Let's assume we have a
TriangleMesh
, and we have a list of vertices and a list of faces. Each vertex with 3 coordinates, each face with 3 vertices (without considering texture, normals,... ). For the sake of simplicity let's use two lists ofPoint3D
to store them.In this link there are several 3D shapes ready to use. Let's grab one
CuboidMesh
.This will give us this 3D shape:
Now, if we have a look at the mesh, we could create two lists with vertices and faces:
Let's add some 3D points in our scene, one origin and one target, both in global coordinates, and define the direction of the vector, normalized:
The ray equation then will be this:
If we add a slender cylinder between these two points we'll have a visual representation of our ray:
Bounding Box Intersection
The first step will be checking if the ray intersects the bounding box of our shape. In local coordinates of the shape we have 6 faces given by their normals, with their 6 centers:
Since we'll work on the local system, we need our origin point in this coordinates:
Now, for any of the six faces, we get the distance
t
to the plane following this link. Then we can check if the point belongs to the box or not.If
counter.get()>0
then we have some intersections between the ray and the shape, and we can proceed with the triangles. In this example, these will be the intersection points: (3.5,-4.5, -2) and (2.5,0.5,2).Triangles intersection
There are several algorithms for the task of finding if the ray intersects any triangle of the mesh, so we don't need to reinvent the wheel.
The one I've used is from Tomas Möller & Ben Trumbore. It will provide the distance
t
from the origin to the plane, and the coordinatesu,v
inside the triangle for a given intersection.Once we have the origin in local coordinates of the shape, and we know the direction of the ray, the implementation of this algorithm is this:
In this sample, we find three faces, given by these vertices: (85, 1245, 1274), (85, 1274, 1266) and (351, 1476, 1479).
If we plot those faces will see the intersection:
Note that by performing all the operations in the local coordinate system of the shape we save the operations of transforming every triangle to the global system.
This algorithm is really fast. I've tested up to 3M triangles in less than 40 ms.
All the code for this test is available here.