PDA

View Full Version : Help: Selecting verticies using the line equation



Kev~
07-02-2002, 02:50 AM
Grrr, I am trying to do 'proper' seection as opposed to the OpenGL selection i have been using. I am using the following code to select a vertex in the scene. the problem is that i have 4 views all snaped to different positions (front,left,side etc) and i get odd lengths back when i am selecting from a view that is snaped to a camera angle other than z is into the screen and y is up.

can anyone suggest what is happening?

code:

int iViewport[4];
double dModelViewMatrix[16];
double dProjectionMatrix[16];
double d1x,d1y,d1z,d2x,d2y,d2z;

m_cGLRC.Begin();

glGetDoublev(GL_MODELVIEW_MATRIX,dModelViewMatrix) ;
glGetDoublev(GL_PROJECTION_MATRIX,dProjectionMatri x);
glGetIntegerv(GL_VIEWPORT,iViewport);

int iY = iViewport[3] - point.y;

gluUnProject(point.x,iY,0.0,dModelViewMatrix,dProj ectionMatrix,iViewport,&d1x,&d1y,&d1z);
gluUnProject(point.x,iY,1.0,dModelViewMatrix,dProj ectionMatrix,iViewport,&d2x,&d2y,&d2z);

m_cGLRC.End();

C3DPoint cScale;
pDoc->m_cModel.GetScale(cScale);

for(int i=0; i<pDoc->m_cModel.m_cPoints.GetSize(); i++)
{
CSTAPoint *pPoint = pDoc->m_cModel.m_cPoints.GetAt(i);

float ox = pPoint->pt[0] * cScale.pt[0];
float oy = pPoint->pt[1] * cScale.pt[1];
float oz = pPoint->pt[2] * cScale.pt[2];

float r = (oz - d1z) / (d2z - d1z);
float px = d1x + r * (d2x - d1x);
float py = d1y + r * (d2y - d1y);
float pz = oz;

TRACE("POINT %f,%f,%f\nMOUSE %f,%f,%f\n",ox,oy,oz,px,py,pz);

C3DVector v1(ox,oy,oz);
C3DVector v2(px,py,pz);
C3DVector vDist = C3DTools::Vector(v1,v2);
float fLen = C3DTools::Magnitude(vDist);

TRACE("LEN: %f\n\n", fLen);

if(fLen < 0.01)
{
pDoc->SelectGeometry(pPoint,false);
}
}

Kev~
07-03-2002, 12:57 AM
ok, so the problem is in my calculation. if its in the xy plane then i have to do:

float r = (oz - d1z) / (d2z - d1z);
float px = d1x + r * (d2x - d1x);
float py = d1y + r * (d2y - d1y);
float pz = oz;

and if its in the xz plane i have to do:
float r = (oy - d1y) / (d2y - d1y);
float px = d1x + r * (d2x - d1x);
float py = oy;
float pz = d1z + r * (d2z - d1z);

this seems like a bit of a kludge to me. is there a propper way to do it - so that it will work independently of the orientation?

anyone? please...?

Kev~
07-03-2002, 03:08 AM
sorted.

for anyone thats interested here is the code:

==============
gluUnProject(point.x,iY,0.0,dModelViewMatrix,dProj ectionMatrix,iViewport,&d1x,&d1y,&d1z);
gluUnProject(point.x,iY,1.0,dModelViewMatrix,dProj ectionMatrix,iViewport,&d2x,&d2y,&d2z);

C3DPoint cScale;
pDoc->m_cModel.GetScale(cScale);

C3DVector vLine[2];
vLine[0].Set(d1x,d1y,d1z);
vLine[1].Set(d2x,d2y,d2z);

for(int i=0; i<pDoc->m_cModel.m_cPoints.GetSize(); i++)
{
CSTAPoint *pPoint = pDoc->m_cModel.m_cPoints.GetAt(i);

float ox = pPoint->pt[0] * cScale.pt[0];
float oy = pPoint->pt[1] * cScale.pt[1];
float oz = pPoint->pt[2] * cScale.pt[2];

C3DVector v1(ox,oy,oz);

float fDist1 = C3DTools: http://www.opengl.org/discussion_boards/ubb/biggrin.gifistance(vLine[0],vLine[1]);
float fDist2 = C3DTools: http://www.opengl.org/discussion_boards/ubb/biggrin.gifistance(vLine[0],v1);

float v = fDist2/fDist1;
float ux = d1x + v * (d2x - d1x);
float uy = d1y + v * (d2y - d1y);
float uz = d1z + v * (d2z - d1z);

C3DVector v2(ux,uy,uz);

float fMissedItByHowMuch = C3DTools: http://www.opengl.org/discussion_boards/ubb/biggrin.gifistance(v1,v2);

if(fMissedItByHowMuch < 0.01)
{
pDoc->SelectGeometry(pPoint,false);
}
}