Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

#ifdef _WIN32
#  include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#ifndef __APPLE__
#  include <GL/glut.h>
#else
#  include <GLUT/glut.h>
#endif
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/param.h>
#include <AR/matrix.h>
#include <AR/ar.h>
#include <AR/arMulti.h>

/* set up the video format globals */

#ifdef _WIN32
char    *vconf = "Data\\WDM_camera_flipV.xml";
#else
char    *vconf = "";
#endif

#define TARGET_NUM 5

#include "paddle.h"
#include "command_sub.h"

PaddleItemInfo myPaddleItem;
ItemList myListItem;

int             xsize, ysize;
int             thresh = 100;
int             count = 0;

char           *cparam_name    = "Data/camera_para.dat";
ARParam         cparam;

char                *config_name = "Data/multi/marker.dat";
ARMultiMarkerInfoT  *config;

/* paddle information  */
int              marker_flag[AR_SQUARE_MAX];
ARPaddleInfo   *paddleInfo;
char           *paddle_name    = "Data/paddle_data";  

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};


PaddleItemInfo myPaddleItem;
ItemList myListItem;

static int    draw_paddle( ARPaddleInfo *paddleInfo, PaddleItemInfo *myPaddleItem);
static void   init(void);
static void   cleanup(void);
static void   keyEvent( unsigned char key, int x, int y);
static void   mainLoop(void);
static int    draw_paddle( ARPaddleInfo *paddleInfo, PaddleItemInfo *myPaddleItem);
static int    drawGroundGrid( double trans[3][4], int divisions, float x, float y, float height);
static void   findPaddlePosition(float curPaddlePos[], double card_trans[3][4],double base_trans[3][4]);
static void drawItems(double trans[3][4],ItemList* list);

int main(int argc, char **argv)
{
        //initialize applications
        glutInit(&argc, argv);
    init();

    arVideoCapStart();
        //start the main event loop
    argMainLoop( NULL, keyEvent, mainLoop );

        return 0;
}

/* keyboard events */
static void   keyEvent( unsigned char key, int x, int y)  
{
    /* quit if the ESC key is pressed */
    if( key == 0x1b ) {
        printf("*** %f (frame/sec)\n", (double)count/arUtilTimer());
        cleanup();
        exit(0);
    }

        /* change the threshold value when 't' key pressed */
    if( key == 't' ) {
        printf("Enter new threshold value (default = 100): ");
        scanf("%d",&thresh); while( getchar()!='\n' );
        printf("\n");
    }

        /* turn on and off the debug mode with d key */
    if( key == 'd' ) {
        printf("*** %f (frame/sec)\n", (double)count/arUtilTimer());
        arDebug = 1 - arDebug;
        if( arDebug == 0 ) {
            glClearColor( 0.0, 0.0, 0.0, 0.0 );
            glClear(GL_COLOR_BUFFER_BIT);
            argSwapBuffers();
            glClear(GL_COLOR_BUFFER_BIT);
            argSwapBuffers();
        }
        count = 0;
    }
}

