Get UV for a mouse click

Jul 26, 2011 at 2:59 AM
Edited Jul 26, 2011 at 3:04 AM

I have a mesh which is basically a sphere with a texture map and I'm trying to get the UV at the point where the user clicks on it.  It looks like there's a lower-level Intersects method that does the trick but I'm not sure how to get to it.  FYI, I'm using an ASE mesh.  Any ideas?

Jul 26, 2011 at 6:24 PM

I discovered how to get the Geometry using GetAssetParts and then Intersects but I think I read in another thread that the face UV is just the local intersection point and nothing to do with the texture UV.

So I guess now I need to see if I can find the texture coordinates given the face index and coordinates...


Jul 26, 2011 at 7:14 PM

Closer. I used GeometryContext.GetDetailLevel and GetTextureCoordinates to get the array of texture UVs.  Then face.DiffuseA/B/C to peek into the array and get the texture UVs for the corners of the face.

Now I just need to figure out how FaceUV is used.  I looks like it's Dot/Cross product of an Edge.  Please don't make me do math!

Jul 30, 2011 at 7:06 PM

I do not have an answer to your question, you're way ahead of me. But I have been trying to figure out how to get to the mesh vertices after I load a model from an SAE file and it sounds like you got past that. Can you share how you get the Geometry and GeometryContext from a Mesh? When I call GetAssetParts() on the Mesh I get an empty array. I am using the Silverlight 5 bersion, I wonder if it is something not yet implemented there. Thanks for any help you have on this.

Coordinator
Aug 8, 2011 at 5:13 PM

The manipulation events has this. But it would be a good idea to actually have this information on all Mouse events.

Coordinator
Aug 8, 2011 at 5:13 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Aug 8, 2011 at 5:37 PM

I never noticed FaceU/V in the ManipulationDeltaEventArgs.  I didn't think they were used anywhere.  I needed the face for a regular MouseLeftButtonDown.

In any case I till needed to turn FaceU/V into something useful.  Here's what I came up with:

double x1 = MainCanvas.Width * tex[face.DiffuseA].U;
double y1 = MainCanvas.Height * tex[face.DiffuseA].V;
double x2 = MainCanvas.Width * tex[face.DiffuseB].U;
double y2 = MainCanvas.Height * tex[face.DiffuseB].V;
double x3 = MainCanvas.Width * tex[face.DiffuseC].U;
double y3 = MainCanvas.Height * tex[face.DiffuseC].V;

double MX = x1 + ((x3 - x1) / 2.0);
double MY = y1 + ((y3 - y1) / 2.0);

double slopeU = (y3 - y1) / (x3 - x1);

double UX = MX + ((x2 - MX) * faceU);
double UY = MY + ((y2 - MY) * faceU);

double NX = x1 + ((x2 - x1) / 2.0);
double NY = y1 + ((y2 - y1) / 2.0);

double slopeV = (y2 - y1) / (x2 - x1);

double VX = NX + ((x3 - NX) * faceV);
double VY = NY + ((y3 - NY) * faceV);

double BU, BV;
double rx, ry;

BU = UY - (UX * slopeU);
BV = VY - (VX * slopeV);

// rx, ry are the Texture UV coordinates of the mouse click
rx = (BV - BU) / (slopeU - slopeV);
ry = (slopeU * rx) + BU;

FaceU/V appear to be points perpendicular to edges 1 and 2.  So I just find the slopes of the edges and interpolate.  Note this code snippet doesn't handle bad slopes.

I would rather FaceU/V be the actual texture UV in the event but I can also see where the physical offsets could be useful.


Coordinator
Aug 8, 2011 at 7:26 PM

Thanks.

Very good point. I'll have to go through in details for the mouse events and provide all the information needed. I think also in some cases, just having the raw pixel data for the texture at that particular location could be useful, and its pretty easy internally getting that information - at least as some kind of helper for getting that info.