View Full Version : Ray Picking and Normal To Plane problem..

12-26-2002, 01:45 AM
Hello to everyone, i've got a little problem (i hope) in my opengl cad application... i'm using ray picking algho to select meshes from my opengl windows when user clicks on them... the problem is that if i load files from the disk (also plane definition for each object face) it works perfectly but if i try to compute plane from my face data nothing works... here is the code i use

BuildPlaneFromPoly : computes 3 points on the plane, normal and distance

GetHitByRay : returns face hit by the ray (if any)

void BuildPlaneFromPoly(SFACE *sFace)
CV3 v1, v2, v3;

sFace->vPlanePts[0] = sFace->sFaceVertices[2];
sFace->vPlanePts[1] = sFace->sFaceVertices[1];
sFace->vPlanePts[2] = sFace->sFaceVertices[0];

v1 = sFace->vPlanePts[0] - sFace->vPlanePts[1];
v2 = sFace->vPlanePts[1] - sFace->vPlanePts[2];
v3 = sFace->vPlanePts[1];
/*v1 = sFace->vPlanePts[0] - sFace->vPlanePts[1];
v2 = sFace->vPlanePts[2] - sFace->vPlanePts[1];
v3 = sFace->vPlanePts[1];
/*v1 = sFace->vPlanePts[1] - sFace->vPlanePts[0];
v2 = sFace->vPlanePts[2] - sFace->vPlanePts[0];
v3 = sFace->vPlanePts[0];*/

sFace->sFacePlane.vNormal = v1.Cross(v2);

sFace->sFacePlane.fDist = v3.Dot(sFace->sFacePlane.vNormal);

SFACE *GetHitByRay(CBRUSH *pBrush,CV3 vRay,CV3 vOrigin,CV3 vDir,float &dist)
SFACE *retface = NULL;
SFACE *pFace = NULL;

float fP1DotPn = 0.0f;
float fP2DotPn = 0.0f;
float frac = 0.0f;

CV3 rayPoint1 = vOrigin;
CV3 rayPoint2 = vRay;

for (int k = 0; k < pBrush->m_NumFaces; k++)
pFace = &amp;pBrush->s_Faces[k];

fP1DotPn = rayPoint1.Dot(pFace->sFacePlane.vNormal) - pFace->sFacePlane.fDist;
fP2DotPn = rayPoint2.Dot(pFace->sFacePlane.vNormal) - pFace->sFacePlane.fDist;

We dot product the two points from the ray to the poly plane normal
to see if there is an intersection. If fP1DotPn * fP2DotPn is >= 0.0f
then there was no intersection. To optimize calculation a bit, we
check to see if both variables are positive or negative instead of
doing the multiplication
if(fP1DotPn >= 0.0f &amp;&amp; fP2DotPn >= 0.0f)
dist = 0;
return NULL;

if(fP1DotPn <= 0.0f &amp;&amp; fP2DotPn <= 0.0f)

// find intersection point
frac = fP1DotPn / (fP1DotPn - fP2DotPn);
if(fP1DotPn > 0)
retface= pFace;

rayPoint1.x = rayPoint1.x + frac *(rayPoint2.x - rayPoint1.x);
rayPoint1.y = rayPoint1.y + frac *(rayPoint2.y - rayPoint1.y);
rayPoint1.z = rayPoint1.z + frac *(rayPoint2.z - rayPoint1.z);
rayPoint2.x = rayPoint1.x + frac *(rayPoint2.x - rayPoint1.x);
rayPoint2.y = rayPoint1.y + frac *(rayPoint2.y - rayPoint1.y);
rayPoint2.z = rayPoint1.z + frac *(rayPoint2.z - rayPoint1.z);

// find where ray clipped to poly
rayPoint1 -= vOrigin;
fP1DotPn = rayPoint1.Dot(vDir);

dist = fP1DotPn;

return retface;

12-26-2002, 09:44 AM
Up :P No one knows about this craP?

12-27-2002, 12:24 PM
I've same problem

12-27-2002, 09:38 PM
sFace->sFacePlane.fDist = v3.Dot(sFace->sFacePlane.vNormal);

Plane equation: ax + by +cz + d = 0

d = - ((x,y,z) dot (a,b,c))
How's your winding? ccw or cw?

12-27-2002, 10:21 PM
Originally posted by roffe:
Plane equation: ax + by +cz + d = 0

d = - ((x,y,z) dot (a,b,c))
How's your winding? ccw or cw?

So the missing bit would be the -ve (ie. you've got

d = ((x,y,z) dot (a,b,c))

12-28-2002, 05:07 AM
My winding is ccw! btw, i tried to find the distance also with the minus but.. didnt worked...

12-28-2002, 09:12 PM
So , you say that "when loading from a file" it works fine, but why? Well as I see it ,only you can answer that. Here are some debug tips: When loading or creating "planes", fprintf all planes and try to figure out how they differ. Using a source level debugger, try stepping through your code. Maybe the error is somewhere else.

12-29-2002, 05:13 AM
When when loading a map i load plane points directly from the file.. that's why i guess error is in that function, because when i create them manually i call that function to generate plane points! I've already debugged code and that's what i've found out that values i get from that func are ok but randomly swapped (i.e. if a plane point had 8 as x in a face, in the loaded file it is y or smth else for the same face) (<-- tests are done with an object with same size/position) ... huh... weird...