home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / JIREND / CURSORS.C < prev    next >
C/C++ Source or Header  |  1993-04-11  |  8KB  |  333 lines

  1. /* 2D and 3D cursor handling  */
  2. /* some manipulation routines */
  3.   
  4. /* Written by Dave Stampe, Aug. 1992 */
  5.   
  6. /* Copyright 1992 by Bernie Roehl.
  7.    May be freely used to write software for release into the public domain;
  8.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  9.    for permission to incorporate any part of this software into their
  10.    products!
  11.  */
  12.   
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <dos.h>
  16.   
  17. #include "rend386.h"
  18. #include "userint.h"
  19. #include "f3dkitd.h"
  20. #include "intmath.h"
  21. #include "pointer.h"
  22. #include "cursor.h"
  23. #include "segio.h"
  24. #include "splits.h"
  25. #include "plg.h"
  26.   
  27. /***************** 2D (screen) cursor handling ************/
  28.   
  29. static int oldx = 160, oldy = 100;
  30. static int cursor_flag = -1;
  31. static int lastpage;
  32.   
  33. void cursor_move(int x, int y) /* move cursor if visible */
  34. {
  35.    oldx = x;
  36.    oldy = y;
  37.    if (cursor_flag == 0)
  38.    {
  39.       set_drawpage(lastpage);
  40.       erase_cursor(lastpage);
  41.       draw_cursor(x,y,0,lastpage);
  42.    }
  43. }
  44.   
  45. int cursor_hide(void) /* erase cursor */
  46. {
  47.    if (cursor_flag >= 0) erase_cursor(lastpage);
  48.    --cursor_flag;
  49.    return lastpage;
  50. }
  51.   
  52. int cursor_forget(void) /* will be erased by redraw: ignore it! */
  53. {
  54.    --cursor_flag;
  55.    return lastpage;
  56. }
  57.   
  58. void cursor_show(int page) /* redisplay cursor */
  59. {
  60.    if (++cursor_flag == 0)
  61.    {
  62.       set_drawpage(page);
  63.       lastpage = page;
  64.       draw_cursor(oldx, oldy, 0, page);
  65.    }
  66. }
  67.   
  68.   
  69. int move_2D(PDRIVER *d, int *x, int *y, unsigned *b)
  70. {
  71.    int c;
  72.   
  73.    if (d == NULL) return 0;
  74.    if (PNEW_POS & (c = mouse_read(d, x, y, b)))
  75.       cursor_move(*x, *y);
  76.    return c;
  77. }
  78.   
  79.   
  80. int move_till_click(PDRIVER *d, unsigned b, int *x, int *y) /* b is button mask */
  81. {
  82.    int s;
  83.    unsigned c;
  84.   
  85.    if (d == NULL) return -1;
  86.    while(1)
  87.    {
  88.       if (((s = move_2D(d, x, y, &c)) & PNEW_BUT) && (c & b)) break;
  89.    }
  90.    return s;
  91. }
  92.   
  93.   
  94. extern int manip_2D_avail;
  95. extern int redraw;
  96.   
  97. int can_point_2D(void)
  98. {
  99.    if (!manip_2D_avail)
  100.    {
  101.       popmsg("Mouse not available");
  102.       delay(500);
  103.       redraw = 1;
  104.       return 0;
  105.    }
  106.    return 1;
  107. }
  108.   
  109.   
  110. int move_and_select_2D(PDRIVER *d)
  111. {
  112.    int x, y, c;
  113.    unsigned b;
  114.   
  115.    if (!(c = move_2D(d, &x, &y, &b))) return 0; /* no changes */
  116.   
  117.    b &= 1; /* only left button wanted */
  118.   
  119.    if (check_controls(x, y, b)) return 0;
  120.   
  121.    if (b != 0 && (c & PNEW_BUT)) /* new button: DOWN event */
  122.    {
  123.       OBJECT *obj;
  124.   
  125.       obj = where_screen_pt(NULL, NULL, x, y);
  126.       if (obj)
  127.       {
  128.          set_obj_flags(obj, get_obj_flags(obj) ^ OBJ_HIGHLIGHTED);
  129.          if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
  130.             highlight_obj(obj);
  131.          else
  132.             unhighlight_obj(obj);
  133.          redraw = 1;
  134.       }
  135.       else
  136.       {
  137.          popmsg("Not on any object");
  138.          delay(300);
  139.       }
  140.       redraw = 1;
  141.    }
  142.    return 0;
  143. }
  144.   
  145.   
  146. /* find world coordinates of pointer based on given view */
  147.   
  148. void pointer_to_world(POINTER *p, VIEW *v, long *x, long *y, long *z)
  149. {
  150.    MATRIX n;
  151.    *x = p->x;
  152.    *y = p->y;
  153.    *z = p->z;
  154.    view_to_matrix(v,n);
  155.    matrix_point(n,x,y,z);
  156.    p->wpos[3][0] = *x;
  157.    p->wpos[3][1] = *y;
  158.    p->wpos[3][2] = *z;
  159.    p->wpos_valid = 1;
  160. }
  161.   
  162.   
  163. /* rotate data to view alignment */
  164.   
  165. void rotate_to_view( VIEW *v, long *x, long *y, long *z)
  166. {
  167.    MATRIX n;
  168.    view_to_matrix(v,n);
  169.    matrix_rotate(n,x,y,z);
  170. }
  171.   
  172.   
  173. /***************** GLOVE CURSOR SUPPORT *************/
  174.   
  175. static SEGMENT *wrist_seg; /* wrist-on-body segment */
  176. /* also used to manip. objects */
  177.   
  178. static SEGMENT *glove_seg; /* wrist twist for presentation */
  179. static SEGMENT *glove_joints[20]; /* joints on hand */
  180.   
  181. #define Y_GLV_OFFSET  0      /* needed as "body" is at neck level */
  182. #define GLOVE_DIST    1000
  183.   
  184. #define SELECT_LENGTH 20   /* distance along last index finger segment */
  185. /* to selection point */
  186.   
  187. int glove_update(PDRIVER *d, POINTER *p) /* read glove, update positions */
  188. {
  189.    int c;
  190.   
  191.    c = pointer_read(d, p);
  192.   
  193.    if ((c & (PNEW_POS | PNEW_ROT | PNEW_FLEX)) == 0) return 0;
  194.   
  195.    abs_move_segment(wrist_seg, p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
  196.    if (d->pdata->type&P_IS6DG)
  197.       abs_rot_segment(wrist_seg, p->rx, p->ry, p->rz, RYXZ);
  198.    else
  199.       abs_rot_segment(glove_seg, -2000L*p->y, p->ry, -4000L*p->x, RYXZ);
  200.   
  201.    abs_rot_segment(glove_joints[1], 0L,30*65536L+18061L*p->flex[0],0L, RYXZ);
  202.    abs_rot_segment(glove_joints[2], -20*65536L,90*65536L,-5*65536L+38700L*p->flex[1], RYZX);
  203.    abs_rot_segment(glove_joints[3], 38700*p->flex[2],0L,0L, RYXZ);
  204.    abs_rot_segment(glove_joints[4], 38700*p->flex[3],0L,0L, RYXZ);
  205.    abs_rot_segment(glove_joints[5], 38700*p->flex[4],0L,0L, RYXZ);
  206.    abs_rot_segment(glove_joints[6], 38700*p->flex[5],0L,0L, RYXZ);
  207.    abs_rot_segment(glove_joints[7], 38700*p->flex[6],0L,0L, RYXZ);
  208.    abs_rot_segment(glove_joints[8], 38700*p->flex[7],0L,0L, RYXZ);
  209.    abs_rot_segment(glove_joints[9], 38700*p->flex[8],0L,0L, RYXZ);
  210.    abs_rot_segment(glove_joints[10],38700*p->flex[9],0L,0L, RYXZ);
  211.   
  212.    redraw = 1;
  213.    return 1;
  214. }
  215.   
  216. extern OBJLIST *objlist; /* only needed during load */
  217. extern void *split_tree;
  218.   
  219. int load_glove_cursor(SEGMENT *body_seg, PDRIVER *gd, char *glove_fname)
  220. {
  221.    int i;
  222.    FILE *in;
  223.    OBJECT *obj;
  224.   
  225.    if ((in = fopen(glove_fname, "r")) == NULL)
  226.    {
  227.       popmsg("Could not open glove file");
  228.       getkey();
  229.       return -1;
  230.    }
  231.    set_readseg_objlist(objlist);
  232.    set_readseg_seglist(glove_joints,20);
  233.    wrist_seg = new_seg(body_seg);
  234.   
  235.    if ((gd->pdata->type & P_IS6DG) == 0)
  236.       abs_rot_segment(wrist_seg, 55*65536L, 0, 0, RYXZ); /* glove wrist pose   */
  237.   
  238.    glove_seg = readseg(in, wrist_seg);
  239.    fclose(in);
  240.   
  241.    if (glove_seg == NULL)
  242.    {
  243.       popmsg("Bad glove figure file!");
  244.       getkey();
  245.       return -2;
  246.    }
  247.    for(i = 0; i < 11; i++) /* glove is a non-selectable object */
  248.    {
  249.       void *obj = seg_get_object(glove_joints[i]);
  250.       set_obj_flags(obj, get_obj_flags(obj) | OBJ_NONSEL);
  251.    }
  252.    return 0;
  253. }
  254.   
  255.   
  256. /************* 3D/6D CURSOR SUPPORT ***********/
  257.   
  258. static SEGMENT *cursor_seg;
  259.   
  260. int load_3D_cursor(SEGMENT *body_seg, PDRIVER *gd, char *cursor_fname)
  261. {
  262.    int i;
  263.    FILE *in;
  264.    OBJECT *obj;
  265.   
  266.    if ((in = fopen(cursor_fname, "r")) == NULL)
  267.    {
  268.       popmsg("Could not open glove file");
  269.       getkey();
  270.       return -1;
  271.    }
  272.    cursor_seg = new_seg(body_seg);
  273.    obj = load_plg(in);
  274.    fclose(in);
  275.   
  276.    if (obj)
  277.    {
  278.       seg_set_object(cursor_seg, obj);
  279.       set_object_owner(obj, cursor_seg);
  280.       set_obj_flags(obj, get_obj_flags(obj) | OBJ_NONSEL);
  281.       add_obj_to_split_area(split_tree, obj);
  282.       update_segment(cursor_seg);
  283.       return 0;
  284.    }
  285.    else
  286.    {
  287.       popmsg("Bad pointer object file!");
  288.       getkey();
  289.       return -2;
  290.    }
  291. }
  292.   
  293.   
  294. int cursor_update3D(PDRIVER *d, POINTER *p) /* read pointer, update positions */
  295. {
  296.    int c;
  297.   
  298.    c = pointer_read(d, p);
  299.   
  300.    if ((c & (PNEW_POS | PNEW_ROT)) == 0) return 0;
  301.   
  302.    abs_move_segment(cursor_seg, p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
  303.    abs_rot_segment(cursor_seg, p->rx, p->ry, p->rz, RYXZ);
  304.   
  305.    redraw = 1;
  306.    return 1;
  307. }
  308.   
  309.   
  310.   
  311.   
  312. /************* USED FOR 3D/6D MANIPULATION *************/
  313.   
  314. extern int have_glove, use_glove, have_ptr;
  315.   
  316. SEGMENT *manip_data(PDRIVER *d, long *x, long *y, long *z)
  317. {
  318.   
  319.    if (!have_ptr)
  320.    {
  321.       *x = 0;
  322.       *y = 0;
  323.       *z = SELECT_LENGTH;
  324.       matrix_point(*get_seg_pmatrix(glove_joints[4]), x, y, z);
  325.       return wrist_seg;
  326.    }
  327.    else
  328.    {
  329.       seg_getposxyz(cursor_seg, x ,y ,z);
  330.       return cursor_seg;
  331.    }
  332. }
  333.