00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #if defined(_WIN32)
00004 #include <windows.h>
00005 #endif
00006 #ifndef __APPLE__
00007 # include <GL/glut.h>
00008 # ifdef GL_VERSION_1_2
00009 # include <GL/glext.h>
00010 # endif
00011 #else
00012 # include <GLUT/glut.h>
00013 # include <OpenGL/glext.h>
00014 #endif
00015 #include <AR/config.h>
00016 #include <AR/param.h>
00017 #include <AR/ar.h>
00018 #include <AR/gsub.h>
00019 #include <AR/video.h>
00020 #include <AR/gsubUtil.h>
00021
00022 #define CALIB_POS1_NUM 5
00023 #define CALIB_POS2_NUM 2
00024
00025 static double calib_pos[CALIB_POS1_NUM][2] = { { 160, 120 },
00026 { 480, 120 },
00027 { 320, 240 },
00028 { 160, 360 },
00029 { 480, 360 } };
00030 static double calib_pos2d[CALIB_POS1_NUM][CALIB_POS2_NUM][2];
00031 static double calib_pos3d[CALIB_POS1_NUM][CALIB_POS2_NUM][3];
00032 static int co1;
00033 static int co2;
00034 static int left_right;
00035 static double target_trans[3][4];
00036 static int target_id;
00037 static int target_visible;
00038 static double target_center[2] = { 0.0, 0.0 };
00039 static double target_width = 80.0;
00040
00041 static ARParam hmd_param[2];
00042 static int thresh;
00043 static int arFittingModeBak;
00044
00045 static int hmdMode;
00046 static int gMiniXnum, gMiniYnum;
00047 static void (*gMouseFunc)(int button, int state, int x, int y);
00048 static void (*gKeyFunc)(unsigned char key, int x, int y);
00049 static void (*gMainFunc)(void);
00050 static void (*gCalibPostFunc)(ARParam *lpara, ARParam *rpara);
00051
00052 static void argCalibMouseFunc(int button, int state, int x, int y);
00053 static void argCalibMainFunc(void);
00054 static int argDrawAttention(double pos[2], int color);
00055
00056 void argUtilCalibHMD( int targetId, int thresh2,
00057 void (*postFunc)(ARParam *lpara, ARParam *rpara) )
00058 {
00059 argInqSetting( &hmdMode, &gMiniXnum, &gMiniYnum,
00060 &gMouseFunc, &gKeyFunc, &gMainFunc );
00061
00062 if( hmdMode == 0 ) return;
00063
00064 target_id = targetId;
00065 thresh = thresh2;
00066 gCalibPostFunc = postFunc;
00067 arFittingModeBak = arFittingMode;
00068
00069 arFittingMode = AR_FITTING_TO_IDEAL;
00070 co1 = 0;
00071 co2 = 0;
00072 left_right = 0;
00073 target_visible = 0;
00074
00075 glutKeyboardFunc( NULL );
00076 glutMouseFunc( argCalibMouseFunc );
00077 glutIdleFunc( argCalibMainFunc );
00078 glutDisplayFunc( argCalibMainFunc );
00079 }
00080
00081 static void argCalibMouseFunc(int button, int state, int x, int y)
00082 {
00083 if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
00084 if( target_visible ) {
00085 calib_pos3d[co1][co2][0] = target_trans[0][3];
00086 calib_pos3d[co1][co2][1] = target_trans[1][3];
00087 calib_pos3d[co1][co2][2] = target_trans[2][3];
00088 calib_pos2d[co1][co2][0] = calib_pos[co1][0];
00089 calib_pos2d[co1][co2][1] = calib_pos[co1][1];
00090 co2++;
00091 if( co2 == CALIB_POS2_NUM ) {
00092 co1++;
00093 co2 = 0;
00094 }
00095
00096 if( co1 == CALIB_POS1_NUM ) {
00097 hmd_param[left_right].xsize = AR_HMD_XSIZE;
00098 hmd_param[left_right].ysize = AR_HMD_YSIZE;
00099 hmd_param[left_right].dist_factor[0] = AR_HMD_XSIZE / 2.0;
00100 hmd_param[left_right].dist_factor[1] = AR_HMD_YSIZE / 2.0;
00101 hmd_param[left_right].dist_factor[2] = 0.0;
00102 hmd_param[left_right].dist_factor[3] = 1.0;
00103 if( arParamGet( (double (*)[3])calib_pos3d, (double (*)[2])calib_pos2d,
00104 CALIB_POS1_NUM*CALIB_POS2_NUM, hmd_param[left_right].mat) < 0 ) {
00105 (*gCalibPostFunc)( NULL, NULL );
00106 arFittingMode = arFittingModeBak;
00107 glutKeyboardFunc( gKeyFunc );
00108 glutMouseFunc( gMouseFunc );
00109 glutIdleFunc( gMainFunc );
00110 glutDisplayFunc( gMainFunc );
00111 return;
00112 }
00113
00114 co1 = 0;
00115 co2 = 0;
00116 left_right++;
00117 if( left_right == 2 ) {
00118 argLoadHMDparam( &hmd_param[0], &hmd_param[1] );
00119 arFittingMode = arFittingModeBak;
00120
00121 if( gCalibPostFunc != NULL ) {
00122 (*gCalibPostFunc)( &hmd_param[0], &hmd_param[1] );
00123 }
00124 glutKeyboardFunc( gKeyFunc );
00125 glutMouseFunc( gMouseFunc );
00126 glutIdleFunc( gMainFunc );
00127 glutDisplayFunc( gMainFunc );
00128 return;
00129 }
00130 }
00131 }
00132 }
00133
00134 if( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN ) {
00135 (*gCalibPostFunc)( NULL, NULL );
00136 arFittingMode = arFittingMode;
00137 glutKeyboardFunc( gKeyFunc );
00138 glutMouseFunc( gMouseFunc );
00139 glutIdleFunc( gMainFunc );
00140 glutDisplayFunc( gMainFunc );
00141 return;
00142 }
00143 }
00144
00145 static void argCalibMainFunc(void)
00146 {
00147 ARUint8 *dataPtr;
00148 ARMarkerInfo *marker_info;
00149 int marker_num;
00150 int i, j;
00151 double cfmax;
00152 double err;
00153
00154
00155 if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
00156 arUtilSleep(2);
00157 return;
00158 }
00159 target_visible = 0;
00160
00161
00162 if( arDetectMarker(dataPtr, thresh,
00163 &marker_info, &marker_num) < 0 ) {
00164 (*gCalibPostFunc)( NULL, NULL );
00165 arFittingMode = arFittingModeBak;
00166 glutKeyboardFunc( gKeyFunc );
00167 glutMouseFunc( gMouseFunc );
00168 glutIdleFunc( gMainFunc );
00169 glutDisplayFunc( gMainFunc );
00170 return;
00171 }
00172 arVideoCapNext();
00173
00174 glClearColor( 0.0, 0.0, 0.0, 0.0 );
00175 glClear(GL_COLOR_BUFFER_BIT);
00176
00177
00178
00179 if( arDebug && gMiniXnum >= 2 && gMiniYnum >= 1 ) {
00180 argDispImage( dataPtr, 1, 1 );
00181 if( arImageProcMode == AR_IMAGE_PROC_IN_HALF )
00182 argDispHalfImage( arImage, 2, 1 );
00183 else
00184 argDispImage( arImage, 2, 1);
00185
00186 glColor3f( 1.0, 0.0, 0.0 );
00187 glLineWidth( 3.0 );
00188 for( i = 0; i < marker_num; i++ ) {
00189 if( marker_info[i].id < 0 ) continue;
00190 argDrawSquare( marker_info[i].vertex, 2, 1 );
00191 }
00192 glLineWidth( 1.0 );
00193 }
00194
00195 if( left_right == 0 ) argDraw2dLeft();
00196 else argDraw2dRight();
00197 glLineWidth( 3.0 );
00198 glColor3f( 1.0, 1.0, 1.0 );
00199 argLineSegHMD( 0, calib_pos[co1][1], AR_HMD_XSIZE, calib_pos[co1][1] );
00200 argLineSegHMD( calib_pos[co1][0], 0, calib_pos[co1][0], AR_HMD_YSIZE );
00201 glLineWidth( 1.0 );
00202 argDrawMode2D();
00203
00204 cfmax = 0.0;
00205 j = -1;
00206 for( i = 0; i < marker_num; i++ ) {
00207 if( marker_info[i].id != target_id ) continue;
00208
00209 if( marker_info[i].cf > cfmax ) {
00210 cfmax = marker_info[i].cf;
00211 j = i;
00212 }
00213 }
00214 if( j < 0 ) {
00215 argSwapBuffers();
00216 return;
00217 }
00218 err = arGetTransMat(&marker_info[j], target_center, target_width, target_trans);
00219 if( err >= 0.0 ) {
00220 target_visible = 1;
00221
00222 if( left_right == 0 ) argDraw2dLeft();
00223 else argDraw2dRight();
00224 argDrawAttention( calib_pos[co1], co2 );
00225 argDrawMode2D();
00226
00227 if( arDebug && gMiniXnum >= 2 && gMiniYnum >= 1 ) {
00228 glColor3f( 0.0, 1.0, 0.0 );
00229 glLineWidth( 3.0 );
00230 argDrawSquare( marker_info[j].vertex, 1, 1 );
00231 glLineWidth( 1.0 );
00232 }
00233 }
00234
00235 argSwapBuffers();
00236 }
00237
00238 static int argDrawAttention( double pos[2], int color )
00239 {
00240 switch( color%7 ) {
00241 case 0: glColor3f( 1.0, 0.0, 0.0 ); break;
00242 case 1: glColor3f( 0.0, 1.0, 0.0 ); break;
00243 case 2: glColor3f( 0.0, 0.0, 1.0 ); break;
00244 case 3: glColor3f( 1.0, 1.0, 0.0 ); break;
00245 case 4: glColor3f( 1.0, 0.0, 1.0 ); break;
00246 case 5: glColor3f( 0.0, 1.0, 1.0 ); break;
00247 case 6: glColor3f( 1.0, 1.0, 1.0 ); break;
00248 }
00249
00250 glLineWidth( 5.0 );
00251 argLineSegHMD( pos[0]-20, pos[1]-20, pos[0]+20, pos[1]-20 );
00252 argLineSegHMD( pos[0]-20, pos[1]+20, pos[0]+20, pos[1]+20 );
00253 argLineSegHMD( pos[0]-20, pos[1]-20, pos[0]-20, pos[1]+20 );
00254 argLineSegHMD( pos[0]+20, pos[1]-20, pos[0]+20, pos[1]+20 );
00255 glLineWidth( 1.0 );
00256
00257 return(0);
00258 }