home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / HDMANIP.CPP < prev    next >
C/C++ Source or Header  |  1993-04-21  |  8KB  |  322 lines

  1. /* Handles body/head/manipulator mappings */
  2.  
  3. /* Written by Dave Stampe, August 1992 */
  4.  
  5. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  6.    May be freely used to write software for release into the public domain;
  7.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  8.    for permission to incorporate any part of this software into their
  9.    products!
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <dos.h>
  14. #include <string.h>
  15.  
  16. #include "rend386.hpp"
  17. #include "intmath.h"
  18. #include "splits.hpp"
  19. #include "segasupp.hpp"
  20. #include "pointer.hpp"
  21. #include "cursor.hpp"
  22.  
  23. #ifdef VIDEO_TRACKER
  24. extern int start_video();
  25. extern int read_head_tracker(long *x, long *y, long *z, long *t, long *p, long *a);
  26. #endif
  27.  
  28. extern int use_glove;
  29.  
  30. extern int redraw;
  31.  
  32. static SEGMENT *rot_seg[2]; /* used to rotate objects by center */
  33.  
  34. SEGMENT *body_seg; /* body-in-world base segment */
  35. static SEGMENT *head_seg; /* head-on-body segment */
  36. SEGMENT *eye_seg; /* eyes-in-head segment */
  37.  
  38. extern PDRIVER *head_device;
  39.  
  40. MATRIX h_recenter, ht_offset, ht_ioffset;
  41.  
  42. #define sub_exit        atexit
  43.  
  44. int head_update(int recenter) /* repositions head based on tracker data */
  45. {
  46.     POINTER hp;
  47.     MATRIX m;
  48.     int c;
  49.  
  50.     if (!head_device) return 0;
  51.     c = pointer_read(head_device, &hp); /* read ht */
  52.  
  53.     if (recenter) /* use current pos'n as zero */
  54.     {
  55.         std_matrix(m, hp.rx, hp.ry, hp.rz, hp.x, hp.y, hp.z);
  56.         inverse_matrix(m, h_recenter);
  57.         matrix_product(ht_ioffset, h_recenter, h_recenter);
  58.         c = PNEW_POS;
  59.     }
  60.  
  61.     if (c & (PNEW_POS | PNEW_ROT)) /* compute new hpos */
  62.     {
  63.         std_matrix(m, hp.rx, hp.ry, hp.rx, hp.x, hp.y, hp.z);
  64.         matrix_product(h_recenter, m, m);
  65.         matrix_product(m, ht_offset, m);
  66.         abs_mat_segment(head_seg, m);
  67.         redraw = 1;
  68.     }
  69.     return 0;
  70. }
  71.  
  72.  
  73.  
  74. void htrack_quit()
  75. {
  76.     pointer_quit(head_device);
  77. }
  78.  
  79.  
  80. PDRIVER *init_head_device(char *dfname, long x, long y, long z, long rx, long ry, long rz)
  81. {
  82.     MATRIX m;
  83.     PDRIVER *p;
  84.     POINTER pt;
  85.  
  86.     p = pointer_init(P_IS6H, dfname); /* setup glove device TEST */
  87.     if (p == NULL) return NULL;
  88.  
  89.     init_pointer(&pt); /* so that defaults are OK */
  90.     /* use abs. head motion */
  91.     pointer_abscale(p, 65536L, 65536L, 65536L, 65536L, 65536L, 65536L);
  92.     pointer_read(p, &pt);
  93.     pointer_read(p, &pt); /* save current position */
  94.  
  95.     head_device = p;
  96.     sub_exit(htrack_quit);
  97.  
  98.     identity_matrix(h_recenter);
  99.     std_matrix(m, rx, ry, rz ,x, y, z);
  100.  
  101.     matrix_copy(m, ht_offset);
  102.     /* matrix_copy(m, h_recenter); */
  103.  
  104.     inverse_matrix(m, ht_ioffset);
  105.     inverse_matrix(m, h_recenter);
  106.  
  107.     head_update(1);
  108.  
  109.     return p;
  110. }
  111.  
  112.  
  113. /* do BEFORE loading, initializing devices */
  114.  
  115. void init_body_links() /* setup body-glove-head system */
  116. {
  117.     body_seg = new_seg(NULL);
  118.     head_seg = new_seg(body_seg);
  119.     eye_seg = new_seg(head_seg);
  120.     rot_seg[0] = new_seg(NULL); /* used by manipulation */
  121.     rot_seg[1] = new_seg(NULL);
  122.  
  123.     abs_rot_segment(head_seg, 0*65536L, 0*65536L, 0, RYXZ);
  124.     abs_move_segment(eye_seg, 0,100,100); /* eyes in head pos'n */
  125. }
  126.  
  127.  
  128. /* takes "view" corresp. to body location,           */
  129. /* converts to centered eye view, updates cursors    */
  130. /* sequence: update cursor/glove, read head tracker, */
  131. /* body_centric_map(), manipulate object, and render */
  132.  
  133. void body_centric_map(VIEW *body, VIEW *v)
  134. {
  135.     MATRIX m;
  136.  
  137.     fast_view_factors(body);
  138.     *v = *body;
  139.     view_to_matrix(v,m);
  140.     abs_mat_segment(body_seg,m);
  141.     update_segment(body_seg);
  142.     memcpy(&m, get_seg_pmatrix(eye_seg),sizeof(MATRIX));
  143.     matrix_view_factors(v,m);
  144. }
  145.  
  146.  
  147. /************* SIMPLE 3D/6D OBJECT MANIPULATION *********/
  148.  
  149. static OBJECT *sel_obj[2];
  150. static SEGMENT *work_seg[2];
  151. static SEGMENT *old_parent[2];
  152.  
  153. extern SPLIT *split_tree;
  154.  
  155.  
  156. static void unhi_it(OBJECT *obj)
  157. {
  158.     set_obj_flags(obj, get_obj_flags(obj) & ~OBJ_HIGHLIGHTED);
  159.     unhighlight_obj(obj);
  160. }
  161.  
  162.  
  163. static MATRIX ogm[2];
  164. static long oxp[2], oyp[2], ozp[2];
  165. static long oxg[2], oyg[2], ozg[2];
  166.  
  167. #define FREE_DO   0
  168. #define GRASP_DO  1
  169. #define ROTATE_DO 2
  170. #define SELECT_DO 3
  171.  
  172. static gmode[2] = {FREE_DO, FREE_DO};
  173.  
  174. void manip_do(PDRIVER *p, int command, int which) // glove execution loop element
  175. {
  176.     OBJLIST *list;
  177.     OBJECT * obj;
  178.     int s;
  179.     long d,x,y,z;
  180.     MATRIX f;
  181.     MATRIX *m;
  182.  
  183.     POINTER pt;
  184.     SEGMENT *wrist_seg = manip_data(p, &x, &y, &z, which);
  185.  
  186.     if (p==NULL) return;
  187.  
  188.     s = last_pointer(p, &pt);
  189.  
  190. newmode:
  191.     switch((gmode[which]))
  192.     {
  193.         case FREE_DO:
  194.             switch(command)
  195.             {
  196.                 case SELECT_DO:
  197.                     (gmode[which]) = SELECT_DO;
  198.                     walk_split_tree(split_tree, unhi_it);
  199.                     (sel_obj[which]) = NULL;
  200.                     redraw = 1;
  201.                     goto newmode;
  202.                 case GRASP_DO:
  203.                     if ((sel_obj[which]))
  204.                     {
  205.                         (work_seg[which]) = (SEGMENT *)get_object_owner((sel_obj[which]));
  206.                         (old_parent[which]) = parent_segment((work_seg[which]));
  207.                         if ((old_parent[which])) detach_segment((work_seg[which]));
  208.                         attach_segment((work_seg[which]), wrist_seg);
  209.                         (gmode[which]) = GRASP_DO;
  210.                         redraw = 1;
  211.                     }
  212.                     break;
  213.                 case ROTATE_DO:
  214.                     if ((sel_obj[which]))
  215.                     {
  216.                         (work_seg[which]) = (SEGMENT *)get_object_owner((sel_obj[which]));
  217.                         if ((work_seg[which]) == NULL) break;
  218.                         (old_parent[which]) = parent_segment((work_seg[which]));
  219.                         update_segment((work_seg[which]));
  220.  
  221.                         if ((old_parent[which]) == NULL)
  222.                             get_object_bounds((sel_obj[which]), &(oxp[which]), &(oyp[which]), &(ozp[which])); /* center of obj */
  223.                         else
  224.                         {
  225.                             m = get_seg_pmatrix((work_seg[which])); /* else by origin ("joint") */
  226.                             (oxp[which]) = (*m)[3][0];
  227.                             (oyp[which]) = (*m)[3][1];
  228.                             (ozp[which]) = (*m)[3][2];
  229.                         }
  230.  
  231.                     abs_rot_segment((rot_seg[which]), 0, 0, 0, RYXZ);
  232.                     abs_move_segment((rot_seg[which]), (oxp[which]), (oyp[which]), (ozp[which]));
  233.                     update_segment((rot_seg[which]));
  234.                     attach_segment((work_seg[which]), (rot_seg[which]));
  235.  
  236.                     (oxg[which]) = x-(oxp[which]);
  237.                     (oyg[which]) = y-(oyp[which]);
  238.                     (ozg[which]) = z-(ozp[which]);
  239.                     vector_to_matrix(f, (oxg[which]), (oyg[which]), (ozg[which]));
  240.                     inverse_matrix(f, (ogm[which]));
  241.                     (gmode[which]) = ROTATE_DO;
  242.                     redraw = 1;
  243.                 }
  244.                 break;
  245.             default:
  246.                 break;
  247.             }
  248.             break;
  249.         case SELECT_DO:
  250.             switch(command)
  251.             {
  252.                 case SELECT_DO:
  253.                     list = which_area_objlist(split_tree, x, y, z);
  254.                     if (list != NULL)
  255.                     {
  256.                         obj = best_collision(list, x, y, z);
  257.                         if (obj == NULL)
  258.                         {
  259.                             unhighlight_obj((sel_obj[which]));
  260.                             (sel_obj[which]) = NULL;
  261.                         }
  262.                     else
  263.                     {
  264.                         if ((sel_obj[which]) != obj) unhighlight_obj((sel_obj[which]));
  265.                         highlight_obj(obj);
  266.                         (sel_obj[which]) = obj;
  267.                     }
  268.                     redraw = 1;
  269.                 }
  270.             break;
  271.         default:
  272.             (gmode[which]) = FREE_DO;
  273.             goto newmode;
  274.         }
  275.         break;
  276.     case GRASP_DO:
  277.         switch(command)
  278.         {
  279.         case GRASP_DO:
  280.             break; /* move is automatic */
  281.         default:
  282.             if ((work_seg[which]))
  283.             {
  284.                 detach_segment((work_seg[which]));
  285.                 if ((old_parent[which])) attach_segment((work_seg[which]), (old_parent[which]));
  286.                 redraw = 1;
  287.             }
  288.             (gmode[which]) = FREE_DO;
  289.             goto newmode;
  290.         }
  291.         break;
  292.     case ROTATE_DO:
  293.         switch(command)
  294.         {
  295.         case ROTATE_DO:
  296.             if ((sel_obj[which]) && (s & PNEW_POS))
  297.             {
  298.                 vector_to_matrix(f, x-(oxp[which]), y-(oyp[which]), z-(ozp[which]));
  299.                 matrix_product(f, (ogm[which]), f);
  300.                 f[3][0] = (oxp[which]);
  301.                 f[3][1] = (oyp[which]);
  302.                 f[3][2] = (ozp[which]);
  303.                 abs_mat_segment((rot_seg[which]), f);
  304.                 update_segment((rot_seg[which]));
  305.                 redraw = 1;
  306.             }
  307.             break;
  308.         default:
  309.             (gmode[which]) = FREE_DO;
  310.             redraw = 1; /* convert to real pos'n */
  311.             detach_segment((work_seg[which]));
  312.             if ((old_parent[which])) attach_segment((work_seg[which]), (old_parent[which]));
  313.             goto newmode;
  314.         }
  315.         break;
  316.     default:
  317.         break;
  318.     }
  319. }
  320.  
  321.  
  322.