The demo performed 2 separate actions, selecting the object clicked on, and if
any object was found, then the object itself was modified and the point clicked
on was highlighted. Picking objects on the screen with a mouse is quite simple
in Three.js. Here's the first half of the MouseDown function which sets up to
perform picking. The bulk of the code fires a ray from the eye into the world.
This is a common way to perform picking. WebGL itself is focused on rendering,
so has no real support for picking in other forms of interaction. It's up to
the program to figure this out. To form a ray from the eye through the screen
we need two points. One's the eye's position in the world space, that's easy.
The other is formed using a point on the screen, that point being locate
wherever the user clicked the mouse. What we want to know is this point's
location in world space. To do so we need to travel upstream, back along the
chain of transformations: window coordinates to normalized device coordinates,
to view, to world coordinates. Happily, Three.js makes this easy. How many
times have I said that sentence during this course? The 2D point from the
MouseDown event is a document object model screen coordinate. This is like a
WebGL window coordinate, only y equals 0 is at the top edge of the screen
instead of the bottom. The mouse vector code here converts from this screen
coordinate system into normalized device coordinates, which go from -1 to 1 in
x and y. The z value doesn't really matter. Any value from z equals -1 to 1
will form a point on the ray. We next create a projector object. Really, it's
better to create this object once during initialization and reuse it here, but
I wanted to show the code all in one piece. The final line of code does the
heavy lifting. It takes the NDC coordinate and forms a raycaster object from
it. Ray casting is like ray tracing except you only trace rays from the eye
into the scene and no further. No new rays are spawn from intersections. Once
we have this raycaster object, we can perform picking, aslo called hit testing.
It's one line of code to pick. You feed a list of objects into the raycaster
and it returns an array of intersections. The If statement checks if the ray
has anything in it. If it does then one or more intersections have been
detected. These intersections are sorted front to back, so the first
intersection on the list is the closest, which is usually the one we want. This
first intersection has information about what the ray hit, including the
object, face and the face's index in the object. We use the object parameter in
the next slide to change the material to a random color. The intersects record
also includes the distance and the point in world space. To show where the
object was hit, we add a small sphere to the scene using this intersection
point for its location. These are just examples, you can do whatever you like
with the intersection information you get back.