/* main loop */
static void mainLoop(void)
{
    ARUint8         *dataPtr;
    ARMarkerInfo    *marker_info;
    int             marker_num;
        float curPaddlePos[3];
    int             i;
    double          err;
    double                      angle;

        err=0.;
    /* grab a video frame */
    if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
        arUtilSleep(2);
        return;
    }
       
    if( count == 0 ) arUtilTimerReset();  
    count++;
   
        /* detect the markers in the video frame */
    if( arDetectMarkerLite(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
        cleanup();
        exit(0);
    }

    argDrawMode2D();
    if( !arDebug ) {
        argDispImage( dataPtr, 0,0 );
    }
    else {
        argDispImage( dataPtr, 1, 1 );
        if( arImageProcMode == AR_IMAGE_PROC_IN_HALF )
            argDispHalfImage( arImage, 0, 0 );
        else
            argDispImage( arImage, 0, 0);

        glColor3f( 1.0, 0.0, 0.0 );
        glLineWidth( 1.0 );
        for( i = 0; i < marker_num; i++ ) {
            argDrawSquare( marker_info[i].vertex, 0, 0 );
        }
        glLineWidth( 1.0 );
    }

    arVideoCapNext();

        for( i = 0; i < marker_num; i++ )
                marker_flag[i] = 0;
 
        /* get the paddle position */
        paddleGetTrans(paddleInfo, marker_info, marker_flag,
                                marker_num, &cparam);
        /* draw the 3D models */
        glClearDepth( 1.0 );
        glClear(GL_DEPTH_BUFFER_BIT);


        /* get the translation from the multimarker pattern */
        if( (err=arMultiGetTransMat(marker_info, marker_num, config)) < 0 ) {
        argSwapBuffers();
        return;
    }  
       
        //    printf("err = %f\n", err);
    if(err > 100.0 ) {
        argSwapBuffers();
        return;
    }
       
        //draw a red ground grid
        drawGroundGrid( config->trans, 15, 150.0, 110.0, 0.0);

        /* find the paddle position relative to the base */
        if (paddleInfo->active)
                findPaddlePosition(curPaddlePos,paddleInfo->trans,config->trans);

        /* checking for paddle gesture */
        if( paddleInfo->active)
          {
            int findItem=-1;
            if (myPaddleItem.item!=-1)
              {

                  if( check_incline(paddleInfo->trans, config->trans, &angle) ) {
                      myPaddleItem.x += 2.0 * cos(angle);
                      myPaddleItem.y += 2.0 * sin(angle);
                      if( myPaddleItem.x*myPaddleItem.x +
                          myPaddleItem.y*myPaddleItem.y > 900.0 ) {
                          myPaddleItem.x -= 2.0 * cos(angle);
                          myPaddleItem.y -= 2.0 * sin(angle);
                          myListItem.item[myPaddleItem.item].onpaddle=0;                     
                          myListItem.item[myPaddleItem.item].pos[0]=curPaddlePos[0];
                          myListItem.item[myPaddleItem.item].pos[1]=curPaddlePos[1];  
                          myPaddleItem.item = -1;
                        }
                  }
              }
            else
              {
                if ((findItem=check_pickup(paddleInfo->trans, config->trans,&myListItem, &angle))!=-1)  {
                   
                    myPaddleItem.item=findItem;
                    myPaddleItem.x =0.0;
                    myPaddleItem.y =0.0;
                    myPaddleItem.angle = 0.0;
                    myListItem.item[myPaddleItem.item].onpaddle=1;
                  }
              }
          }

        /* draw the item */
        drawItems(config->trans,&myListItem);

        /* draw the paddle */
        if( paddleInfo->active ){
          draw_paddle(paddleInfo,&myPaddleItem);
        }
       
        argSwapBuffers();
}

static void init( void )
{
  ARParam  wparam;
       
    /* open the video path */
    if( arVideoOpen( vconf ) < 0 ) exit(0);
    /* find the size of the window */
    if( arVideoInqSize(&xsize, &ysize) < 0 ) exit(0);
    printf("Image size (x,y) = (%d,%d)\n", xsize, ysize);

    /* set the initial camera parameters */
    if( arParamLoad(cparam_name, 1, &wparam) < 0 ) {
        printf("Camera parameter load error !!\n");
        exit(0);
    }
    arParamChangeSize( &wparam, xsize, ysize, &cparam );
    arInitCparam( &cparam );
    printf("*** Camera Parameter ***\n");
    arParamDisp( &cparam );

        /* load the paddle marker file */
        if( (paddleInfo = paddleInit(paddle_name)) == NULL ) {
                printf("paddleInit error!!\n");
                exit(0);
        }
        printf("Loaded Paddle File\n");

        if( (config = arMultiReadConfigFile(config_name)) == NULL ) {
        printf("config data load error !!\n");
        exit(0);
    }
        printf("Loaded Multi Marker File\n");

        /* init items */
        myListItem.itemnum=4;
        myListItem.item[0].pos[0]=0.;myListItem.item[0].pos[1]=0.;myListItem.item[0].onpaddle=0;
        myListItem.item[1].pos[0]=100.;myListItem.item[1].pos[1]=-100.;myListItem.item[1].onpaddle=0;
        myListItem.item[2].pos[0]=200.;myListItem.item[2].pos[1]=0.;myListItem.item[2].onpaddle=0;
        myListItem.item[3].pos[0]=0.;myListItem.item[3].pos[1]=0.;myListItem.item[3].onpaddle=1;       

        /* set up the initial paddle contents */
        myPaddleItem.item = 3;
        myPaddleItem.angle = 0.0;
        myPaddleItem.x = 0.0;
        myPaddleItem.y = 0.0;

    /* open the graphics window */
        argInit( &cparam, 1.0, 0, 0, 0, 0 );
}

