UV Picking
"Picking" is the process of looking into the 3D world and getting information about the geometry that intersects a ray cast into the world. For instance, it's useful for finding out what polygons a laser beam hits, or what polygon the user just clicked. (In the case of finding where the user clicked, the system just fires a ray into the 3D world from the mouse location on the camera plane in the direction of view.)
Picking is done using the modelsUnderRay and
modelsUnderLoc commands. They can either return a simple
list of models, or it can return detailed information about each
intersection, such as the actual point of intersection, the surface
normal at the point, and the UV coordinates of the intersection.
Most of the time, it's sufficient to know which model the ray hits, but sometimes, you need to know exactly where on the model's texture the ray hits. For instance, if you are using 3D Flash Sprites, your polygons will likely have alpha-channeled areas that you don't want to register as a "hit". Or maybe you need to know where on the texture the user clicks to, say, have a monster get damaged in the head or the body.
You might think that the UV coordinates returned by the modelsUnderRay
and modelsUnderLoc commands provide you with this, but they
do not. The UV coordinates they return is a special UV system for mapping
onto that particular triangular polygon. If you want to extract the
actual texture UV coordinates, you have some math to do.
Luckily, James Newton has released code that solves exactly this
problem. It takes a property list like that
returned by the modelsUnderRay or modelsUnderLoc
in #detailed mode, and returns the UV texture coordinate
point of the intersection. You can then use getPixel on
your texture to, say, find out whether the ray went through a transparent
area of the texture, or do other computations.
Here's the code: