PDA

View Full Version : 3D Picking



04-06-2003, 05:49 PM
I'm having trouble picking objects in my 3D world, and I was wondering if someone could point me into the correct direction. The first segment of the code is what draws the pickable objects and the second part is my picking routine which does absolutely nothing at this current moment. Most of the functions should be self explanatory... but the basic setup of this program is that I have a dynamic array of pointers p[i] which holds pointers to pickable objects that can be dynamically created and deleted in the scene. ObjectHolder is another array that basically does the same thing... I don't remember why I put it in there, but I haven't changed it as of yet.

// draw the pickable items
//
// used for both the drawing routine and for
// picking routine
static void
drawPickable()
{
if (objectCount > 0)
{
// clear the name stack
glInitNames();

for (int i = 0; i < objectCount; i++)
{
// it may have been deleted, so check
if (objectHolder[i] != -1)
{
glPushName(p[i]->getId());
p[i]->display();
glPopName();
}
}
}
}

// this is our picking routine
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && mouseMode == 0)
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

// Set viewport to be a 10x10 pixel area around cursor
// remember to convert y for origin top left vs. bottom left
GLint viewport[4];
glGetIntegerv (GL_VIEWPORT, viewport);

// set viewport to be a 10x10 window around cursor
gluPickMatrix((GLdouble)x, (GLdouble)y, 10, 10, viewport);
gluOrtho2D(0, (GLfloat)windowDim, 0, (GLfloat)windowDim);

// designate buffer for hits
GLuint nameBuffer[BUFSIZE];
glSelectBuffer(BUFSIZE, nameBuffer);

// "draw" in GL_SELECT mode
glRenderMode(GL_SELECT);
drawPickable();

// restore original projection
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glutSwapBuffers();

// return to GL_RENDER and decode hits
int nhits = glRenderMode(GL_RENDER);

cout << nhits;

// iterate over buffer and pick
int ibuf = 0; // iterate over whole buffer
int ihit; // iterate over the hits
int ipart; // iterate over parts within a hit
int nparts;
int mindepth;
int maxdepth;
int name = -1;

for (ihit = 0; ihit < nhits; ihit++)
{
nparts = nameBuffer[ibuf++];
mindepth = nameBuffer[ibuf++];
maxdepth = nameBuffer[ibuf++];

for (ipart = 0; ipart < nparts; ipart++)
{
name = nameBuffer[ibuf++];
cout << " part " << name << endl;
}
}

// goes through available objects and sees if we
// have a hit
if (objectCount > 0 && name != -1)
{
for (int i = 0; i < objectCount; i++)
{
if (name == p[i]->getId())
cout << "i: " << i << endl;
}
}

}

Any help is most appreciated.
Thanks in advance

04-06-2003, 06:10 PM
Don't even bother replying... figured out my own mistakes

cheers