/* ------------------------------------------------------------- * Designed by: Dr. Peter Hor-Ching Wang * Date: Sep. 10, 1995 * Purpose: Attach VPL Dataglove to ching virtual reality system * Notes: This is a VR system based on sense8 WorldToolKit and * DataGlove driver from Dr. Tomohiro Kuroda * ------------------------------------------------------------- */ #include "hand.c" #include "handfont.c" #include "datag.c" /* * onlyhand.c: attach DataGlove in com1 to hand object and move it * * (C) Tomohiro Kuroda June 1995 */ /* #define COM2 "/dev/ttyd2" #define COM1 "/dev/ttyd1" */ /******* Port number *********/ #define GLOVEPORT COM1 #define BALLPORT COM2 /******* Include Headers *******/ #include "wt.h" /* Standard WTK header files */ #include "DataG.h" /* Data Glove controlling functions */ #include "hand.h" /* Hand object creating & dealing functions */ #define RIGHT TRUE /* TRUE in right hand */ /******* Global variables *******/ WTsensor *mouse = NULL; /* a handle on the mouse */ WTviewpoint *uview; /* universe's viewpoint */ WTsensor *glove = NULL; /* Data Glove object */ WTsensor *headpolh = NULL; /* Polhemous Fastrak */ WTsensor *polh = NULL; /* Polhemous Fastrak */ WTsensor *ball = NULL; /* Spaceball */ WtGloveHand *hand; /* Hand object */ WTpq InitialView; /* Intiaial view point */ WTpq InitialHand; /* Initial hand position */ WTp3 light_pos = { 1200, -800, -1000 }; /* light position */ WTp3 light_dir = { -.68, .48, .58 }; /* light direction */ int gb_calib_step = 0; /* Calibration step of data glove * 0 : not in the calibration * 1 : calibrate fist * 2 : calibrate parm */ void LoadObjects (char *directory); void LoadObjectsFile (char *directory); void LoadUniverse (char *filename, float scale); char fname[80]; /******* prototypes *******/ void actions(void); void handle_key(int key); void toggle_object(WTobject *obj); void reset_view(void); void reset_hand(void); void rotate_fastrak(WTsensor *sensor); void handle_spaceball(void); /*************************/ /******* functions *******/ /*************************/ /******* main *******/ WTserial *serial; WTserial *WTserial_new(); int main(int argc, char *argv[]) { printf("WorldToolKit Data Glove simple demo\n"); printf("Copyright 1995 Tomohiro Kuroda\n\n"); printf ("Creating new universe\n"); WTuniverse_new(WTDISPLAY_DEFAULT, WTWINDOW_DEFAULT); uview = WTuniverse_getviewpoint(); WTlight_setambient(0.02); WTlight_new(light_pos, light_dir, 1.0); /* prepare to read keyboard */ WTkeyboard_open(); /* setup mouse sensor */ mouse = WTsensor_new(WTmouse_open, WTmouse_close, WTmouse_moveview2, NULL, 1, WTSENSOR_DEFAULT); WTsensor_setsensitivity (mouse,1000.0f); /* setup dataglove sensor */ /* glove = WTdataglove_new(GLOVEPORT); */ serial = WTserial_new("/dev/ttyd1" ,9600) ; printf("Glove serial = %x\n",serial); WTserial_setsize(serial, 256); glove = WTsensor_new(WTdataglove_open, WTdataglove_close, WTdataglove_update, serial,1,WTSENSOR_DEFAULT); if(glove == NULL) printf("***************** glove not ready **************\n"); /* setup polhemous sensor */ while ( !headpolh ){ printf("FastTrak_new\n"); headpolh = WTfastrak_new("/dev/ttyd2",1); } polh = WTfastrak_new("/dev/ttyd2",2); printf("headpolh=%x, polh=%x\n",headpolh, polh); /* setup spaceball */ /* ball = WTspaceball_new("/dev/ttyd2"); */ /* create hand object*/ while( !hand) { printf("hand_new\n"); hand = WtGloveHandInit(RIGHT, TRUE); } if(hand) WTobject_add(hand->parm); WTobject_getposition(hand->parm, InitialHand.p); WTobject_getorientation(hand->parm, InitialHand.q); /* attach polhemus */ if(polh && hand){ WTobject_addsensor(hand->parm, polh, WTFRAME_LOCAL); rotate_fastrak(polh); } /* set universe action function */ WTuniverse_setactions(actions); printf ("Universe ready\n"); WTuniverse_ready(); /* zoom until roughly all of universe is in view */ WTviewpoint_zoomall(uview); /* save initial view point */ WTviewpoint_getposition(uview, InitialView.p); WTviewpoint_getorientation(uview, InitialView.q); WTsensor_setsensitivity(mouse, 0.05 * WTuniverse_getradius()); WTviewpoint_addsensor(uview, mouse); if(ball) WTviewpoint_addsensor(uview, ball); /* enter main loop */ printf("Universe go\n"); printf("(press ? for help)\n"); WTuniverse_go(); /* all done - clean up */ WTuniverse_delete(); return 0; } /******* actions *******/ void actions(void) { int key; /* Move Hand object along Data Glove input */ if(!gb_calib_step) WtGloveHand_update(hand, glove, 0, FALSE); /* handle spaceball */ if(ball) handle_spaceball(); /* get key and do key functions */ key = WTkeyboard_getlastkey(); if (key) handle_key(key); /* interpret keypress */ } void handle_key(int key) { int ren; WTpq l6d; switch (key) { case 'q': printf("Quitting.\n"); WTuniverse_stop(); break; case 'm': printf("Load objects from a Master File: "); gets(fname); LoadObjectsFile(fname); break; case 'd': printf("Load objects from a directory: "); gets(fname); LoadObjects(fname); break; case 'h': WTobject_addsensor (hand->parm, mouse, WTFRAME_VPOINT); break; case 'u': LoadUniverse (NULL, 0.0f); break; case 'w': ren = WTuniverse_getrendering(); if ( ren & WTRENDER_WIREFRAME ) WTuniverse_setrendering(WTRENDER_GOURAUD); else WTuniverse_setrendering(WTRENDER_WIREFRAME); break; case '!': /* displays state information */ /* frame rate and total polygons */ printf("\nPolygons: %6d, Frame rate: %8.2f fps\n", WTuniverse_npolygons(), WTuniverse_framerate()); /* current viewpoint */ WTviewpoint_getposition(uview, l6d.p); WTviewpoint_getorientation(uview, l6d.q); printf("View: x=%8.3f, y=%8.3f, z=%8.3f\n", l6d.p[X], l6d.p[Y], l6d.p[Z]); printf(" qx=%8.4f, qy=%8.4f, qz=%8.4f, qw=%8.4f\n", l6d.q[X], l6d.q[Y], l6d.q[Z], l6d.q[W]); break; case 'c': if(!gb_calib_step){ /* if(polh) WTobject_removesensor(hand->parm, polh); */ reset_hand(); reset_view(); } if(!WTglove_calibrate(glove, gb_calib_step)) gb_calib_step = 2; gb_calib_step = (gb_calib_step == 2 ? 0 : gb_calib_step + 1); WtGloveHand_update(hand, glove, gb_calib_step, FALSE); if(!gb_calib_step){ /* if(polh){ WTobject_addsensor(hand->parm, polh, WTFRAME_LOCAL); rotate_fastrak(polh); } */ } break; case 'i': reset_view(); break; case '?': printf("\nYou can use the mouse to fly around\n"); printf(" and you can use Dataglove to move fingers ( Not hand itself)\n"); default: printf("\n"); printf(" 'w' Toggles wireframe\n"); printf(" '!' Get informations\n"); printf(" 'c' Calibrate Data Glove\n"); printf(" 'i' Initialize viewing point\n"); printf(" 'm' Load objects from a master file\n"); printf(" 'd' Load objects from a directory\n"); printf(" 'u' Load Universe\n"); printf(" 'q' Quits\n"); break; } } void reset_view() { WTviewpoint_setposition(uview, InitialView.p); WTviewpoint_setorientation(uview, InitialView.q); } void reset_hand() { WTobject_setposition(hand->parm, InitialHand.p); WTobject_setorientation(hand->parm, InitialHand.q); } void rotate_fastrak(WTsensor *polh) { WTq q; /* rotate -90 degree about X */ WTeuler_2q(-0.5*PI, 0.0, 0.0, q); WTsensor_rotate(polh, q); } void handle_spaceball(void) { int data; static FLAG button_up = TRUE; data = WTsensor_getmiscdata(ball); /* teleport to initial view with BUTTON1 */ if(button_up){ if ( data & WTSPACEBALL_BUTTON1_DOWN ){ button_up = FALSE; reset_view(); } /* Data Glove calibration with button 7 */ else if( data & WTSPACEBALL_BUTTON7_DOWN ){ button_up = FALSE; if(!gb_calib_step){ /* if(polh) WTobject_removesensor(hand->parm, polh); */ reset_hand(); reset_view(); } if(!WTglove_calibrate(glove, gb_calib_step)) gb_calib_step = 2; gb_calib_step = (gb_calib_step == 2 ? 0 : gb_calib_step + 1); WtGloveHand_update(hand, glove, gb_calib_step, FALSE); if(!gb_calib_step){ /* if(polh){ WTobject_addsensor(hand->parm, polh, WTFRAME_LOCAL); rotate_fastrak(polh); } */ } } } else if(data & WTSPACEBALL_BUTTONS_UP) button_up = TRUE; } /* ------------------------------------------------------- */ /* * loads a new universe from filename and scale passed * into the function. If either of the arguments * is null, prompts the user */ void LoadUniverse (char *filename, float scale) { char buf[WTPATHLEN]; WTpq initView; /* if no filename ask for one */ if (filename == NULL) { filename = malloc (WTPATHLEN); printf ("Enter filename to load as new universe: "); gets (filename); } /* if scale is 0.0 ask for one */ if (scale == 0.0f) { printf ("Enter scale for new universe: "); gets (buf); if (!buf[0]) scale = 1.0f; else scale = (float) atof (buf); } /* load universe geometry */ scale=1.0; printf ("Loading new universe '%s' at scale '%.2f'\n",filename,scale); if (WTuniverse_load (filename, &initView, scale) ) { /* move the viewpoint to the position and orientation read from the model */ WTviewpoint_moveto (uview, &initView); /* scale mouse sensitivity with the size of the universe */ /* printf("universe getradius=%f\n",WTuniverse_getradius); WTsensor_setsensitivity (mouse, 0.03f*WTuniverse_getradius ()); */ WTsensor_setsensitivity (mouse,1000.0f); WTsensor_setsensitivity (ball, 1000.0f); printf ("done.\n"); } else printf ("error.\n"); /* show text menu */ } /* END LoadUniverse */ /* ------------------------------------------------------- */ /* * load a master file * of dynamic objects */ void LoadObjectsFile (char *directory) { FILE *fp; WTpq pq; char fname[80]; WTobject *obj = NULL; char *newline; /* if no directory ask for one */ if (directory == NULL) { directory = malloc (WTPATHLEN); printf ("Enter directory to load objects from: "); gets (directory); } /* open directory */ printf ("Loading dynamic objects from master file : '%s'\n", directory); fp = fopen(directory,"r"); if (!fp) { WTwarning ("Couldn't open file : '%s'!\n", directory); return; } /* load objects from specified master file*/ while ( fgets(fname, 80, fp) != NULL ) { /* check the file extension to see if we recognize it. */ newline = strchr(fname,'\n'); *newline = '\0'; printf ("Loading: '%s'...", fname); obj = WTobject_new (fname, &pq, 1.0f, FALSE, FALSE); if (obj) printf("done.\n"); else printf("error.\n"); } fclose(fp); } /* END LoadObjects */ /* ------------------------------------------------------- */ /* * load an entire directory * of dynamic objects */ void LoadObjects (char *directory) { WTpq pq; char path[WTPATHLEN], *fname; WTobject *obj = NULL; WTdirectory *dir; char *period; /* if no directory ask for one */ if (directory == NULL) { directory = malloc (WTPATHLEN); printf ("Enter directory to load objects from: "); gets (directory); } /* open directory */ printf ("Loading dynamic objects from directory: '%s'\n", directory); dir = WTdirectory_open(directory); if (!dir) { WTwarning ("Couldn't open directory: '%s'!\n", directory); return; } /* load objects from specified directory */ while ( (fname = WTdirectory_getentry (dir)) != NULL ) { /* check the file extension to see if we recognize it. */ strlwr (fname); period = strchr (fname, '.'); if (!period) continue; if (strcmp(period, ".nff") && strcmp(period, ".dxf") && strcmp (period, ".3ds") && strcmp(period,".stl") && strcmp (period, ".obj") ) continue; /* make up path and load object */ strcpy (path, directory); strcat (path, WTFILE_DELIM); strcat (path, fname); printf ("Loading: '%s'...", path); obj = WTobject_new (path, &pq, 1.0f, FALSE, FALSE); if (obj) printf("done.\n"); else printf("error.\n"); } /* done loading close directory */ WTdirectory_close (dir); } /* END LoadObjects */