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