home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / cursglov.c < prev    next >
C/C++ Source or Header  |  1996-03-19  |  6KB  |  211 lines

  1. // Routines for PowerGlove cursor load, movement and
  2. // manipulation interface.  Used in combination with GLOVEPTR.C
  3.  
  4. /* Original written by Dave Stampe, Aug. 1992 */
  5.  
  6. /*
  7.  This code is part of the VR-386 project, created by Dave Stampe.
  8.  VR-386 is a desendent of REND386, created by Dave Stampe and
  9.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  10.  Stampre for VR-386.
  11.  
  12.  Copyright (c) 1994 by Dave Stampe:
  13.  May be freely used to write software for release into the public domain
  14.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  15.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  16.  this software or source code into their products!  Usually there is no
  17.  charge for under 50-100 items for low-cost or shareware products, and terms
  18.  are reasonable.  Any royalties are used for development, so equipment is
  19.  often acceptable payment.
  20.  
  21.  ATTRIBUTION:  If you use any part of this source code or the libraries
  22.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  23.  and any other authors in your documentation, source code, and at startup
  24.  of your program.  Let's keep the freeware ball rolling!
  25.  
  26.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  27.  REND386, improving programmer access by rewriting the code and supplying
  28.  a standard API.  If you write improvements, add new functions rather
  29.  than rewriting current functions.  This will make it possible to
  30.  include you improved code in the next API release.  YOU can help advance
  31.  VR-386.  Comments on the API are welcome.
  32.  
  33.  CONTACT: dstampe@psych.toronto.edu
  34. */
  35.  
  36.  
  37. #include <stdio.h>
  38. #include <dos.h>
  39.  
  40. #include "vrconst.h"
  41. #include "pointint.h"
  42. #include "vr_api.h"
  43. #include "intmath.h"
  44. #include "pcdevice.h"
  45. #include "segment.h"
  46.  
  47.  
  48. /***************** GLOVE CURSOR SUPPORT *************/
  49.  
  50. /* also used to manip. objects */
  51.  
  52. static SEGMENT *glove_seg; /* wrist twist for presentation */
  53. static SEGMENT *glove_joints[20]; /* joints on hand */
  54.  
  55. #define SELECT_LENGTH 20    /* distance along last index finger segment */
  56. /* to selection point */
  57.  
  58. static int glove_update(PDRIVER *d, POINTER *p) /* read glove, update positions */
  59. {
  60.   int c;
  61.  
  62.   c = pointer_read(d, p);
  63.  
  64.   if ((c & (PNEW_POS | PNEW_ROT | PNEW_FLEX)) == 0) return 0;
  65.  
  66.   abs_move_segment(wrist_seg, p->x, p->y + Y_PTR_OFFSET, p->z + PTR_DIST);
  67.  
  68.   if (d->pdata->type&P_IS6DG)
  69.     abs_rot_segment(wrist_seg, p->rx, p->ry, p->rz, RYXZ);
  70.   else    // fake rotation: looks good
  71.     abs_rot_segment(glove_seg, -2000L*p->y, p->ry, -4000L*p->x, RYXZ);
  72.  
  73.   abs_rot_segment(glove_joints[1], 0L,30*65536L+18061L*p->flex[0],0L, RYXZ);
  74.   abs_rot_segment(glove_joints[2], -20*65536L,90*65536L,-5*65536L+38700L*p->flex[1], RYZX);
  75.   abs_rot_segment(glove_joints[3], 38700*p->flex[2],0L,0L, RYXZ);
  76.   abs_rot_segment(glove_joints[4], 38700*p->flex[3],0L,0L, RYXZ);
  77.   abs_rot_segment(glove_joints[5], 38700*p->flex[4],0L,0L, RYXZ);
  78.   abs_rot_segment(glove_joints[6], 38700*p->flex[5],0L,0L, RYXZ);
  79.   abs_rot_segment(glove_joints[7], 38700*p->flex[6],0L,0L, RYXZ);
  80.   abs_rot_segment(glove_joints[8], 38700*p->flex[7],0L,0L, RYXZ);
  81.   abs_rot_segment(glove_joints[9], 38700*p->flex[8],0L,0L, RYXZ);
  82.   abs_rot_segment(glove_joints[10],38700*p->flex[9],0L,0L, RYXZ);
  83.  
  84.   world_changed++;
  85.   update_object(wrist_seg);
  86.   return 1;
  87. }
  88.  
  89.  
  90.     // sets up the 3D/6D manip system
  91. void set_3D_manip_data(PDRIVER *ptr, SEGMENT *move, SEGMENT *sel, POSE *seloffset);
  92.  
  93.  
  94. static int load_glove_cursor(PDRIVER *gd, char *glove_fname)
  95. {
  96.   int i;
  97.   FILE *in;
  98.   OBJECT *obj;
  99.   POSE pgo = { 0,0,SELECT_LENGTH,0,0,0};  // glove to select point
  100.  
  101.   if ((in = fopen(glove_fname, "r")) == NULL)
  102.     {
  103.       errprintf("Cannot read glove object file %s", glove_fname);
  104.       return -1;
  105.     }
  106.   if ((gd->pdata->type & P_IS6DG) == 0)
  107.     abs_rot_segment(wrist_seg, 55*65536L, 0, 0, RYXZ); /* glove wrist pose */
  108.  
  109.   glove_seg = load_figure_as_object(in, default_objlist, glove_joints, 20, 1, 1, 1);
  110.   attach_object(glove_seg, wrist_seg, 0);
  111.   fclose(in);
  112.  
  113.   add_objlist_to_world(default_objlist);
  114.  
  115.   if (seg_error(NULL) || (glove_seg == NULL))
  116.     {
  117.       errprintf("%s loading glove object", seg_error(NULL));
  118.       return -2;
  119.     }
  120.  
  121.   do_for_all_child_objects(glove_seg, make_object_unselectable);
  122.  
  123.     // register 3D manipulation data
  124.   set_3D_manip_data(gd, wrist_seg, glove_joints[4], &pgo);
  125.  
  126.   return 0;
  127. }
  128.  
  129. static PDRIVER *glvptr;
  130.  
  131.  
  132. static void gloveptr_quit()
  133. {
  134.   pointer_quit(glvptr);
  135. }
  136.  
  137.  
  138. PDRIVER *glove_initialize(char *glvdev, char *glvobj, POSE *s)
  139. {
  140.   PDRIVER *p;
  141.   POINTER x;
  142.  
  143.   p = pointer_init(P_IS3DG | P_IS6DG, glvdev); /* setup glove device */
  144.   if (p == NULL) return NULL;
  145.  
  146.   init_pointer(&x); /* so that defaults are OK */
  147.     /* use abs. glove motion */
  148.   pointer_abscale(p, s->x, s->y, s->z, s->rx, s->ry, s->rz);
  149.   set_mouse_limits(p, screeninfo->xmax, screeninfo->ymax);
  150.   pointer_read(p, &x);
  151.   pointer_read(p, &x); /* save current position */
  152.   mouse_read(p, NULL, NULL, NULL);
  153.  
  154.   glvptr = p;
  155.   atexit(gloveptr_quit);
  156.  
  157.   load_glove_cursor(p, glvobj);
  158.  
  159.   return p;
  160. }
  161.  
  162.  
  163.  
  164.  
  165.     // read, handle glove gestures
  166. void glove_process()
  167. {
  168.   POINTER gp;
  169.   int g;
  170.  
  171.   glove_update(glvptr, &gp);
  172.   switch(gp.gesture)
  173.     {
  174.       case G_FIST :
  175.     g = GRASP_DO;
  176.     break;
  177.       case G_PINCH:
  178.     g = ROTATE_DO;
  179.     break;
  180.       case G_POINT:
  181.     g = SELECT_DO;
  182.     break;
  183.       default:
  184.     g = FREE_DO;
  185.     break;
  186.    }
  187.  do_3D_manip(g);
  188. }
  189.  
  190.  
  191.  
  192. static char *gest[] = {
  193.     "FLAT", "THUMB_IN", "INDEX_IN", "MIDDLE_IN",
  194.     "RING_IN", "PINCH", "FIST", "THUMB_OUT", "POINT",
  195.     "BADFINGER", "RING_OUT", "??????" };
  196.  
  197.  
  198. char *get_glove_gesture_name()
  199. {
  200.   if (glvptr) /* prevent pre-init call */
  201.     {
  202.       int sl;
  203.       POINTER p;
  204.  
  205.       last_pointer(glvptr, &p);
  206.       sl = p.gesture;
  207.       if (sl<0 || sl>G_UNKNOWN) sl = G_UNKNOWN;
  208.       return gest[sl];
  209.     }
  210.   return NULL;
  211. }