PDA

View Full Version : Picking with ARToolkit


lexouille
April 1st, 2005, 06:37 PM
Hi,

I want to do picking in virtual objects wich are positionned with artoolkit. The usual procedure don't work.
Do you know what is wrong in my code ?


//Function for drawing vitual objects on the right place
static void draw(double patt_trans[3][4])
{
double gl_para[16];
GLfloat mat_ambient[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash_shiny[] = {50.0};
GLfloat light_position[] = {100.0,-200.0,200.0,0.0};
GLfloat ambi[] = {0.1, 0.1, 0.1, 0.1};
GLfloat lightZeroColor[] = {0.9, 0.9, 0.9, 0.1};

argDrawMode3D();
argDraw3dCamera( 0, 0 );
glClearDepth( 1.0 );
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

argConvGlpara(patt_trans, gl_para);
glMatrixMode(GL_PROJECTION);

glPushMatrix();
glMultMatrixd( gl_para );

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

draw_objects_pick();
glPopMatrix();

glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );

}

This is the function of the exemple "simple". And I create a new one :


static void picking(double patt_trans[3][4])
{
int hits;
double gl_para[16];

GLsizei BUFF_SIZE = 512;
GLuint buffer[512];
GLint viewport[4];

glGetIntegerv(GL_VIEWPORT, viewport); //Get viewport parameters
glSelectBuffer(BUFF_SIZE, buffer); //buffer for stack of name

glRenderMode(GL_SELECT); //switch to select buffer
glInitNames();
glPushName(0);

//I found this type of code in tutorials on the web
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

gluPickMatrix(mouse_x, viewport[3]-mouse_y, 1, 1, viewport);

//They usually use here glPerspective or something like that
//But here I must use the camera coordinates
argConvGlpara(patt_trans, gl_para);
glMultMatrixd( gl_para );

draw_objects_pick(); //Draw virutal objects

glPopMatrix();

hits=glRenderMode(GL_RENDER);

printf("Nb hits = %d | ", hits);
printf("buffer : %d %d | ", (GLuint) buffer[0], (GLuint) buffer[7]);
printf("mouse_x : %d, mouse_y : %d\n", mouse_x, mouse_y);
}


ps: sorry for my english !

lexouille
April 5th, 2005, 01:11 PM
Perhaps can I reformulate my problem.
Does everybody know how drawing virtual objects without using glMultMatrixd() ? Perhaps could I use glPerspective and glTranslate, glRotate in place of this function... but I don't know how using values of the gl_para matrix.
Thanks.

lexouille
April 18th, 2005, 01:55 PM
I found the solution :-) If somebody is interested....

ffritz
April 28th, 2005, 01:41 PM
Hi.

I am also trying for a while to get the picking done, but till now it seems like that, that its picking always all the objekts that are visible in the window. But not the one i am clicking on. The Picking matrix is quite small just 3x3 pixels, that cant be the problem.

Do you maybe know what the problem might be or give me some advise to get that working?

thanx

lexouille
April 28th, 2005, 04:47 PM
Yep,

I had the same problem (picking all the objects). The problem is there is an information which is missing : the transformation matrix for the camera (called gl_cpara here).
This is this matrix you must use for the projection in the picking function.

picking function :
/////////////////////////////////////////////////////
glGetIntegerv (GL_VIEWPORT, viewport);

glSelectBuffer (BUFF_SIZE, buffer);
(void) glRenderMode (GL_SELECT);

glInitNames();
glPushName(-1);

glMatrixMode(GL_PROJECTION);
glPushMatrix ();
glLoadIdentity();

gluPickMatrix ((GLdouble) mouse_x, (GLdouble) (viewport[3] - mouse_y), 10.0, 10.0, viewport);

/////////right projection ///////////
glMultMatrixd( gl_cpara );
///////////////////////////////

glMatrixMode(GL_MODELVIEW);
glPushMatrix();

argConvGlpara(patt_trans, gl_para);
glMultMatrixd( gl_para );

drawObjectPicking();

glPopMatrix();
...
...
...
////////////////////////////////////////////////

Where can you find this matrix, gl_cpara ? In the init function.


At the end of the init function :
/////////////////////////////////////////////
...
...
...
argInit( &cparam, windowRatio, 0, 0, 0, 0 );

gCparam = cparam;

for( i = 0; i < 4; i++ )
{
gCparam.mat[1][i] = (gCparam.ysize-1)*(gCparam.mat[2][i]) - gCparam.mat[1][i];
}

argConvGLcpara( &gCparam, AR_GL_CLIP_NEAR, AR_GL_CLIP_FAR, gl_cpara );
/////////////////////////////////////////////

gCparam is a ARParam variable and gl_cpara is a global variable.