/* cleanup function called when program exits */
static void cleanup(void)
{
  arVideoCapStop();
  arVideoClose();
  argCleanup();
}

/* find the position of the paddle card relative to the base and set the dropped blob position to this */
static void       findPaddlePosition(float curPaddlePos[], double card_trans[3][4],double base_trans[3][4])
{
        int i,j;

        ARMat   *mat_a,  *mat_b, *mat_c;
    double  x, y, z;

        //get card position relative to base pattern
    mat_a = arMatrixAlloc( 4, 4 );
    mat_b = arMatrixAlloc( 4, 4 );
    mat_c = arMatrixAlloc( 4, 4 );
    for( j = 0; j < 3; j++ ) {
        for( i = 0; i < 4; i++ ) {
            mat_b->m[j*4+i] = base_trans[j][i];
        }
    }
    mat_b->m[3*4+0] = 0.0;
    mat_b->m[3*4+1] = 0.0;
    mat_b->m[3*4+2] = 0.0;
    mat_b->m[3*4+3] = 1.0;
    for( j = 0; j < 3; j++ ) {
        for( i = 0; i < 4; i++ ) {
            mat_a->m[j*4+i] = card_trans[j][i];
        }
    }
    mat_a->m[3*4+0] = 0.0;
    mat_a->m[3*4+1] = 0.0;
    mat_a->m[3*4+2] = 0.0;
    mat_a->m[3*4+3] = 1.0;
    arMatrixSelfInv( mat_b );
    arMatrixMul( mat_c, mat_b, mat_a );

        //x,y,z is card position relative to base pattern
    x = mat_c->m[0*4+3];
    y = mat_c->m[1*4+3];
    z = mat_c->m[2*4+3];
   
        curPaddlePos[0] = x;
        curPaddlePos[1] = y;
        curPaddlePos[2] = z;

        //      printf("Position: %3.2f %3.2f %3.2f\n",x,y,z);

        arMatrixFree( mat_a );
    arMatrixFree( mat_b );
    arMatrixFree( mat_c );
       
}


/* draw the paddle */
int  draw_paddle( ARPaddleInfo *paddleInfo, PaddleItemInfo *paddleItemInfo )
{
    double  gl_para[16];
    int     i;

    argDrawMode3D();
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
   
    argDraw3dCamera( 0, 0 );
    argConvGlpara(paddleInfo->trans, gl_para);
     
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixd( gl_para );

    glColor3f( 1.0, 0.0, 0.0 );
    glLineWidth(4.0);
    glBegin(GL_LINE_LOOP);
        glVertex2f( -25.0, -25.0 );
        glVertex2f(  25.0, -25.0 );
        glVertex2f(  25.0,  25.0 );
        glVertex2f( -25.0,  25.0 );
    glEnd();

    glColor3f( 0.0, 0.0, 1.0);
    glBegin(GL_LINE_LOOP);
    for( i = 0; i < 16; i++ ) {
        double  x, y;
        x = PADDLE_RADIUS * cos(i*3.141592*2/16);
        y = PADDLE_RADIUS * sin(i*3.141592*2/16);
        glVertex2d( x, y );
    }
    glEnd();
    glBegin(GL_LINE_LOOP);
        glVertex2f( -7.5,    0.0 );
        glVertex2f(  7.5,    0.0 );
        glVertex2f(  7.5, -105.0 );
        glVertex2f( -7.5, -105.0 );
    glEnd();

    glEnable(GL_BLEND);
    glBlendFunc(GL_ZERO,GL_ONE);
   
    glColor4f(1,1,1,0);    
        glBegin(GL_POLYGON);
    for( i = 0; i < 16; i++ ) {
        double  x, y;
        x = 40.0 * cos(i*3.141592*2/16);
        y = 40.0 * sin(i*3.141592*2/16);
        glVertex2d( x, y );    
        }
    glEnd();
    glBegin(GL_POLYGON);
        glVertex2f( -7.5,    0.0 );
        glVertex2f(  7.5,    0.0 );
        glVertex2f(  7.5, -105.0 );
        glVertex2f( -7.5, -105.0 );
    glEnd();
    glDisable(GL_BLEND);

        /* draw any objects on the paddle */
        if( (i=paddleItemInfo->item) !=-1) {

        glPushMatrix();
        glTranslatef( paddleItemInfo->x, paddleItemInfo->y, 10.0 );
        glRotatef( paddleItemInfo->angle * 180.0/3.141592, 0.0, 0.0, 1.0 );
        glColor3f(0.0,1.0,0.0);
        glutSolidSphere(10,10,10);
        //      glutSolidTeapot(10.);
        glPopMatrix();
        }

    glDisable(GL_DEPTH_TEST);
        argDrawMode2D();
    return 0;
}

