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