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:

Made on Mac