/* draw the items on the ground */
void drawItems(double trans[3][4], ItemList* itlist)
{
  int i;
  double        gl_para[16];
  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};
  GLfloat   mat_ambient[]    = {0.0, 1.0, 0.0, 1.0};
  GLfloat   mat_flash2[]      = {0.0, 1.0, 1.0, 1.0};
  GLfloat   mat_flash_shiny2[]= {50.0};

  argDrawMode3D();
  argDraw3dCamera( 0, 0 );
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
 
  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_flash2);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny2);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

    /* load the camera transformation matrix */
    glMatrixMode(GL_MODELVIEW);
    argConvGlpara(trans, gl_para);
    glLoadMatrixd( gl_para );
    for(i = 0; i < itlist->itemnum; i ++ )
      {
        if (!itlist->item[i].onpaddle)
          {
            glPushMatrix();
            glTranslatef(itlist->item[i].pos[0],itlist->item[i].pos[1], 10.0 );
             glColor3f(0.0,1.0,0.0);
             glutSolidSphere(10,10,10);
            glPopMatrix();
          }
      }
    glDisable( GL_LIGHTING );
    glDisable( GL_DEPTH_TEST );    
    argDrawMode2D();
}

/*************************************************************************************
**
** drawGroundGrid - draws a ground plane
**
***************************************************************************************/

int drawGroundGrid( double trans[3][4], int divisions, float x, float y, float height)
{
        double        gl_para[16];
    int           i;
        float x0,x1,y0,y1;
        float deltaX, deltaY;

        argDrawMode3D();
    argDraw3dCamera( 0, 0 );
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
   
    /* load the camera transformation matrix */
    glMatrixMode(GL_MODELVIEW);
    argConvGlpara(trans, gl_para);
    glLoadMatrixd( gl_para );
       
    glTranslatef(x/2.,-y/2.,0.);
        //draw the grid
    glColor3f(1,0,0);
        glLineWidth(6.0);
        glBegin(GL_LINE_LOOP);
        glVertex3f( -x, y, height );
        glVertex3f(  x, y, height );  
        glVertex3f(  x, -y, height );
        glVertex3f( -x, -y, height );
        glEnd();
        glLineWidth(3.0);
       
        //draw a grid of lines
        //X direction
        x0 = -x; x1 = -x;
        y0 = -y; y1 = y;
        deltaX = (2*x)/divisions;

        for(i=0;i<divisions;i++){
                x0 = x0 + deltaX;
                glBegin(GL_LINES);
                glVertex3f(x0,y0,height);
                glVertex3f(x0,y1,height);
                glEnd();
        }

        x0 = -x; x1 = x;
        deltaY = (2*y)/divisions;

        for(i=0;i<divisions;i++){
                y0 = y0 + deltaY;
                glBegin(GL_LINES);
                glVertex3f(x0,y0,height);
                glVertex3f(x1,y0,height);
                glEnd();
        }

        glLineWidth(1.0);

        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);

        glDisable( GL_LIGHTING );
    glDisable( GL_DEPTH_TEST );    
    argDrawMode2D();
    return 0;
}