Selecting vertices

Hi there!

I’m trying to build a model editor for my game project, mainly to assign vertices to bones and such. However, I find it difficult to achieve a way of selecting vertices using the mouse. What I want is a way to find which vertices are selected using a sweep selection.
is there a way to retrieve the screen coordinates of a vertex, f.ex?

TIA

For selecting vertices, use glProject to project to 2D coordinates (xo,yo) then calculate which vertice is closer to mouse (x,y) coordinates using distance:

d=sqr((x-xo)^2+(y-yo)^2)

be careful with y coordinate value because “max y” of Windows corresponds to “min y” of OpenGL.

i think you sould try to avoid using sqrt per vertex, maybe you can use a treshold and every vertex found in that treshold that “surrounds” the mouse is selected. and i think you can and should disable this treshold when the user have cliked and dragged to select a lot of vertices.
do i make myself clear?

Clarification - you are trying to use a rubber-banding box sort of idea to select all of the points contained in it? Or are you trying to select individual points by clicking on/near them?

If you are talking about the former, then there are a couple ways that I can think of…

[1] Flatten the image to 2d, calculate the percentages of the corners of the selection area, convert to GL coordinates, select points in that range.

[2] Use the feedback buffer, but instead of the usual method of setting the matrix based off of the mouse position (give or take a few pixels), set it using the corners of the selection area.

I’m not sure if [2] is actually possible, but it’s what I was hoping to do later on when I get to implementing object selection inside a region. So let me know if you try it…

Chris

Yes, a rubber-band style solution would be preferrable… But yes, I do believe that glUnProject will do the trick for me.
I’ll post any progress here, and thanks in the meantime!

Hi there!
I implemented the picking with gluProject and i worked fine. Also the performance is ok. I also tried gluUnProject, which is much faster, but the coordinates are not correct. Has someone experienced this problem??
Juergen

Yes, why of course - gluUnProject does the exact opposite of gluProject. With UNproject, you take 2D coordinates and make them 3D, and with Project, you take 3D and make them 2D.

How did you do it. In my case i have double buffer and the following code.
glGetDoublev(GL_MODELVIEW_MATRIX,modelmatrix);
glGetDoublev(GL_PROJECTION_MATRIX,projectionmatrix);
glGetIntegerv(GL_VIEWPORT,viewport);
glReadBuffer(GL_BACK);
glReadPixels((GLdouble) xRot_old, (GLdouble) (viewport[3]-yRot_old-1), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fWindowZ);
workproject=gluUnProject ((GLdouble) xRot_old, (GLdouble) (viewport[3]-yRot_old-1), fWindowZ, modelmatrix,projectionmatrix,viewport, &winX, &winY, &winZ);
for (int index=0;index<numVertices;index++){
distance = sqrt(sqr(vertices[index3 ]-winX)+sqr(vertices[index3+1]-winY)+sqr(vertices[index*3+2]-winZ));
Some times it workes fine, sometimes not. So, i am not shure whats the problem.
Juergen

Aye, using gluProject to test every vertex is too slow.

Why not use the GL selection buffer?

Right now you’re probably thinking “but K, trying to select each tiny vertex by clicking on it is too hard”. Right on, however, faces are easy to select. So draw all the faces into the selection buffer and use that to narrow down the vertices you have to test with gluProject.

Well, here it is, my code:

void bbMarquee::CalculateNewProjections (bbMesh3D theMesh)

{

    int i;

    GLdouble		stolenModelMatrix [16];

    GLdouble		stolenProjMatrix [16];

    GLint		stolenViewPort [4];

    

    glGetDoublev (GL_MODELVIEW_MATRIX, stolenModelMatrix);

    glGetDoublev (GL_PROJECTION_MATRIX, stolenProjMatrix);

    glGetIntegerv (GL_VIEWPORT, stolenViewPort);

    for (i = 0; i < theMesh.numOfVertices; i++)

    {

        double tempX, tempY, tempZ;

        gluProject (	theMesh.transVertices[i].xPos,

                        theMesh.transVertices[i].yPos,

                        theMesh.transVertices[i].zPos,

                        stolenModelMatrix,

                        stolenProjMatrix,

                        stolenViewPort,

                        &tempX,

                        &tempY,

                        &tempZ);

        this->vertexProjections[i].xPos = tempX;

        this->vertexProjections[i].yPos = tempY;

        this->vertexProjections[i].zPos = tempZ;

}

}

gotta agree with the super-K on this one the selection buffer is a far better bet u can use gluPickMatrix(…) which chooses an area. ive used this before to let the user drag + slect 1000’s of vertices onscreen

Wow! If that’s faster, then how is it done? Drool