simpleVRML.c
Go to the documentation of this file.
00001 /*
00002  *      simpleVRML.c
00003  *
00004  *      Demonstration of ARToolKit with models rendered in VRML.
00005  *
00006  *  Press '?' while running for help on available key commands.
00007  *
00008  *      Copyright (c) 2002 Mark Billinghurst (MB) grof@hitl.washington.edu
00009  *      Copyright (c) 2004 Raphael Grasset (RG) raphael.grasset@hitlabnz.org.
00010  *      Copyright (c) 2004-2007 Philip Lamb (PRL) phil@eden.net.nz. 
00011  *      
00012  *      Rev             Date            Who             Changes
00013  *      1.0.0   ????-??-??      MB              Original from ARToolKit
00014  *  1.0.1   2004-10-29  RG              Fix for ARToolKit 2.69.
00015  *  1.0.2   2004-11-30  PRL     Various fixes.
00016  *
00017  */
00018 /*
00019  * 
00020  * This file is part of ARToolKit.
00021  * 
00022  * ARToolKit is free software; you can redistribute it and/or modify
00023  * it under the terms of the GNU General Public License as published by
00024  * the Free Software Foundation; either version 2 of the License, or
00025  * (at your option) any later version.
00026  * 
00027  * ARToolKit is distributed in the hope that it will be useful,
00028  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00029  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00030  * GNU General Public License for more details.
00031  * 
00032  * You should have received a copy of the GNU General Public License
00033  * along with ARToolKit; if not, write to the Free Software
00034  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00035  * 
00036  */
00037 
00038 
00039 // ============================================================================
00040 //      Includes
00041 // ============================================================================
00042 
00043 #ifdef _WIN32
00044 #  include <windows.h>
00045 #endif
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 #include <string.h>
00049 
00050 #ifdef __APPLE__
00051 #  include <GLUT/glut.h>
00052 #else
00053 #  include <GL/glut.h>
00054 #endif
00055 
00056 #include <AR/config.h>
00057 #include <AR/video.h>
00058 #include <AR/param.h>                   // arParamDisp()
00059 #include <AR/ar.h>
00060 #include <AR/gsub_lite.h>
00061 #include <AR/arvrml.h>
00062 
00063 #include "object.h"
00064 
00065 // ============================================================================
00066 //      Constants
00067 // ============================================================================
00068 
00069 #define VIEW_SCALEFACTOR                1.0                     // 1.0 ARToolKit unit becomes 1.0 of my OpenGL units.
00070 #define VIEW_DISTANCE_MIN               10.0            // Objects closer to the camera than this will not be displayed.
00071 #define VIEW_DISTANCE_MAX               10000.0         // Objects further away from the camera than this will not be displayed.
00072 
00073 
00074 // ============================================================================
00075 //      Global variables
00076 // ============================================================================
00077 
00078 // Preferences.
00079 static int prefWindowed = TRUE;
00080 static int prefWidth = 640;                                     // Fullscreen mode width.
00081 static int prefHeight = 480;                            // Fullscreen mode height.
00082 static int prefDepth = 32;                                      // Fullscreen mode bit depth.
00083 static int prefRefresh = 0;                                     // Fullscreen mode refresh rate. Set to 0 to use default rate.
00084 
00085 // Image acquisition.
00086 static ARUint8          *gARTImage = NULL;
00087 
00088 // Marker detection.
00089 static int                      gARTThreshhold = 100;
00090 static long                     gCallCountMarkerDetect = 0;
00091 
00092 // Drawing.
00093 static ARParam          gARTCparam;
00094 static ARGL_CONTEXT_SETTINGS_REF gArglSettings = NULL;
00095 
00096 // Object Data.
00097 static ObjectData_T     *gObjectData;
00098 static int                      gObjectDataCount;
00099 
00100 // ============================================================================
00101 //      Functions
00102 // ============================================================================
00103 
00104 static int setupCamera(const char *cparam_name, char *vconf, ARParam *cparam)
00105 {       
00106     ARParam                     wparam;
00107         int                             xsize, ysize;
00108 
00109     // Open the video path.
00110     if (arVideoOpen(vconf) < 0) {
00111         fprintf(stderr, "setupCamera(): Unable to open connection to camera.\n");
00112         return (FALSE);
00113         }
00114         
00115     // Find the size of the window.
00116     if (arVideoInqSize(&xsize, &ysize) < 0) return (FALSE);
00117     fprintf(stdout, "Camera image size (x,y) = (%d,%d)\n", xsize, ysize);
00118         
00119         // Load the camera parameters, resize for the window and init.
00120     if (arParamLoad(cparam_name, 1, &wparam) < 0) {
00121                 fprintf(stderr, "setupCamera(): Error loading parameter file %s for camera.\n", cparam_name);
00122         return (FALSE);
00123     }
00124     arParamChangeSize(&wparam, xsize, ysize, cparam);
00125     fprintf(stdout, "*** Camera Parameter ***\n");
00126     arParamDisp(cparam);
00127         
00128     arInitCparam(cparam);
00129 
00130         if (arVideoCapStart() != 0) {
00131         fprintf(stderr, "setupCamera(): Unable to begin camera data capture.\n");
00132                 return (FALSE);         
00133         }
00134         
00135         return (TRUE);
00136 }
00137 
00138 static int setupMarkersObjects(char *objectDataFilename, ObjectData_T **objectDataRef, int *objectDataCountRef)
00139 {       
00140         // Load in the object data - trained markers and associated bitmap files.
00141     if ((*objectDataRef = read_VRMLdata(objectDataFilename, objectDataCountRef)) == NULL) {
00142         fprintf(stderr, "setupMarkersObjects(): read_VRMLdata returned error !!\n");
00143         return (FALSE);
00144     }
00145     printf("Object count = %d\n", *objectDataCountRef);
00146 
00147         return (TRUE);
00148 }
00149 
00150 // Report state of ARToolKit global variables arFittingMode,
00151 // arImageProcMode, arglDrawMode, arTemplateMatchingMode, arMatchingPCAMode.
00152 static void debugReportMode(const ARGL_CONTEXT_SETTINGS_REF arglContextSettings)
00153 {
00154         if (arFittingMode == AR_FITTING_TO_INPUT) {
00155                 fprintf(stderr, "FittingMode (Z): INPUT IMAGE\n");
00156         } else {
00157                 fprintf(stderr, "FittingMode (Z): COMPENSATED IMAGE\n");
00158         }
00159         
00160         if (arImageProcMode == AR_IMAGE_PROC_IN_FULL) {
00161                 fprintf(stderr, "ProcMode (X)   : FULL IMAGE\n");
00162         } else {
00163                 fprintf(stderr, "ProcMode (X)   : HALF IMAGE\n");
00164         }
00165         
00166         if (arglDrawModeGet(arglContextSettings) == AR_DRAW_BY_GL_DRAW_PIXELS) {
00167                 fprintf(stderr, "DrawMode (C)   : GL_DRAW_PIXELS\n");
00168         } else if (arglTexmapModeGet(arglContextSettings) == AR_DRAW_TEXTURE_FULL_IMAGE) {
00169                 fprintf(stderr, "DrawMode (C)   : TEXTURE MAPPING (FULL RESOLUTION)\n");
00170         } else {
00171                 fprintf(stderr, "DrawMode (C)   : TEXTURE MAPPING (HALF RESOLUTION)\n");
00172         }
00173                 
00174         if (arTemplateMatchingMode == AR_TEMPLATE_MATCHING_COLOR) {
00175                 fprintf(stderr, "TemplateMatchingMode (M)   : Color Template\n");
00176         } else {
00177                 fprintf(stderr, "TemplateMatchingMode (M)   : BW Template\n");
00178         }
00179         
00180         if (arMatchingPCAMode == AR_MATCHING_WITHOUT_PCA) {
00181                 fprintf(stderr, "MatchingPCAMode (P)   : Without PCA\n");
00182         } else {
00183                 fprintf(stderr, "MatchingPCAMode (P)   : With PCA\n");
00184         }
00185 }
00186 
00187 static void Quit(void)
00188 {
00189         arglCleanup(gArglSettings);
00190         arVideoCapStop();
00191         arVideoClose();
00192 #ifdef _WIN32
00193         CoUninitialize();
00194 #endif
00195         exit(0);
00196 }
00197 
00198 static void Keyboard(unsigned char key, int x, int y)
00199 {
00200         int mode, threshChange = 0;
00201         
00202         switch (key) {
00203                 case 0x1B:                                              // Quit.
00204                 case 'Q':
00205                 case 'q':
00206                         Quit();
00207                         break;
00208                 case 'C':
00209                 case 'c':
00210                         mode = arglDrawModeGet(gArglSettings);
00211                         if (mode == AR_DRAW_BY_GL_DRAW_PIXELS) {
00212                                 arglDrawModeSet(gArglSettings, AR_DRAW_BY_TEXTURE_MAPPING);
00213                                 arglTexmapModeSet(gArglSettings, AR_DRAW_TEXTURE_FULL_IMAGE);
00214                         } else {
00215                                 mode = arglTexmapModeGet(gArglSettings);
00216                                 if (mode == AR_DRAW_TEXTURE_FULL_IMAGE) arglTexmapModeSet(gArglSettings, AR_DRAW_TEXTURE_HALF_IMAGE);
00217                                 else arglDrawModeSet(gArglSettings, AR_DRAW_BY_GL_DRAW_PIXELS);
00218                         }
00219                         fprintf(stderr, "*** Camera - %f (frame/sec)\n", (double)gCallCountMarkerDetect/arUtilTimer());
00220                         gCallCountMarkerDetect = 0;
00221                         arUtilTimerReset();
00222                         debugReportMode(gArglSettings);
00223                         break;
00224                 case '-':
00225                         threshChange = -5;
00226                         break;
00227                 case '+':
00228                 case '=':
00229                         threshChange = +5;
00230                         break;
00231                 case 'D':
00232                 case 'd':
00233                         arDebug = !arDebug;
00234                         break;
00235                 case '?':
00236                 case '/':
00237                         printf("Keys:\n");
00238                         printf(" q or [esc]    Quit demo.\n");
00239                         printf(" c             Change arglDrawMode and arglTexmapMode.\n");
00240                         printf(" - and +       Adjust threshhold.\n");
00241                         printf(" d             Activate / deactivate debug mode.\n");
00242                         printf(" ? or /        Show this help.\n");
00243                         printf("\nAdditionally, the ARVideo library supplied the following help text:\n");
00244                         arVideoDispOption();
00245                         break;
00246                 default:
00247                         break;
00248         }
00249         if (threshChange) {
00250                 gARTThreshhold += threshChange;
00251                 if (gARTThreshhold < 0) gARTThreshhold = 0;
00252                 if (gARTThreshhold > 255) gARTThreshhold = 255;
00253                 printf("Threshhold changed to %d.\n", gARTThreshhold);
00254         }
00255 }
00256 
00257 static void Idle(void)
00258 {
00259         static int ms_prev;
00260         int ms;
00261         float s_elapsed;
00262         ARUint8 *image;
00263 
00264         ARMarkerInfo    *marker_info;                                   // Pointer to array holding the details of detected markers.
00265     int             marker_num;                                         // Count of number of markers detected.
00266     int             i, j, k;
00267         
00268         // Find out how long since Idle() last ran.
00269         ms = glutGet(GLUT_ELAPSED_TIME);
00270         s_elapsed = (float)(ms - ms_prev) * 0.001;
00271         if (s_elapsed < 0.01f) return; // Don't update more often than 100 Hz.
00272         ms_prev = ms;
00273         
00274         // Update drawing.
00275         arVrmlTimerUpdate();
00276         
00277         // Grab a video frame.
00278         if ((image = arVideoGetImage()) != NULL) {
00279                 gARTImage = image;      // Save the fetched image.
00280                 
00281                 gCallCountMarkerDetect++; // Increment ARToolKit FPS counter.
00282                 
00283                 // Detect the markers in the video frame.
00284                 if (arDetectMarker(gARTImage, gARTThreshhold, &marker_info, &marker_num) < 0) {
00285                         exit(-1);
00286                 }
00287                                 
00288                 // Check for object visibility.
00289                 
00290                 for (i = 0; i < gObjectDataCount; i++) {
00291                 
00292                         // Check through the marker_info array for highest confidence
00293                         // visible marker matching our object's pattern.
00294                         k = -1;
00295                         for (j = 0; j < marker_num; j++) {
00296                                 if (marker_info[j].id == gObjectData[i].id) {
00297                                         if( k == -1 ) k = j; // First marker detected.
00298                                         else if (marker_info[k].cf < marker_info[j].cf) k = j; // Higher confidence marker detected.
00299                                 }
00300                         }
00301                         
00302                         if (k != -1) {
00303                                 // Get the transformation between the marker and the real camera.
00304                                 //fprintf(stderr, "Saw object %d.\n", i);
00305                                 if (gObjectData[i].visible == 0) {
00306                                         arGetTransMat(&marker_info[k],
00307                                                                   gObjectData[i].marker_center, gObjectData[i].marker_width,
00308                                                                   gObjectData[i].trans);
00309                                 } else {
00310                                         arGetTransMatCont(&marker_info[k], gObjectData[i].trans,
00311                                                                           gObjectData[i].marker_center, gObjectData[i].marker_width,
00312                                                                           gObjectData[i].trans);
00313                                 }
00314                                 gObjectData[i].visible = 1;
00315                         } else {
00316                                 gObjectData[i].visible = 0;
00317                         }
00318                 }
00319                 
00320                 // Tell GLUT the display has changed.
00321                 glutPostRedisplay();
00322         }
00323 }
00324 
00325 //
00326 //      This function is called on events when the visibility of the
00327 //      GLUT window changes (including when it first becomes visible).
00328 //
00329 static void Visibility(int visible)
00330 {
00331         if (visible == GLUT_VISIBLE) {
00332                 glutIdleFunc(Idle);
00333         } else {
00334                 glutIdleFunc(NULL);
00335         }
00336 }
00337 
00338 //
00339 //      This function is called when the
00340 //      GLUT window is resized.
00341 //
00342 static void Reshape(int w, int h)
00343 {
00344         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00345         glViewport(0, 0, (GLsizei) w, (GLsizei) h);
00346         
00347         glMatrixMode(GL_PROJECTION);
00348         glLoadIdentity();
00349         glMatrixMode(GL_MODELVIEW);
00350         glLoadIdentity();
00351 
00352         // Call through to anyone else who needs to know about window sizing here.
00353 }
00354 
00355 //
00356 // This function is called when the window needs redrawing.
00357 //
00358 static void Display(void)
00359 {
00360         int i;
00361     GLdouble p[16];
00362         GLdouble m[16];
00363         
00364         // Select correct buffer for this context.
00365         glDrawBuffer(GL_BACK);
00366         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
00367         
00368         arglDispImage(gARTImage, &gARTCparam, 1.0, gArglSettings);      // zoom = 1.0.
00369         arVideoCapNext();
00370         gARTImage = NULL; // Image data is no longer valid after calling arVideoCapNext().
00371                                 
00372         // Projection transformation.
00373         arglCameraFrustumRH(&gARTCparam, VIEW_DISTANCE_MIN, VIEW_DISTANCE_MAX, p);
00374         glMatrixMode(GL_PROJECTION);
00375         glLoadMatrixd(p);
00376         glMatrixMode(GL_MODELVIEW);
00377                 
00378         // Viewing transformation.
00379         glLoadIdentity();
00380         // Lighting and geometry that moves with the camera should go here.
00381         // (I.e. must be specified before viewing transformations.)
00382         //none
00383         
00384         for (i = 0; i < gObjectDataCount; i++) {
00385         
00386                 if ((gObjectData[i].visible != 0) && (gObjectData[i].vrml_id >= 0)) {
00387         
00388                         // Calculate the camera position for the object and draw it.
00389                         // Replace VIEW_SCALEFACTOR with 1.0 to make one drawing unit equal to 1.0 ARToolKit units (usually millimeters).
00390                         arglCameraViewRH(gObjectData[i].trans, m, VIEW_SCALEFACTOR);
00391                         glLoadMatrixd(m);
00392 
00393                         // All lighting and geometry to be drawn relative to the marker goes here.
00394                         //fprintf(stderr, "About to draw object %i\n", i);
00395                         arVrmlDraw(gObjectData[i].vrml_id);
00396                 }                       
00397         }
00398         
00399         // Any 2D overlays go here.
00400         //none
00401         
00402         glutSwapBuffers();
00403 }
00404 
00405 int main(int argc, char** argv)
00406 {
00407         int i;
00408         char glutGamemode[32];
00409         const char *cparam_name = "Data/camera_para.dat";
00410         //
00411         // Camera configuration.
00412         //
00413 #ifdef _WIN32
00414         char                    *vconf = "Data\\WDM_camera_flipV.xml";
00415 #else
00416         char                    *vconf = "";
00417 #endif
00418         char objectDataFilename[] = "Data/object_data_vrml";
00419         
00420         // ----------------------------------------------------------------------------
00421         // Library inits.
00422         //
00423 
00424         glutInit(&argc, argv);
00425 
00426         // ----------------------------------------------------------------------------
00427         // Hardware setup.
00428         //
00429 
00430         if (!setupCamera(cparam_name, vconf, &gARTCparam)) {
00431                 fprintf(stderr, "main(): Unable to set up AR camera.\n");
00432                 exit(-1);
00433         }
00434         
00435 #ifdef _WIN32
00436         CoInitialize(NULL);
00437 #endif
00438 
00439         // ----------------------------------------------------------------------------
00440         // Library setup.
00441         //
00442 
00443         // Set up GL context(s) for OpenGL to draw into.
00444         glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
00445         if (!prefWindowed) {
00446                 if (prefRefresh) sprintf(glutGamemode, "%ix%i:%i@%i", prefWidth, prefHeight, prefDepth, prefRefresh);
00447                 else sprintf(glutGamemode, "%ix%i:%i", prefWidth, prefHeight, prefDepth);
00448                 glutGameModeString(glutGamemode);
00449                 glutEnterGameMode();
00450         } else {
00451                 glutInitWindowSize(prefWidth, prefHeight);
00452                 glutCreateWindow(argv[0]);
00453         }
00454 
00455         // Setup argl library for current context.
00456         if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {
00457                 fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");
00458                 exit(-1);
00459         }
00460         debugReportMode(gArglSettings);
00461         glEnable(GL_DEPTH_TEST);
00462         arUtilTimerReset();
00463 
00464         if (!setupMarkersObjects(objectDataFilename, &gObjectData, &gObjectDataCount)) {
00465                 fprintf(stderr, "main(): Unable to set up AR objects and markers.\n");
00466                 Quit();
00467         }
00468         
00469         // Test render all the VRML objects.
00470     fprintf(stdout, "Pre-rendering the VRML objects...");
00471         fflush(stdout);
00472     glEnable(GL_TEXTURE_2D);
00473     for (i = 0; i < gObjectDataCount; i++) {
00474                 arVrmlDraw(gObjectData[i].vrml_id);
00475     }
00476     glDisable(GL_TEXTURE_2D);
00477         fprintf(stdout, " done\n");
00478         
00479         // Register GLUT event-handling callbacks.
00480         // NB: Idle() is registered by Visibility.
00481         glutDisplayFunc(Display);
00482         glutReshapeFunc(Reshape);
00483         glutVisibilityFunc(Visibility);
00484         glutKeyboardFunc(Keyboard);
00485         
00486         glutMainLoop();
00487 
00488         return (0);
00489 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:15:00