# Ray Picking - need help

This topic is 2341 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

I'm trying to implement ray picking algorithm, but it looks like it doesn't work as it should.
If I get it right, the ray should starts from the near view, go straight to the mouse cursor, and then ends at the far view.

 const Matrix4& inverseVP = (pCamera->mProjection * pCamera->mView()).inverse(); float NewX = (2.0f * MouseX/ pCamera->fWidth) - 1.0f; float NewY = 1.0f - (2.0f * MouseY/pCamera->fHeight); vec3 nearPoint(NewX, NewY, -1.f ); vec3 midPoint (NewX, NewY, 0.0f); vec3 rayOrigin, rayTarget; m_WorldPosition = inverseVP * (nearPoint); rayTarget = inverseVP * (midPoint); m_Direction = rayTarget - rayOrigin; m_Direction.normal(); m_WorldPosition = rayOrigin; 

Draw the ray: ( with GL_LINES )
 vec3 p0 = m_WorldPosition; vec3 p1 = m_WorldPosition + pCamera->fZFar*m_Direction; 

I have tried other algorithms which uses tan(FOV/PI/360) but got the same results.

Any help would be great.

tnx

Anyone?

##### Share on other sites
If I get it right, the ray should starts from the near view, go straight to the mouse cursor, and then ends at the far view.
You should see nothing except possibly a 1 pixel dot under some circumstances.

 const Matrix4& inverseVP = (pCamera->mProjection * pCamera->mView()).inverse(); float NewX = (2.0f * MouseX/ pCamera->fWidth) - 1.0f; float NewY = 1.0f - (2.0f * MouseY/pCamera->fHeight); vec3 nearPoint(NewX, NewY, -1.f ); vec3 midPoint (NewX, NewY, 0.0f); vec3 rayOrigin, rayTarget; m_WorldPosition = inverseVP * (nearPoint); rayTarget = inverseVP * (midPoint); m_Direction = rayTarget - rayOrigin; m_Direction.normal(); m_WorldPosition = rayOrigin; 
It looks like you're converting the mouse positions to normalized device coordinates, then transforming by the inverse view projection matrix. Did you take into account the perspective divide between clip coordinates and normalized device coordinates?

I usually prefer getting the world space camera position and basis vectors, and then using those to figure out world space positions. I find it makes the math more straightforward.

This line is suspect: "m_WorldPosition = inverseVP * (nearPoint);"
It looks like it should be: "rayOrigin = inverseVP * (nearPoint);"
Otherwise many lines in your code deal with an uninitialzed variable.

[quote name='masterbubu']Anyone?[/quote] Impatient, are we? Edited by scniton

##### Share on other sites
Hi,

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

### [background=rgb(250, 251, 252)]Did you take into account the perspective divide between clip coordinates and normalized device coordinates[/background][/font] [/quote] Doesn't the projection multiplication do that? Do u mean that I need to divide by Z coord? About the uninitialized variable, I noticed after posting, so tnx for that [color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][background=rgb(250, 251, 252)][/background][/font][color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][background=rgb(250, 251, 252)] Impatient, are we? [/background][/font] [/quote] Sorry, I have short deadline for that.

##### Share on other sites

[background=rgb(250, 251, 252)]Did you take into account the perspective divide between clip coordinates and normalized device coordinates[/background]

Doesn't the projection multiplication do that?
Do u mean that I need to divide by Z coord?
[/quote]
Usually, it doesn't. A matrix multiplication is basically a sum of a few dot products, which means, it can't divide something. If your * operator internally lifts a vec3 to vec4 and eventually projects it back, then your lucky. If it only use the upper-left 3x3 part of your matrix, well - then you're not.
Just to be safe, I'd do it myself:

const Matrix4& inverseVP = (pCamera->mProjection * pCamera->mView()).inverse(); float NewX = (2.0f * MouseX/ pCamera->fWidth) - 1.0f; float NewY = 1.0f - (2.0f * MouseY/pCamera->fHeight); vec4 nearPoint(NewX, NewY, -1.f, 1); // lift from cartesian to homogeneous coodinates. vec4 midPoint (NewX, NewY, 0.0f, 1); // lift from cartesian to homogeneous coodinates. vec4 rayOrigin, rayTarget; rayOrigin = inverseVP * (nearPoint); rayTarget = inverseVP * (midPoint); rayOrigin /= rayOrigin.w; // project from homogeneous coordinates to cartesian. rayOrigin /= rayOrigin.w; // project from homogeneous coordinates to cartesian. m_Direction = rayTarget.xyz() - rayOrigin.xyz(); // only use the xyz components m_Direction.normal(); // does this method modify m_Direction or should it perhaps be: m_Direction = m_Direction.normal(); m_WorldPosition = rayOrigin;

Best regards!

##### Share on other sites
Hi,

tnx for the help.
I have tried you suggestion.
In order to draw the ray, I draw a line from the m_WorldPostion to m_WorldPostion + t* m_Direction. Where t = Z far of the camera.
The ray appears good on the 3D scene, however, it does not seems to cross the scene, so the collisions does not works.

##### Share on other sites
So the ray is placed in the scene just fine but no intersection is detected?
It appears to me that we are on a good way. The first part seems to work.

Which intersection test do you use? Here is some very nice overview of intersection algorithms. I usually use the test of Möller and Trumbore for ray tests with triangles and try to cull objects by their bounding volumes. For picking this used to be fast enough for me. (If you need more speed you could keep some acceleration data structure to get faster ray traversals, e.g. bounding volume hierarchies, Kd trees etc.)

A frequent bug is to have the ray and the geometry in different spaces, e.g. the ray is in world or view space and the geometry is in object space. It's the easiest to transform the ray into the space of the model and then do the test there. This can be done by transforming the ray's position (w=1) and the ray's direction (w=0) with the inverse world matrix (or inverse worldview matrix respectively).

Best regards! Edited by Tsus

1. 1
2. 2
Rutin
19
3. 3
khawk
18
4. 4
A4L
14
5. 5

• 12
• 16
• 26
• 10
• 44
• ### Forum Statistics

• Total Topics
633767
• Total Posts
3013734
×