You have now a global variable which contain values of camera transformation. It will be use in place of functions like gluPerspective() with glMultMatrix().

Do you understand me ? Perhaps should I work my english... :rolleyes:

ffritz
April 28th, 2005, 08:08 PM
Hi.
Thanx for the reply. Dont worry about your English.

well, the thing is, that despite of your help I did not get the picking running yet.

Actually I am not using the gl_param thing, since I am working without the markers and dont need it. But I tryed to put it in my program to get the picking done. But still it was always picking all the objects.

The thing that I was trying before, was also about the Projection Matrix ,

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glGetIntegerv(GL_VIEWPORT,viewport); /* Get the viewport bounds */

gluPickMatrix(x,viewport[3]-y,3.0f,3.0f,viewport);

glGetDoublev(GL_PROJECTION_MATRIX, ArTMat);
glMultMatrixd(ArTMat);
printf("viewport: Position x:%d\n Position y:%d\n width: %d\n height: %d", viewport[0],
viewport[1], viewport[2], viewport[3]);


glMatrixMode(GL_MODELVIEW);
glPushMatrix();

draw();
glPopMatrix();


I tryed to get the Matrix with that and than to multiply it with the Picking matrix, also did not work.

Would be great if you maybe could help me some more in that.

Thanks

Frauke

lexouille
May 17th, 2005, 12:48 PM
Hi,

because you don't use the markers, use a glPerspective() to put your camera, and use it to perform picking.
In the picking function, you just must use the same projection like in the "draw" function.
I understand your problem, but I don't have a better solution than yours.

Alex

Leif Oppermann
September 21st, 2005, 06:14 PM
Don't know if it is still a problem, but:

1) If you were using markers, you were clearly missing a arGetTransMat()

2) this code is known to work:
// get the transformation between the marker and the real camera
arGetTransMat(&m_mymarkerinfo, m_center, m_width, m_trans);
argDrawMode3D();
argDraw3dCamera( 0, 0 );

// clip scene to mouse cursor
glMatrixMode( GL_PROJECTION );
glGetIntegerv(GL_VIEWPORT, viewport);
glGetFloatv(GL_PROJECTION_MATRIX, pmatrix);

glLoadIdentity( );
gluPickMatrix((GLdouble) mouse_x, (GLdouble) (viewport[3]-mouse_y), 1.0f, 1.0f, viewport);
glMultMatrixf(pmatrix);


// load the camera transformation matrix
glMatrixMode(GL_MODELVIEW);
argConvGlpara(m_trans, gl_para);
glLoadMatrixd( gl_para );

3) you may want to check ARGUI (http://projekt.medieninformatik.de/argui/) which was all about picking with ARToolkit

Hope this helped,
Leif

pengjm18
January 22nd, 2007, 03:42 AM
Hi Hi,

good day to you all. Sorry but may I ask is there anyone who has met problems like when you click on one virtual object, it actually selects all of the objects??

I use the simpleVRML.c in ARToolkit as an example. I really hope that someone with this experience would help me solve this problem. I can send my code if required.

Many thanks and hope to hear from you soon.

Jimmy.

flyjason
January 22nd, 2007, 07:51 AM
Hi lexouille,

From the function picking(double patt_trans[3][4])

i.e

static void picking(double patt_trans[3][4])
{
................
................
................
draw_objects_pick(); //Draw virutal objects
................
................
................
}

I would be grateful if you could post the actual implementation/coding of this function [draw_objects_pick()]. I guess it's a routine for displaying any 3d object.

I don't know if you read my last thread titled 'Integrate 3ds loader with ARToolKit', in which I was looking for a good 3ds loader to load 3d objects. Can you talk about if you are using loaders or any other way of translating 3d objects into OpenGL code?? Provide some useful links so that I can solve the problem if you can.

Would really appreciate.

Thanks

flyjason
March 12th, 2007, 10:18 PM
Hi Jimmy,

I'm also working with simpleVRML. So have you solved the problem of picking all the objects? Can you provide me with the code you have used please?

rainiou
March 28th, 2007, 09:48 PM
Hi,

I would like to use your Picking method. I had a look at nehe's tutorial, and some other ( such has my big OpenGL book) and I don't realy know why it doesn't work.

I don't use mouse to do my picking but a kind of crossair. The crossair has it position (0,0) at the begining (center of the frame).

My question is here, as you use your mouse to select element does the x_mouse & y_mouse have pixel coordinates? I mean in a frame of 240*320 does the x_mous has a position between 0 and 240?

I think I answered my question, but just want to be sure.

Thanks,
Henry

rainiou
March 29th, 2007, 01:42 AM
In fact I was right :) thanks to the previous posts they were quite efficient, I am almoste done with this!