00001 #ifdef _WIN32
00002 # include <windows.h>
00003 #endif
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include <math.h>
00008
00009 #ifndef __APPLE__
00010 # include <GL/glut.h>
00011 #else
00012 # include <GLUT/glut.h>
00013 #endif
00014 #include <AR/gsub.h>
00015 #include <AR/param.h>
00016 #include <AR/matrix.h>
00017 #include <AR/ar.h>
00018 #include <AR/video.h>
00019 #include <AR/arMulti.h>
00020
00021 #define TOUCHED 1
00022 #define NOT_TOUCHED -1
00023 #define TARGET_NUM 5
00024
00025 #include "paddle.h"
00026
00027
00028
00029 #ifdef _WIN32
00030 char *vconf = "Data\\WDM_camera_flipV.xml";
00031 #else
00032 char *vconf = "";
00033 #endif
00034
00035
00036 typedef struct {
00037 int id;
00038 int state;
00039 float pos[3];
00040 } targetInfo;
00041
00042 targetInfo myTarget[TARGET_NUM];
00043
00044 int draw_paddle( ARPaddleInfo *paddleInfo );
00045
00046 int xsize, ysize;
00047 int thresh = 100;
00048 int count = 0;
00049
00050 char *cparam_name = "Data/camera_para.dat";
00051 ARParam cparam;
00052
00053 char *config_name = "Data/multi/marker.dat";
00054 ARMultiMarkerInfoT *config;
00055
00056
00057 int marker_flag[AR_SQUARE_MAX];
00058 ARPaddleInfo *paddleInfo;
00059 char *paddle_name = "Data/paddle_data";
00060
00061 GLfloat light_position[] = {100.0,-200.0,200.0,0.0};
00062 GLfloat ambi[] = {0.1, 0.1, 0.1, 0.1};
00063 GLfloat lightZeroColor[] = {0.9, 0.9, 0.9, 0.1};
00064
00065 static void init(void);
00066 static void cleanup(void);
00067 static void keyEvent( unsigned char key, int x, int y);
00068 static void mainLoop(void);
00069 static void draw( targetInfo myTarget, double BaseTrans[3][4]);
00070 int drawGroundGrid( double trans[3][4], int divisions, float x, float y, float height);
00071 static int checkCollision(float Pos1[],float Pos2[], float range);
00072 static void findPaddlePosition(float curPaddlePos[], double card_trans[3][4],double base_trans[3][4]);
00073
00074
00075 int main(int argc, char **argv)
00076 {
00077
00078 glutInit(&argc, argv);
00079 init();
00080
00081 arVideoCapStart();
00082
00083 argMainLoop( NULL, keyEvent, mainLoop );
00084
00085 return 0;
00086 }
00087
00088
00089 static void keyEvent( unsigned char key, int x, int y)
00090 {
00091
00092 if( key == 0x1b ) {
00093 printf("*** %f (frame/sec)\n", (double)count/arUtilTimer());
00094 cleanup();
00095 exit(0);
00096 }
00097
00098
00099 if( key == 't' ) {
00100 printf("Enter new threshold value (default = 100): ");
00101 scanf("%d",&thresh); while( getchar()!='\n' );
00102 printf("\n");
00103 }
00104
00105
00106 if( key == 'd' ) {
00107 printf("*** %f (frame/sec)\n", (double)count/arUtilTimer());
00108 arDebug = 1 - arDebug;
00109 if( arDebug == 0 ) {
00110 glClearColor( 0.0, 0.0, 0.0, 0.0 );
00111 glClear(GL_COLOR_BUFFER_BIT);
00112 argSwapBuffers();
00113 glClear(GL_COLOR_BUFFER_BIT);
00114 argSwapBuffers();
00115 }
00116 count = 0;
00117 }
00118 }
00119
00120
00121 static void mainLoop(void)
00122 {
00123 ARUint8 *dataPtr;
00124 ARMarkerInfo *marker_info;
00125 int marker_num;
00126 float curPaddlePos[3];
00127 int i;
00128 double err;
00129
00130
00131 if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
00132 arUtilSleep(2);
00133 return;
00134 }
00135
00136 if( count == 0 ) arUtilTimerReset();
00137 count++;
00138
00139
00140 if( arDetectMarkerLite(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
00141 cleanup();
00142 exit(0);
00143 }
00144
00145 argDrawMode2D();
00146 if( !arDebug ) {
00147 argDispImage( dataPtr, 0,0 );
00148 }
00149 else {
00150 argDispImage( dataPtr, 1, 1 );
00151 if( arImageProcMode == AR_IMAGE_PROC_IN_HALF )
00152 argDispHalfImage( arImage, 0, 0 );
00153 else
00154 argDispImage( arImage, 0, 0);
00155
00156 glColor3f( 1.0, 0.0, 0.0 );
00157 glLineWidth( 1.0 );
00158 for( i = 0; i < marker_num; i++ ) {
00159 argDrawSquare( marker_info[i].vertex, 0, 0 );
00160 }
00161 glLineWidth( 1.0 );
00162 }
00163 arVideoCapNext();
00164
00165 for( i = 0; i < marker_num; i++ ) marker_flag[i] = 0;
00166
00167
00168 paddleGetTrans(paddleInfo, marker_info, marker_flag,
00169 marker_num, &cparam);
00170
00171
00172 glClearDepth( 1.0 );
00173 glClear(GL_DEPTH_BUFFER_BIT);
00174
00175
00176 if( paddleInfo->active ){
00177 draw_paddle( paddleInfo);
00178 }
00179
00180
00181 if( (err=arMultiGetTransMat(marker_info, marker_num, config)) < 0 ) {
00182 argSwapBuffers();
00183 return;
00184 }
00185
00186
00187 if(err > 100.0 ) {
00188 argSwapBuffers();
00189 return;
00190 }
00191
00192
00193 drawGroundGrid( config->trans, 20, 150.0f, 105.0f, 0.0f);
00194
00195
00196 findPaddlePosition(curPaddlePos, paddleInfo->trans, config->trans);
00197
00198
00199 for(i=0;i<TARGET_NUM;i++){
00200 myTarget[i].state = NOT_TOUCHED;
00201 if(checkCollision(curPaddlePos, myTarget[i].pos, 20.0f))
00202 {
00203 myTarget[i].state = TOUCHED;
00204 fprintf(stderr,"touched !!\n");
00205 }
00206 }
00207
00208
00209 for(i=0;i<TARGET_NUM;i++){
00210 draw(myTarget[i],config->trans);
00211 }
00212
00213 argSwapBuffers();
00214 }
00215
00216 static void init( void )
00217 {
00218 ARParam wparam;
00219 int i;
00220
00221
00222 if( arVideoOpen( vconf ) < 0 ) exit(0);
00223
00224 if( arVideoInqSize(&xsize, &ysize) < 0 ) exit(0);
00225 printf("Image size (x,y) = (%d,%d)\n", xsize, ysize);
00226
00227
00228 if( arParamLoad(cparam_name, 1, &wparam) < 0 ) {
00229 printf("Camera parameter load error !!\n");
00230 exit(0);
00231 }
00232 arParamChangeSize( &wparam, xsize, ysize, &cparam );
00233 arInitCparam( &cparam );
00234 printf("*** Camera Parameter ***\n");
00235 arParamDisp( &cparam );
00236
00237
00238 if( (paddleInfo = paddleInit(paddle_name)) == NULL ) {
00239 printf("paddleInit error!!\n");
00240 exit(0);
00241 }
00242 printf("Loaded Paddle File\n");
00243
00244 if( (config = arMultiReadConfigFile(config_name)) == NULL ) {
00245 printf("config data load error !!\n");
00246 exit(0);
00247 }
00248 printf("Loaded Multi Marker File\n");
00249
00250
00251 for (i=0;i<TARGET_NUM;i++){
00252 myTarget[i].pos[0] = 50.0*i;
00253 myTarget[i].pos[1] = -50.0*i;
00254 myTarget[i].pos[2] = 50.0*i;
00255 myTarget[i].state = NOT_TOUCHED;
00256 }
00257
00258
00259 argInit( &cparam, 1.0, 0, 0, 0, 0 );
00260 }
00261
00262
00263 static void cleanup(void)
00264 {
00265 arVideoCapStop();
00266 arVideoClose();
00267 argCleanup();
00268 }
00269
00270
00271 static void findPaddlePosition(float curPaddlePos[], double card_trans[3][4],double base_trans[3][4])
00272 {
00273 int i,j;
00274
00275 ARMat *mat_a, *mat_b, *mat_c;
00276 double x, y, z;
00277
00278
00279 mat_a = arMatrixAlloc( 4, 4 );
00280 mat_b = arMatrixAlloc( 4, 4 );
00281 mat_c = arMatrixAlloc( 4, 4 );
00282 for( j = 0; j < 3; j++ ) {
00283 for( i = 0; i < 4; i++ ) {
00284 mat_b->m[j*4+i] = base_trans[j][i];
00285 }
00286 }
00287 mat_b->m[3*4+0] = 0.0;
00288 mat_b->m[3*4+1] = 0.0;
00289 mat_b->m[3*4+2] = 0.0;
00290 mat_b->m[3*4+3] = 1.0;
00291 for( j = 0; j < 3; j++ ) {
00292 for( i = 0; i < 4; i++ ) {
00293 mat_a->m[j*4+i] = card_trans[j][i];
00294 }
00295 }
00296 mat_a->m[3*4+0] = 0.0;
00297 mat_a->m[3*4+1] = 0.0;
00298 mat_a->m[3*4+2] = 0.0;
00299 mat_a->m[3*4+3] = 1.0;
00300 arMatrixSelfInv( mat_b );
00301 arMatrixMul( mat_c, mat_b, mat_a );
00302
00303
00304 x = mat_c->m[0*4+3];
00305 y = mat_c->m[1*4+3];
00306 z = mat_c->m[2*4+3];
00307
00308 curPaddlePos[0] = x;
00309 curPaddlePos[1] = y;
00310 curPaddlePos[2] = z;
00311
00312 printf("Position: %3.2f %3.2f %3.2f\n",x,-y,z);
00313
00314 arMatrixFree( mat_a );
00315 arMatrixFree( mat_b );
00316 arMatrixFree( mat_c );
00317 }
00318
00319
00320 static int checkCollision(float pos1[],float pos2[], float range)
00321 {
00322 float xdist,ydist,zdist,dist;
00323
00324 xdist = pos1[0]-pos2[0];
00325 ydist = pos1[1]-pos2[1];
00326 zdist = pos1[2]-pos2[2];
00327
00328 dist = xdist*xdist+ydist*ydist+zdist*zdist;
00329
00330 if(dist<(range*range))
00331 return 1;
00332 else
00333 return 0;
00334 }
00335
00336
00337 static void draw( targetInfo myTarget, double BaseTrans[3][4])
00338 {
00339 double gl_para[16];
00340 GLfloat light_position[] = {100.0,-200.0,200.0,0.0};
00341 GLfloat ambi[] = {0.1, 0.1, 0.1, 0.1};
00342 GLfloat lightZeroColor[] = {0.9, 0.9, 0.9, 0.1};
00343 GLfloat mat_ambient2[] = {0.0, 0.0, 1.0, 1.0};
00344 GLfloat mat_ambient[] = {1.0, 0.0, 0.0, 1.0};
00345 GLfloat mat_flash2[] = {0.0, 1.0, 1.0, 1.0};
00346 GLfloat mat_flash_shiny2[]= {50.0};
00347
00348 argDrawMode3D();
00349 argDraw3dCamera( 0, 0 );
00350 glEnable(GL_DEPTH_TEST);
00351 glDepthFunc(GL_LEQUAL);
00352
00353
00354 glMatrixMode(GL_MODELVIEW);
00355 argConvGlpara(BaseTrans, gl_para);
00356 glLoadMatrixd( gl_para );
00357
00358
00359 glEnable(GL_LIGHTING);
00360 glEnable(GL_LIGHT0);
00361 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
00362 glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
00363 glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
00364 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash2);
00365 glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny2);
00366 if(myTarget.state == TOUCHED)
00367 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
00368 else
00369 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient2);
00370
00371 glMatrixMode(GL_MODELVIEW);
00372 glTranslatef( myTarget.pos[0], myTarget.pos[1], myTarget.pos[2] );
00373 glutSolidCube(40.0);
00374
00375 if(myTarget.state == TOUCHED){
00376 glColor3f(1.0,1.0,1.0);
00377 glLineWidth(6.0);
00378 glutWireCube(60.0);
00379 glLineWidth(1.0);
00380 }
00381
00382 glDisable( GL_LIGHTING );
00383 glDisable( GL_DEPTH_TEST );
00384 argDrawMode2D();
00385 }
00386
00387
00388 int draw_paddle( ARPaddleInfo *paddleInfo )
00389 {
00390 double gl_para[16];
00391 int i;
00392
00393 argDrawMode3D();
00394 glEnable(GL_DEPTH_TEST);
00395 glDepthFunc(GL_LEQUAL);
00396
00397 argDraw3dCamera( 0, 0 );
00398 argConvGlpara(paddleInfo->trans, gl_para);
00399
00400 glMatrixMode(GL_MODELVIEW);
00401 glLoadMatrixd( gl_para );
00402
00403 glColor3f( 1.0, 0.0, 0.0 );
00404 glLineWidth(4.0);
00405 glBegin(GL_LINE_LOOP);
00406 glVertex2f( -25.0, -25.0 );
00407 glVertex2f( 25.0, -25.0 );
00408 glVertex2f( 25.0, 25.0 );
00409 glVertex2f( -25.0, 25.0 );
00410 glEnd();
00411
00412 glColor3f( 0.0, 0.0, 1.0);
00413 glBegin(GL_LINE_LOOP);
00414 for( i = 0; i < 16; i++ ) {
00415 double x, y;
00416 x = PADDLE_RADIUS * cos(i*3.141592*2/16);
00417 y = PADDLE_RADIUS * sin(i*3.141592*2/16);
00418 glVertex2d( x, y );
00419 }
00420 glEnd();
00421 glBegin(GL_LINE_LOOP);
00422 glVertex2f( -7.5, 0.0 );
00423 glVertex2f( 7.5, 0.0 );
00424 glVertex2f( 7.5, -105.0 );
00425 glVertex2f( -7.5, -105.0 );
00426 glEnd();
00427
00428 glEnable(GL_BLEND);
00429 glBlendFunc(GL_ZERO,GL_ONE);
00430
00431 glColor4f(1,1,1,0);
00432 glBegin(GL_POLYGON);
00433 for( i = 0; i < 16; i++ ) {
00434 double x, y;
00435 x = 40.0 * cos(i*3.141592*2/16);
00436 y = 40.0 * sin(i*3.141592*2/16);
00437 glVertex2d( x, y );
00438 }
00439 glEnd();
00440 glBegin(GL_POLYGON);
00441 glVertex2f( -7.5, 0.0 );
00442 glVertex2f( 7.5, 0.0 );
00443 glVertex2f( 7.5, -105.0 );
00444 glVertex2f( -7.5, -105.0 );
00445 glEnd();
00446 glDisable(GL_BLEND);
00447
00448 glDisable(GL_DEPTH_TEST);
00449 argDrawMode2D();
00450 return 0;
00451 }
00452
00453
00454
00455
00456
00457
00458 int drawGroundGrid( double trans[3][4], int divisions, float x, float y, float height)
00459 {
00460 double gl_para[16];
00461 int i;
00462 float x0,x1,y0,y1;
00463 float deltaX, deltaY;
00464
00465 argDrawMode3D();
00466 argDraw3dCamera( 0, 0 );
00467 glEnable(GL_DEPTH_TEST);
00468 glDepthFunc(GL_LEQUAL);
00469
00470
00471 glMatrixMode(GL_MODELVIEW);
00472 argConvGlpara(trans, gl_para);
00473 glLoadMatrixd( gl_para );
00474 glTranslatef(x/2.,-y/2.,0.);
00475
00476 glColor3f(1,0,0);
00477 glLineWidth(6.0);
00478 glBegin(GL_LINE_LOOP);
00479 glVertex3f( -x, y, height );
00480 glVertex3f( x, y, height );
00481 glVertex3f( x, -y, height );
00482 glVertex3f( -x, -y, height );
00483 glEnd();
00484 glLineWidth(3.0);
00485
00486
00487
00488 x0 = -x; x1 = -x;
00489 y0 = -y; y1 = y;
00490 deltaX = (2*x)/divisions;
00491
00492 for(i=0;i<divisions;i++){
00493 x0 = x0 + deltaX;
00494 glBegin(GL_LINES);
00495 glVertex3f(x0,y0,height);
00496 glVertex3f(x0,y1,height);
00497 glEnd();
00498 }
00499
00500 x0 = -x; x1 = x;
00501 deltaY = (2*y)/divisions;
00502
00503 for(i=0;i<divisions;i++){
00504 y0 = y0 + deltaY;
00505 glBegin(GL_LINES);
00506 glVertex3f(x0,y0,height);
00507 glVertex3f(x1,y0,height);
00508 glEnd();
00509 }
00510
00511 glLineWidth(1.0);
00512
00513 glEnable(GL_LIGHTING);
00514 glEnable(GL_LIGHT0);
00515 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
00516 glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
00517 glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
00518
00519 glDisable( GL_LIGHTING );
00520 glDisable( GL_DEPTH_TEST );
00521 argDrawMode2D();
00522 return 0;
00523 }